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

btrfs: Adjust loop in free_extent_buffer

The loop construct in free_extent_buffer was added in
242e18c7c1a8 ("Btrfs: reduce lock contention on extent buffer locks")
as means of reducing the times the eb lock is taken, the non-last ref
count is decremented and lock is released. As the special handling
of UNMAPPED extent buffers was removed now there is only one decrement
op which is happening for EXTENT_BUFFER_UNMAPPED case.

This commit modifies the loop condition so that in case of UNMAPPED
buffers the eb's lock is taken only if we are 100% sure the eb is going
to be freed by the current executor of the code. Additionally, remove
superfluous ref count ops in btrfs test.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by

Nikolay Borisov and committed by
David Sterba
46cc775e 9cfc8ba7

+3 -9
+3 -1
fs/btrfs/extent_io.c
··· 5074 5074 5075 5075 while (1) { 5076 5076 refs = atomic_read(&eb->refs); 5077 - if (refs <= 3) 5077 + if ((!test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags) && refs <= 3) 5078 + || (test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags) && 5079 + refs == 1)) 5078 5080 break; 5079 5081 old = atomic_cmpxchg(&eb->refs, refs, refs - 1); 5080 5082 if (old == refs)
-2
fs/btrfs/tests/btrfs-tests.c
··· 177 177 if (root->node) { 178 178 /* One for allocate_extent_buffer */ 179 179 free_extent_buffer(root->node); 180 - /* One for get_exent_buffer */ 181 - free_extent_buffer(root->node); 182 180 } 183 181 kfree(root); 184 182 }
-6
fs/btrfs/tests/inode-tests.c
··· 254 254 goto out; 255 255 } 256 256 257 - /* 258 - * We will just free a dummy node if it's ref count is 2 so we need an 259 - * extra ref so our searches don't accidentally release our page. 260 - */ 261 - extent_buffer_get(root->node); 262 257 btrfs_set_header_nritems(root->node, 0); 263 258 btrfs_set_header_level(root->node, 0); 264 259 ret = -EINVAL; ··· 855 860 goto out; 856 861 } 857 862 858 - extent_buffer_get(root->node); 859 863 btrfs_set_header_nritems(root->node, 0); 860 864 btrfs_set_header_level(root->node, 0); 861 865 BTRFS_I(inode)->root = root;