|
@@ -2721,6 +2721,80 @@ done:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * helper to use instead of search slot if no exact match is needed but
|
|
|
|
+ * instead the next or previous item should be returned.
|
|
|
|
+ * When find_higher is true, the next higher item is returned, the next lower
|
|
|
|
+ * otherwise.
|
|
|
|
+ * When return_any and find_higher are both true, and no higher item is found,
|
|
|
|
+ * return the next lower instead.
|
|
|
|
+ * When return_any is true and find_higher is false, and no lower item is found,
|
|
|
|
+ * return the next higher instead.
|
|
|
|
+ * It returns 0 if any item is found, 1 if none is found (tree empty), and
|
|
|
|
+ * < 0 on error
|
|
|
|
+ */
|
|
|
|
+int btrfs_search_slot_for_read(struct btrfs_root *root,
|
|
|
|
+ struct btrfs_key *key, struct btrfs_path *p,
|
|
|
|
+ int find_higher, int return_any)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+ struct extent_buffer *leaf;
|
|
|
|
+
|
|
|
|
+again:
|
|
|
|
+ ret = btrfs_search_slot(NULL, root, key, p, 0, 0);
|
|
|
|
+ if (ret <= 0)
|
|
|
|
+ return ret;
|
|
|
|
+ /*
|
|
|
|
+ * a return value of 1 means the path is at the position where the
|
|
|
|
+ * item should be inserted. Normally this is the next bigger item,
|
|
|
|
+ * but in case the previous item is the last in a leaf, path points
|
|
|
|
+ * to the first free slot in the previous leaf, i.e. at an invalid
|
|
|
|
+ * item.
|
|
|
|
+ */
|
|
|
|
+ leaf = p->nodes[0];
|
|
|
|
+
|
|
|
|
+ if (find_higher) {
|
|
|
|
+ if (p->slots[0] >= btrfs_header_nritems(leaf)) {
|
|
|
|
+ ret = btrfs_next_leaf(root, p);
|
|
|
|
+ if (ret <= 0)
|
|
|
|
+ return ret;
|
|
|
|
+ if (!return_any)
|
|
|
|
+ return 1;
|
|
|
|
+ /*
|
|
|
|
+ * no higher item found, return the next
|
|
|
|
+ * lower instead
|
|
|
|
+ */
|
|
|
|
+ return_any = 0;
|
|
|
|
+ find_higher = 0;
|
|
|
|
+ btrfs_release_path(p);
|
|
|
|
+ goto again;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (p->slots[0] == 0) {
|
|
|
|
+ ret = btrfs_prev_leaf(root, p);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ return ret;
|
|
|
|
+ if (!ret) {
|
|
|
|
+ p->slots[0] = btrfs_header_nritems(leaf) - 1;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ if (!return_any)
|
|
|
|
+ return 1;
|
|
|
|
+ /*
|
|
|
|
+ * no lower item found, return the next
|
|
|
|
+ * higher instead
|
|
|
|
+ */
|
|
|
|
+ return_any = 0;
|
|
|
|
+ find_higher = 1;
|
|
|
|
+ btrfs_release_path(p);
|
|
|
|
+ goto again;
|
|
|
|
+ } else {
|
|
|
|
+ --p->slots[0];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* adjust the pointers going up the tree, starting at level
|
|
* adjust the pointers going up the tree, starting at level
|
|
* making sure the right key of each node is points to 'key'.
|
|
* making sure the right key of each node is points to 'key'.
|