Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Dave Chen and committed by
David Sterba
e0dfaebb e70e3f85

+7 -3
+7 -3
fs/btrfs/inode.c
··· 3197 3197 bool freespace_inode; 3198 3198 bool truncated = false; 3199 3199 bool clear_reserved_extent = true; 3200 - unsigned int clear_bits = EXTENT_DEFRAG; 3200 + unsigned int clear_bits = 0; 3201 3201 3202 3202 start = ordered_extent->file_offset; 3203 3203 end = start + ordered_extent->num_bytes - 1; ··· 3207 3207 !test_bit(BTRFS_ORDERED_DIRECT, &ordered_extent->flags) && 3208 3208 !test_bit(BTRFS_ORDERED_ENCODED, &ordered_extent->flags)) 3209 3209 clear_bits |= EXTENT_DELALLOC_NEW; 3210 + 3211 + if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) 3212 + clear_bits |= EXTENT_DEFRAG; 3210 3213 3211 3214 freespace_inode = btrfs_is_free_space_inode(inode); 3212 3215 if (!freespace_inode) ··· 3342 3339 goto out; 3343 3340 } 3344 3341 out: 3345 - btrfs_clear_extent_bit(&inode->io_tree, start, end, clear_bits, 3346 - &cached_state); 3342 + if (clear_bits) 3343 + btrfs_clear_extent_bit(&inode->io_tree, start, end, clear_bits, 3344 + &cached_state); 3347 3345 3348 3346 if (trans) 3349 3347 btrfs_end_transaction(trans);