|
@@ -2426,6 +2426,40 @@ done:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static void key_search_validate(struct extent_buffer *b,
|
|
|
+ struct btrfs_key *key,
|
|
|
+ int level)
|
|
|
+{
|
|
|
+#ifdef CONFIG_BTRFS_ASSERT
|
|
|
+ struct btrfs_disk_key disk_key;
|
|
|
+
|
|
|
+ btrfs_cpu_key_to_disk(&disk_key, key);
|
|
|
+
|
|
|
+ if (level == 0)
|
|
|
+ ASSERT(!memcmp_extent_buffer(b, &disk_key,
|
|
|
+ offsetof(struct btrfs_leaf, items[0].key),
|
|
|
+ sizeof(disk_key)));
|
|
|
+ else
|
|
|
+ ASSERT(!memcmp_extent_buffer(b, &disk_key,
|
|
|
+ offsetof(struct btrfs_node, ptrs[0].key),
|
|
|
+ sizeof(disk_key)));
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+static int key_search(struct extent_buffer *b, struct btrfs_key *key,
|
|
|
+ int level, int *prev_cmp, int *slot)
|
|
|
+{
|
|
|
+ if (*prev_cmp != 0) {
|
|
|
+ *prev_cmp = bin_search(b, key, level, slot);
|
|
|
+ return *prev_cmp;
|
|
|
+ }
|
|
|
+
|
|
|
+ key_search_validate(b, key, level);
|
|
|
+ *slot = 0;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* look for key in the tree. path is filled in with nodes along the way
|
|
|
* if key is found, we return zero and you can find the item in the leaf
|
|
@@ -2454,6 +2488,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
|
int write_lock_level = 0;
|
|
|
u8 lowest_level = 0;
|
|
|
int min_write_lock_level;
|
|
|
+ int prev_cmp;
|
|
|
|
|
|
lowest_level = p->lowest_level;
|
|
|
WARN_ON(lowest_level && ins_len > 0);
|
|
@@ -2484,6 +2519,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
|
min_write_lock_level = write_lock_level;
|
|
|
|
|
|
again:
|
|
|
+ prev_cmp = -1;
|
|
|
/*
|
|
|
* we try very hard to do read locks on the root
|
|
|
*/
|
|
@@ -2584,7 +2620,7 @@ cow_done:
|
|
|
if (!cow)
|
|
|
btrfs_unlock_up_safe(p, level + 1);
|
|
|
|
|
|
- ret = bin_search(b, key, level, &slot);
|
|
|
+ ret = key_search(b, key, level, &prev_cmp, &slot);
|
|
|
|
|
|
if (level != 0) {
|
|
|
int dec = 0;
|
|
@@ -2719,6 +2755,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;
|
|
|
|
|
|
lowest_level = p->lowest_level;
|
|
|
WARN_ON(p->nodes[0] != NULL);
|
|
@@ -2729,6 +2766,7 @@ 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;
|
|
@@ -2746,7 +2784,7 @@ again:
|
|
|
*/
|
|
|
btrfs_unlock_up_safe(p, level + 1);
|
|
|
|
|
|
- ret = bin_search(b, key, level, &slot);
|
|
|
+ ret = key_search(b, key, level, &prev_cmp, &slot);
|
|
|
|
|
|
if (level != 0) {
|
|
|
int dec = 0;
|