* [PATCH] btrfs: do compressed bio size roundup and zeroing in one go
@ 2026-02-19 23:43 Qu Wenruo
2026-02-24 13:41 ` Anand Jain
2026-02-24 14:06 ` David Sterba
0 siblings, 2 replies; 4+ messages in thread
From: Qu Wenruo @ 2026-02-19 23:43 UTC (permalink / raw)
To: linux-btrfs
Currently we zero out all the remaining bytes of the last folio of
the compressed bio, then round the bio size to fs block boundary.
But that is done in two different functions, zero_last_folio() to zero
the remaining bytes of the last folio, and round_up_last_block() to
round up the bio to fs block boundary.
There are some minor problems:
- zero_last_folio() is zeroing ranges we won't submit
This is mostly affecting block size < page size cases, where we can
have a large folio (e.g. 64K), but the fs block size is only 4K.
In that case, we may only want to submit the first 4K of the folio,
the remaining range won't matter, but we still zero them all.
This causes unnecessary CPU usage just to zero out some bytes we won't
utilized.
- compressed_bio_last_folio() is called twice in two different functions
Which in theory we only need to call it once.
Enhance the situation by:
- Only zero out bytes up to the fs block boundary
Thus this will reduce some overhead for bs < ps cases.
- Move the folio_zero_range() call into round_up_last_block()
So that we can reuse the same folio returned by
compressed_bio_last_folio().
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/inode.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 471fb08ebff2..07d6c39f4a3f 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -842,28 +842,20 @@ static struct folio *compressed_bio_last_folio(struct compressed_bio *cb)
return page_folio(phys_to_page(paddr));
}
-static void zero_last_folio(struct compressed_bio *cb)
-{
- struct bio *bio = &cb->bbio.bio;
- struct folio *last_folio = compressed_bio_last_folio(cb);
- const u32 bio_size = bio->bi_iter.bi_size;
- const u32 foffset = offset_in_folio(last_folio, bio_size);
-
- folio_zero_range(last_folio, foffset, folio_size(last_folio) - foffset);
-}
-
static void round_up_last_block(struct compressed_bio *cb, u32 blocksize)
{
struct bio *bio = &cb->bbio.bio;
struct folio *last_folio = compressed_bio_last_folio(cb);
const u32 bio_size = bio->bi_iter.bi_size;
const u32 foffset = offset_in_folio(last_folio, bio_size);
+ const u32 padding_len = round_up(foffset, blocksize) - foffset;
bool ret;
if (IS_ALIGNED(bio_size, blocksize))
return;
- ret = bio_add_folio(bio, last_folio, round_up(foffset, blocksize) - foffset, foffset);
+ folio_zero_range(last_folio, foffset, padding_len);
+ ret = bio_add_folio(bio, last_folio, padding_len, foffset);
/* The remaining part should be merged thus never fail. */
ASSERT(ret);
}
@@ -888,7 +880,6 @@ static void compress_file_range(struct btrfs_work *work)
struct btrfs_inode *inode = async_chunk->inode;
struct btrfs_fs_info *fs_info = inode->root->fs_info;
struct compressed_bio *cb = NULL;
- const u32 min_folio_size = btrfs_min_folio_size(fs_info);
u64 blocksize = fs_info->sectorsize;
u64 start = async_chunk->start;
u64 end = async_chunk->end;
@@ -898,7 +889,6 @@ static void compress_file_range(struct btrfs_work *work)
int ret = 0;
unsigned long total_compressed = 0;
unsigned long total_in = 0;
- unsigned int loff;
int compress_type = fs_info->compress_type;
int compress_level = fs_info->compress_level;
@@ -981,20 +971,13 @@ static void compress_file_range(struct btrfs_work *work)
total_compressed = cb->bbio.bio.bi_iter.bi_size;
total_in = cur_len;
- /*
- * Zero the tail end of the last folio, as we might be sending it down
- * to disk.
- */
- loff = (total_compressed & (min_folio_size - 1));
- if (loff)
- zero_last_folio(cb);
-
/*
* We aren't doing an inline extent. Round the compressed size up to a
* block size boundary so the allocator does sane things.
*/
- total_compressed = ALIGN(total_compressed, blocksize);
round_up_last_block(cb, blocksize);
+ total_compressed = cb->bbio.bio.bi_iter.bi_size;
+ ASSERT(IS_ALIGNED(total_compressed, blocksize));
/*
* One last check to make sure the compression is really a win, compare
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] btrfs: do compressed bio size roundup and zeroing in one go
2026-02-19 23:43 [PATCH] btrfs: do compressed bio size roundup and zeroing in one go Qu Wenruo
@ 2026-02-24 13:41 ` Anand Jain
2026-02-24 22:05 ` Qu Wenruo
2026-02-24 14:06 ` David Sterba
1 sibling, 1 reply; 4+ messages in thread
From: Anand Jain @ 2026-02-24 13:41 UTC (permalink / raw)
To: Qu Wenruo, linux-btrfs
Looks good to me.
Reviewed-by: Anand Jain <asj@kernel.org>
Anan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] btrfs: do compressed bio size roundup and zeroing in one go
2026-02-19 23:43 [PATCH] btrfs: do compressed bio size roundup and zeroing in one go Qu Wenruo
2026-02-24 13:41 ` Anand Jain
@ 2026-02-24 14:06 ` David Sterba
1 sibling, 0 replies; 4+ messages in thread
From: David Sterba @ 2026-02-24 14:06 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Fri, Feb 20, 2026 at 10:13:38AM +1030, Qu Wenruo wrote:
> Currently we zero out all the remaining bytes of the last folio of
> the compressed bio, then round the bio size to fs block boundary.
>
> But that is done in two different functions, zero_last_folio() to zero
> the remaining bytes of the last folio, and round_up_last_block() to
> round up the bio to fs block boundary.
>
> There are some minor problems:
>
> - zero_last_folio() is zeroing ranges we won't submit
> This is mostly affecting block size < page size cases, where we can
> have a large folio (e.g. 64K), but the fs block size is only 4K.
>
> In that case, we may only want to submit the first 4K of the folio,
> the remaining range won't matter, but we still zero them all.
>
> This causes unnecessary CPU usage just to zero out some bytes we won't
> utilized.
>
> - compressed_bio_last_folio() is called twice in two different functions
> Which in theory we only need to call it once.
>
> Enhance the situation by:
>
> - Only zero out bytes up to the fs block boundary
> Thus this will reduce some overhead for bs < ps cases.
>
> - Move the folio_zero_range() call into round_up_last_block()
> So that we can reuse the same folio returned by
> compressed_bio_last_folio().
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-02-24 22:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 23:43 [PATCH] btrfs: do compressed bio size roundup and zeroing in one go Qu Wenruo
2026-02-24 13:41 ` Anand Jain
2026-02-24 22:05 ` Qu Wenruo
2026-02-24 14:06 ` David Sterba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox