Skip to content

Commit

Permalink
btrfs: make compression path to be subpage compatible
Browse files Browse the repository at this point in the history
Currently btrfs compression path is not really subpage compatible, every
thing is still done in page unit.

That's fine for regular sector size and subpage routine. As even for
subpage routine compression is only enabled if the whole range is page
aligned, so reading the page cache in page unit is totally fine.

However in preparation for the future subpage perfect compression
support, we need to change the compression routine to properly handle a
subpage range.

This patch would prepare both zlib and zstd to only read the subpage
range for compression.
Lzo is already doing subpage aware read, as lzo's on-disk format is
already sectorsize dependent.

Signed-off-by: Qu Wenruo <[email protected]>
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
  • Loading branch information
adam900710 authored and kdave committed Sep 10, 2024
1 parent 9ca0e58 commit fd1e75d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
8 changes: 8 additions & 0 deletions fs/btrfs/compression.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ static inline unsigned int btrfs_compress_level(unsigned int type_level)
return ((type_level & 0xF0) >> 4);
}

/* @range_end must be exclusive. */
static inline u32 btrfs_calc_input_length(u64 range_end, u64 cur)
{
u64 page_end = round_down(cur, PAGE_SIZE) + PAGE_SIZE;

return min(range_end, page_end) - cur;
}

int __init btrfs_init_compress(void);
void __cold btrfs_exit_compress(void);

Expand Down
19 changes: 16 additions & 3 deletions fs/btrfs/zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <linux/refcount.h>
#include "btrfs_inode.h"
#include "compression.h"
#include "fs.h"
#include "subpage.h"

/* workspace buffer size for s390 zlib hardware support */
#define ZLIB_DFLTCC_BUF_SIZE (4 * PAGE_SIZE)
Expand Down Expand Up @@ -108,6 +110,7 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
unsigned long len = *total_out;
unsigned long nr_dest_folios = *out_folios;
const unsigned long max_out = nr_dest_folios * PAGE_SIZE;
const u64 orig_end = start + len;

*out_folios = 0;
*total_out = 0;
Expand Down Expand Up @@ -153,6 +156,10 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
if (in_buf_folios > 1) {
int i;

/* S390 hardware acceleration path, not subpage. */
ASSERT(!btrfs_is_subpage(
inode_to_fs_info(mapping->host),
mapping));
for (i = 0; i < in_buf_folios; i++) {
if (data_in) {
kunmap_local(data_in);
Expand All @@ -167,9 +174,14 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
copy_page(workspace->buf + i * PAGE_SIZE,
data_in);
start += PAGE_SIZE;
workspace->strm.avail_in =
(in_buf_folios << PAGE_SHIFT);
}
workspace->strm.next_in = workspace->buf;
} else {
unsigned int pg_off;
unsigned int cur_len;

if (data_in) {
kunmap_local(data_in);
folio_put(in_folio);
Expand All @@ -179,12 +191,13 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
start, &in_folio);
if (ret < 0)
goto out;
data_in = kmap_local_folio(in_folio, 0);
pg_off = offset_in_page(start);
cur_len = btrfs_calc_input_length(orig_end, start);
data_in = kmap_local_folio(in_folio, pg_off);
start += PAGE_SIZE;
workspace->strm.next_in = data_in;
workspace->strm.avail_in = cur_len;
}
workspace->strm.avail_in = min(bytes_left,
(unsigned long) workspace->buf_size);
}

ret = zlib_deflate(&workspace->strm, Z_SYNC_FLUSH);
Expand Down
19 changes: 13 additions & 6 deletions fs/btrfs/zstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,10 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
unsigned long tot_out = 0;
unsigned long len = *total_out;
const unsigned long nr_dest_folios = *out_folios;
const u64 orig_end = start + len;
unsigned long max_out = nr_dest_folios * PAGE_SIZE;
unsigned int pg_off;
unsigned int cur_len;
zstd_parameters params = zstd_get_btrfs_parameters(workspace->req_level,
len);

Expand All @@ -415,9 +418,11 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
ret = btrfs_compress_filemap_get_folio(mapping, start, &in_folio);
if (ret < 0)
goto out;
workspace->in_buf.src = kmap_local_folio(in_folio, 0);
pg_off = offset_in_page(start);
cur_len = btrfs_calc_input_length(orig_end, start);
workspace->in_buf.src = kmap_local_folio(in_folio, pg_off);
workspace->in_buf.pos = 0;
workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE);
workspace->in_buf.size = cur_len;

/* Allocate and map in the output buffer */
out_folio = btrfs_alloc_compr_folio();
Expand Down Expand Up @@ -494,14 +499,16 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
kunmap_local(workspace->in_buf.src);
workspace->in_buf.src = NULL;
folio_put(in_folio);
start += PAGE_SIZE;
len -= PAGE_SIZE;
start += cur_len;
len -= cur_len;
ret = btrfs_compress_filemap_get_folio(mapping, start, &in_folio);
if (ret < 0)
goto out;
workspace->in_buf.src = kmap_local_folio(in_folio, 0);
pg_off = offset_in_page(start);
cur_len = btrfs_calc_input_length(orig_end, start);
workspace->in_buf.src = kmap_local_folio(in_folio, pg_off);
workspace->in_buf.pos = 0;
workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE);
workspace->in_buf.size = cur_len;
}
}
while (1) {
Expand Down

0 comments on commit fd1e75d

Please sign in to comment.