mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
btrfs: fix creation of compressed inline extents that don't save space
If the compressed data of an inline extent is larger than or equals to the size of the uncompressed data, we are still allowing the creation of the compressed inline extent, which does not result in any benefits, quite the contrary as we waste metadata space and have to decompress when reading. This is a recent regression introduced in commit3eaf5f082c("btrfs: extract inlined creation into a dedicated delalloc helper"). It happens because we are passing the block size to btrfs_compress_bio(), so we don't get -E2BIG from the compression code anymore, but we can not pass i_size either, because if i_size is smaller than sector size, we end up never creating lzo compressed inline extent for such small i_size values. So refuse the compressed result at run_delalloc_inline() if its size is not smaller than the uncompressed size (i_size). Reported-by: Hanabishi <i.r.e.c.c.a.k.u.n+kernel.org@gmail.com> Link: https://lore.kernel.org/linux-btrfs/c97652a5-ac6b-4de6-aa23-3cdebc01d00b@gmail.com/ Fixes:3eaf5f082c("btrfs: extract inlined creation into a dedicated delalloc helper") CC: stable@vger.kernel.org # 7.1+ Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
f59d86d25e
commit
cc337324cc
|
|
@ -2339,12 +2339,27 @@ static int run_delalloc_inline(struct btrfs_inode *inode, struct folio *locked_f
|
|||
} else if (inode->prop_compress) {
|
||||
compress_type = inode->prop_compress;
|
||||
}
|
||||
/*
|
||||
* We need to pass blocksize and not i_size, otherwise we can't
|
||||
* create compressed inline extents for data smaller than sector
|
||||
* size with lzo.
|
||||
*/
|
||||
cb = btrfs_compress_bio(inode, 0, blocksize, compress_type, compress_level, 0);
|
||||
if (IS_ERR(cb)) {
|
||||
cb = NULL;
|
||||
/* Just fall back to non-compressed case. */
|
||||
} else {
|
||||
compressed_size = cb->bbio.bio.bi_iter.bi_size;
|
||||
/*
|
||||
* If we did not save space, it's pointless and wasteful
|
||||
* to have an inline compressed extent, so fallback to
|
||||
* an uncompressed inline extent.
|
||||
*/
|
||||
if (compressed_size >= i_size) {
|
||||
cleanup_compressed_bio(cb);
|
||||
cb = NULL;
|
||||
compressed_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!can_cow_file_range_inline(inode, 0, i_size, compressed_size)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user