mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
btrfs: simplify leaf traversal after path release in btrfs_next_old_leaf()
After releasing the path in btrfs_next_old_leaf(), we need to re-check the leaf because a balance operation may have added items or removed the last item. The original code handled this with two separate conditional blocks, the second marked with a lengthy comment explaining a "missed case". Merge these two blocks into a single logical structure that handles both scenarios more clearly. Also update the comment to be more concise and accurate, incorporating the explanation directly into the main block rather than a separate annotation. Signed-off-by: Sun YangKai <sunk67188@gmail.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
3afa17bf24
commit
139f75a3b1
|
|
@ -4853,34 +4853,23 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
|
|||
|
||||
nritems = btrfs_header_nritems(path->nodes[0]);
|
||||
/*
|
||||
* by releasing the path above we dropped all our locks. A balance
|
||||
* could have added more items next to the key that used to be
|
||||
* at the very end of the block. So, check again here and
|
||||
* advance the path if there are now more items available.
|
||||
* By releasing the path above we dropped all our locks. A balance
|
||||
* could have happened and
|
||||
*
|
||||
* 1. added more items after the previous last item
|
||||
* 2. deleted the previous last item
|
||||
*
|
||||
* So, check again here and advance the path if there are now more
|
||||
* items available.
|
||||
*/
|
||||
if (nritems > 0 && path->slots[0] < nritems - 1) {
|
||||
if (ret == 0)
|
||||
if (nritems > 0 && path->slots[0] <= nritems - 1) {
|
||||
if (ret == 0 && path->slots[0] != nritems - 1) {
|
||||
path->slots[0]++;
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* So the above check misses one case:
|
||||
* - after releasing the path above, someone has removed the item that
|
||||
* used to be at the very end of the block, and balance between leafs
|
||||
* gets another one with bigger key.offset to replace it.
|
||||
*
|
||||
* This one should be returned as well, or we can get leaf corruption
|
||||
* later(esp. in __btrfs_drop_extents()).
|
||||
*
|
||||
* And a bit more explanation about this check,
|
||||
* with ret > 0, the key isn't found, the path points to the slot
|
||||
* where it should be inserted, so the path->slots[0] item must be the
|
||||
* bigger one.
|
||||
*/
|
||||
if (nritems > 0 && ret > 0 && path->slots[0] == nritems - 1) {
|
||||
ret = 0;
|
||||
goto done;
|
||||
goto done;
|
||||
} else if (ret > 0) {
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
while (level < BTRFS_MAX_LEVEL) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user