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: fix raid stripe search missing entries at leaf boundaries

In btrfs_delete_raid_extent(), the search key uses offset=0. When the
target stripe entry is the first item on a leaf, btrfs_search_slot()
may land on the previous leaf and decrementing the slot from nritems
still points to the wrong entry, causing the stripe extent to be
silently missed.

Fix this by searching with offset=(u64)-1 instead. Since no real stripe
entry has this offset, btrfs_search_slot() always returns 1 with the
slot pointing past the last matching objectid entry. Then unconditionally
decrement the slot with a proper slots[0]==0 early-exit check to handle
the case where no matching entry exists.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: robbieko <robbieko@synology.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by

robbieko and committed by
David Sterba
2aef5cb1 513f8a52

+15 -3
+15 -3
fs/btrfs/raid-stripe-tree.c
··· 98 98 while (1) { 99 99 key.objectid = start; 100 100 key.type = BTRFS_RAID_STRIPE_KEY; 101 - key.offset = 0; 101 + key.offset = (u64)-1; 102 102 103 103 ret = btrfs_search_slot(trans, stripe_root, &key, path, -1, 1); 104 104 if (ret < 0) 105 105 break; 106 106 107 - if (path->slots[0] == btrfs_header_nritems(path->nodes[0])) 108 - path->slots[0]--; 107 + /* 108 + * Search with offset=(u64)-1 ensures we land on the correct 109 + * leaf even when the target entry is the first item on a leaf. 110 + * Since no real entry has offset=(u64)-1, ret is always 1 and 111 + * slot points past the last entry with objectid==start (or 112 + * past the end of the leaf if that entry is the last item). 113 + * Back up one slot to find the actual entry. 114 + */ 115 + if (path->slots[0] == 0) { 116 + /* No entry with objectid <= start exists. */ 117 + ret = 0; 118 + break; 119 + } 120 + path->slots[0]--; 109 121 110 122 leaf = path->nodes[0]; 111 123 slot = path->slots[0];