summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2025-08-11 09:43:42 +0930
committerDavid Sterba <dsterba@suse.com>2025-09-22 10:54:31 +0200
commit0a6dcd42353b96ab4a74796aed1541591de5890c (patch)
tree831e9ee6a0c5532c679dcd50a55280f4c97dcf37
parentd71b419f274c2eea83038c8623ddc45d51af70e9 (diff)
downloadlinux-0a6dcd42353b96ab4a74796aed1541591de5890c.tar.gz
linux-0a6dcd42353b96ab4a74796aed1541591de5890c.tar.bz2
linux-0a6dcd42353b96ab4a74796aed1541591de5890c.zip
btrfs: use blocksize to check if compression is making things larger
[BEHAVIOR DIFFERENCE BETWEEN COMPRESSION ALGOS] Currently LZO compression algorithm will check if we're making the compressed data larger after compressing more than 2 blocks. But zlib and zstd do the same checks after compressing more than 8192 bytes. This is not a big deal, but since we're already supporting larger block size (e.g. 64K block size if page size is also 64K), this check is not suitable for all block sizes. For example, if our page and block size are both 16KiB, and after the first block compressed using zlib, the resulted compressed data is slightly larger than 16KiB, we will immediately abort the compression. This makes zstd and zlib compression algorithms to behave slightly different from LZO, which only aborts after compressing two blocks. [ENHANCEMENT] To unify the behavior, only abort the compression after compressing at least two blocks. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/zlib.c3
-rw-r--r--fs/btrfs/zstd.c3
2 files changed, 4 insertions, 2 deletions
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index 21af68f93a2d..33dc7e7b5c36 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -148,6 +148,7 @@ int zlib_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
unsigned long len = *total_out;
unsigned long nr_dest_folios = *out_folios;
const unsigned long max_out = nr_dest_folios * PAGE_SIZE;
+ const u32 blocksize = inode->root->fs_info->sectorsize;
const u64 orig_end = start + len;
*out_folios = 0;
@@ -234,7 +235,7 @@ int zlib_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
}
/* we're making it bigger, give up */
- if (workspace->strm.total_in > 8192 &&
+ if (workspace->strm.total_in > blocksize * 2 &&
workspace->strm.total_in <
workspace->strm.total_out) {
ret = -E2BIG;
diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c
index 00159e0e921e..d521187336a5 100644
--- a/fs/btrfs/zstd.c
+++ b/fs/btrfs/zstd.c
@@ -400,6 +400,7 @@ int zstd_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
unsigned long len = *total_out;
const unsigned long nr_dest_folios = *out_folios;
const u64 orig_end = start + len;
+ const u32 blocksize = inode->root->fs_info->sectorsize;
unsigned long max_out = nr_dest_folios * PAGE_SIZE;
unsigned int cur_len;
@@ -456,7 +457,7 @@ int zstd_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
}
/* Check to see if we are making it bigger */
- if (tot_in + workspace->in_buf.pos > 8192 &&
+ if (tot_in + workspace->in_buf.pos > blocksize * 2 &&
tot_in + workspace->in_buf.pos <
tot_out + workspace->out_buf.pos) {
ret = -E2BIG;