diff options
| author | Dave Chen <davechen@synology.com> | 2026-03-30 11:31:48 +0800 |
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2026-04-07 19:43:22 +0200 |
| commit | e0dfaebb8f4a1de59a8b805d600e3b662b235efc (patch) | |
| tree | 66b667b91fc7fc904d40c4a79f6c205f7588cc76 | |
| parent | e70e3f858e084aee34a2206e5f4dd49a47673f6a (diff) | |
btrfs: skip clearing EXTENT_DEFRAG for NOCOW ordered extents
In btrfs_finish_one_ordered(), clear_bits is unconditionally initialized
with EXTENT_DEFRAG. For NOCOW ordered extents this is always a no-op
because should_nocow() already forces the COW path when EXTENT_DEFRAG is
set, so a NOCOW ordered extent can never have EXTENT_DEFRAG on its range.
Although harmless, the unconditional btrfs_clear_extent_bit() call still
performs a cold rbtree lookup under the io tree spinlock on every NOCOW
write completion. Avoid this by only adding EXTENT_DEFRAG to clear_bits
for non-NOCOW ordered extents, and skip the call entirely when there are
no bits to clear.
Signed-off-by: Dave Chen <davechen@synology.com>
Signed-off-by: Robbie Ko <robbieko@synology.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
| -rw-r--r-- | fs/btrfs/inode.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 808e52aa6ef2..40474014c03f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3197,7 +3197,7 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) bool freespace_inode; bool truncated = false; bool clear_reserved_extent = true; - unsigned int clear_bits = EXTENT_DEFRAG; + unsigned int clear_bits = 0; start = ordered_extent->file_offset; end = start + ordered_extent->num_bytes - 1; @@ -3208,6 +3208,9 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) !test_bit(BTRFS_ORDERED_ENCODED, &ordered_extent->flags)) clear_bits |= EXTENT_DELALLOC_NEW; + if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) + clear_bits |= EXTENT_DEFRAG; + freespace_inode = btrfs_is_free_space_inode(inode); if (!freespace_inode) btrfs_lockdep_acquire(fs_info, btrfs_ordered_extent); @@ -3339,8 +3342,9 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) goto out; } out: - btrfs_clear_extent_bit(&inode->io_tree, start, end, clear_bits, - &cached_state); + if (clear_bits) + btrfs_clear_extent_bit(&inode->io_tree, start, end, clear_bits, + &cached_state); if (trans) btrfs_end_transaction(trans); |
