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:
Sun YangKai 2025-11-14 15:24:47 +08:00 committed by David Sterba
parent 3afa17bf24
commit 139f75a3b1

View File

@ -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) {