]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: simplify leaf traversal after path release in btrfs_next_old_leaf()
authorSun YangKai <sunk67188@gmail.com>
Fri, 14 Nov 2025 07:24:47 +0000 (15:24 +0800)
committerDavid Sterba <dsterba@suse.com>
Tue, 25 Nov 2025 00:50:56 +0000 (01:50 +0100)
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>
fs/btrfs/ctree.c

index 4df4c6cda620d8fb19adb16ecb7d50bc2c7ade45..fc712e00d4fb57a4ea3497697ee6cb3f058c2805 100644 (file)
@@ -4853,34 +4853,23 @@ again:
 
        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.
-        */
-       if (nritems > 0 && path->slots[0] < nritems - 1) {
-               if (ret == 0)
-                       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.
+        * By releasing the path above we dropped all our locks.  A balance
+        * could have happened and
         *
-        * This one should be returned as well, or we can get leaf corruption
-        * later(esp. in __btrfs_drop_extents()).
+        * 1. added more items after the previous last item
+        * 2. deleted the previous last item
         *
-        * 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.
+        * So, check again here and advance the path if there are now more
+        * items available.
         */
-       if (nritems > 0 && ret > 0 && path->slots[0] == nritems - 1) {
-               ret = 0;
-               goto done;
+       if (nritems > 0 && path->slots[0] <= nritems - 1) {
+               if (ret == 0 && path->slots[0] != nritems - 1) {
+                       path->slots[0]++;
+                       goto done;
+               } else if (ret > 0) {
+                       ret = 0;
+                       goto done;
+               }
        }
 
        while (level < BTRFS_MAX_LEVEL) {