]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Btrfs: do a full search everytime in btrfs_search_old_slot
authorJosef Bacik <jbacik@fusionio.com>
Tue, 24 Sep 2013 18:09:34 +0000 (14:09 -0400)
committerChris Mason <chris.mason@fusionio.com>
Tue, 12 Nov 2013 02:51:17 +0000 (21:51 -0500)
While running some snashot aware defrag tests I noticed I was panicing every
once and a while in key_search.  This is because of the optimization that says
if we find a key at slot 0 it will be at slot 0 all the way down the rest of the
tree.  This isn't the case for btrfs_search_old_slot since it will likely replay
changes to a buffer if something has changed since we took our sequence number.
So short circuit this optimization by setting prev_cmp to -1 every time we call
key_search so we will do our normal binary search.  With this patch I am no
longer seeing the panics I was seeing before.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/ctree.c

index c274a752c93d05e6aa5f8ffdb8b2651123fee06c..6932686b61cf0508a79f452b91120819a3b6cbbb 100644 (file)
@@ -2758,7 +2758,7 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key,
        int level;
        int lowest_unlock = 1;
        u8 lowest_level = 0;
-       int prev_cmp;
+       int prev_cmp = -1;
 
        lowest_level = p->lowest_level;
        WARN_ON(p->nodes[0] != NULL);
@@ -2769,7 +2769,6 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key,
        }
 
 again:
-       prev_cmp = -1;
        b = get_old_root(root, time_seq);
        level = btrfs_header_level(b);
        p->locks[level] = BTRFS_READ_LOCK;
@@ -2787,6 +2786,11 @@ again:
                 */
                btrfs_unlock_up_safe(p, level + 1);
 
+               /*
+                * Since we can unwind eb's we want to do a real search every
+                * time.
+                */
+               prev_cmp = -1;
                ret = key_search(b, key, level, &prev_cmp, &slot);
 
                if (level != 0) {