]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
btrfs: migrate btrfs_bio_ctrl::submit_bitmap to support larger bitmaps
authorQu Wenruo <wqu@suse.com>
Wed, 13 May 2026 04:36:20 +0000 (14:06 +0930)
committerFilipe Manana <fdmanana@suse.com>
Tue, 9 Jun 2026 10:49:26 +0000 (11:49 +0100)
commitea1ab09df95c44ba1738237eb3360bdd59c566eb
tree477cf1ec36e87d902570ed07e2d6c3ddd763e49a
parenteb6915bb86438a7370c84ef666a06b45c4f48627
btrfs: migrate btrfs_bio_ctrl::submit_bitmap to support larger bitmaps

[CURRENT LIMIT]
Btrfs currently only supports sub-bitmaps (e.g. dirty bitmap) no larger
than BITS_PER_LONG.

One call site that utilizes this limit is btrfs_bio_ctrl::submit_bitmap,
which makes it very simple and straightforward to just grab an unsigned
long value and assign it to submit_bitmap.

Unfortunately that limit prevents us from supporting huge folios.
For 4K page size and block size, a huge folio (order 9) means 512 blocks
inside a 2M folio.

[ENHANCEMENT]
Instead of using a fixed unsigned long value, change
btrfs_bio_ctrl::submit_bitmap to an unsigned long pointer.

And for cases where an unsigned long can hold the whole bitmap,
introduce @submit_bitmap_value, and just point that pointer to that
unsigned long.

Then update all direct users of bio_ctrl->submit_bitmap to use the
pointer version.

There are several call sites that get extra changes:

- @range_bitmap inside extent_writepage_io()
  Which is only utilized to truncate the bitmap.
  Since we do not want to allocate new memory just for such temporary
  usage, change the original bitmap_set() and bitmap_and() into
  bitmap_clear() for the ranges outside of the target range.

- Getting dirty subpage bitmap inside writepage_delalloc()
  Since we're passing an unsigned long pointer now, we need to go with
  different handling (bs == ps, blocks_per_folio <= BITS_PER_LONG,
  blocks_per_folio > BITS_PER_LONG).

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent_io.c
fs/btrfs/subpage.c
fs/btrfs/subpage.h