summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chen <davechen@synology.com>2026-03-30 11:31:48 +0800
committerDavid Sterba <dsterba@suse.com>2026-04-07 19:43:22 +0200
commite0dfaebb8f4a1de59a8b805d600e3b662b235efc (patch)
tree66b667b91fc7fc904d40c4a79f6c205f7588cc76
parente70e3f858e084aee34a2206e5f4dd49a47673f6a (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.c10
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);