]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: replace for_each_set_bit() with for_each_set_bitmap()
authorQu Wenruo <wqu@suse.com>
Wed, 10 Dec 2025 08:32:34 +0000 (19:02 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 3 Feb 2026 05:38:32 +0000 (06:38 +0100)
Inside extent_io.c, there are several simple call sites doing things
like:

for_each_set_bit(bit, bitmap, bitmap_size) {
/* handle one fs block */
}

The workload includes:

- set_bit()
  Inside extent_writepage_io().

  This can be replaced with a bitmap_set().

- btrfs_folio_set_lock()
- btrfs_mark_ordered_io_finished()
  Inside writepage_delalloc().

  Instead of calling it multiple times, we can pass a range into the
  function with one call.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent_io.c

index 9d4a95e4e2e724b6f9319f6609224fe960a2e2e6..f804131b1c78e1b4a743a878be8d488d19620489 100644 (file)
@@ -1439,8 +1439,9 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
        u64 delalloc_start = page_start;
        u64 delalloc_end = page_end;
        u64 delalloc_to_write = 0;
+       unsigned int start_bit;
+       unsigned int end_bit;
        int ret = 0;
-       int bit;
 
        /* Save the dirty bitmap as our submission bitmap will be a subset of it. */
        if (btrfs_is_subpage(fs_info, folio)) {
@@ -1450,10 +1451,12 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
                bio_ctrl->submit_bitmap = 1;
        }
 
-       for_each_set_bit(bit, &bio_ctrl->submit_bitmap, blocks_per_folio) {
-               u64 start = page_start + (bit << fs_info->sectorsize_bits);
+       for_each_set_bitrange(start_bit, end_bit, &bio_ctrl->submit_bitmap,
+                             blocks_per_folio) {
+               u64 start = page_start + (start_bit << fs_info->sectorsize_bits);
+               u32 len = (end_bit - start_bit) << fs_info->sectorsize_bits;
 
-               btrfs_folio_set_lock(fs_info, folio, start, fs_info->sectorsize);
+               btrfs_folio_set_lock(fs_info, folio, start, len);
        }
 
        /* Lock all (subpage) delalloc ranges inside the folio first. */
@@ -1570,10 +1573,13 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
                                fs_info->sectorsize_bits,
                                blocks_per_folio);
 
-               for_each_set_bit(bit, &bio_ctrl->submit_bitmap, bitmap_size)
-                       btrfs_mark_ordered_io_finished(inode, folio,
-                               page_start + (bit << fs_info->sectorsize_bits),
-                               fs_info->sectorsize, false);
+               for_each_set_bitrange(start_bit, end_bit, &bio_ctrl->submit_bitmap,
+                                     bitmap_size) {
+                       u64 start = page_start + (start_bit << fs_info->sectorsize_bits);
+                       u32 len = (end_bit - start_bit) << fs_info->sectorsize_bits;
+
+                       btrfs_mark_ordered_io_finished(inode, folio, start, len, false);
+               }
                return ret;
        }
 out:
@@ -1741,8 +1747,8 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
                return ret;
        }
 
-       for (cur = start; cur < end; cur += fs_info->sectorsize)
-               set_bit((cur - folio_start) >> fs_info->sectorsize_bits, &range_bitmap);
+       bitmap_set(&range_bitmap, (start - folio_pos(folio)) >> fs_info->sectorsize_bits,
+                  len >> fs_info->sectorsize_bits);
        bitmap_and(&bio_ctrl->submit_bitmap, &bio_ctrl->submit_bitmap, &range_bitmap,
                   blocks_per_folio);