forked from Minki/linux
btrfs: introduce btrfs_search_backwards function
It's a common practice to start a search using offset (u64)-1, which is the u64 maximum value, meaning that we want the search_slot function to be set in the last item with the same objectid and type. Once we are in this position, it's a matter to start a search backwards by calling btrfs_previous_item, which will check if we'll need to go to a previous leaf and other necessary checks, only to be sure that we are in last offset of the same object and type. The new btrfs_search_backwards function does the all these steps when necessary, and can be used to avoid code duplication. Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
ea3dc7d2d1
commit
0ff40a910f
@ -2101,6 +2101,27 @@ again:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute search and call btrfs_previous_item to traverse backwards if the item
|
||||
* was not found.
|
||||
*
|
||||
* Return 0 if found, 1 if not found and < 0 if error.
|
||||
*/
|
||||
int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key,
|
||||
struct btrfs_path *path)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
|
||||
if (ret > 0)
|
||||
ret = btrfs_previous_item(root, path, key->objectid, key->type);
|
||||
|
||||
if (ret == 0)
|
||||
btrfs_item_key_to_cpu(path->nodes[0], key, path->slots[0]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* adjust the pointers going up the tree, starting at level
|
||||
* making sure the right key of each node is points to 'key'.
|
||||
|
@ -2908,6 +2908,10 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
|
||||
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
|
||||
int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
|
||||
u64 time_seq);
|
||||
|
||||
int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key,
|
||||
struct btrfs_path *path);
|
||||
|
||||
static inline int btrfs_next_old_item(struct btrfs_root *root,
|
||||
struct btrfs_path *p, u64 time_seq)
|
||||
{
|
||||
|
@ -2389,23 +2389,16 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
|
||||
key.offset = (u64)-1;
|
||||
|
||||
while (1) {
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
ret = btrfs_search_backwards(root, &key, path);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
else if (ret > 0) {
|
||||
ret = btrfs_previous_item(root, path, dirid,
|
||||
BTRFS_INODE_REF_KEY);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
else if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
l = path->nodes[0];
|
||||
slot = path->slots[0];
|
||||
btrfs_item_key_to_cpu(l, &key, slot);
|
||||
|
||||
iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref);
|
||||
len = btrfs_inode_ref_name_len(l, iref);
|
||||
@ -2480,23 +2473,16 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
|
||||
key.type = BTRFS_INODE_REF_KEY;
|
||||
key.offset = (u64)-1;
|
||||
while (1) {
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
if (ret < 0) {
|
||||
ret = btrfs_search_backwards(root, &key, path);
|
||||
if (ret < 0)
|
||||
goto out_put;
|
||||
else if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
goto out_put;
|
||||
} else if (ret > 0) {
|
||||
ret = btrfs_previous_item(root, path, dirid,
|
||||
BTRFS_INODE_REF_KEY);
|
||||
if (ret < 0) {
|
||||
goto out_put;
|
||||
} else if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
goto out_put;
|
||||
}
|
||||
}
|
||||
|
||||
leaf = path->nodes[0];
|
||||
slot = path->slots[0];
|
||||
btrfs_item_key_to_cpu(leaf, &key, slot);
|
||||
|
||||
iref = btrfs_item_ptr(leaf, slot, struct btrfs_inode_ref);
|
||||
len = btrfs_inode_ref_name_len(leaf, iref);
|
||||
|
@ -1201,21 +1201,14 @@ char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
|
||||
key.type = BTRFS_ROOT_BACKREF_KEY;
|
||||
key.offset = (u64)-1;
|
||||
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
ret = btrfs_search_backwards(root, &key, path);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
} else if (ret > 0) {
|
||||
ret = btrfs_previous_item(root, path, subvol_objectid,
|
||||
BTRFS_ROOT_BACKREF_KEY);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
} else if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
ret = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
|
||||
subvol_objectid = key.offset;
|
||||
|
||||
root_ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
|
||||
@ -1248,21 +1241,14 @@ char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
|
||||
key.type = BTRFS_INODE_REF_KEY;
|
||||
key.offset = (u64)-1;
|
||||
|
||||
ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
|
||||
ret = btrfs_search_backwards(fs_root, &key, path);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
} else if (ret > 0) {
|
||||
ret = btrfs_previous_item(fs_root, path, dirid,
|
||||
BTRFS_INODE_REF_KEY);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
} else if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
ret = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
|
||||
dirid = key.offset;
|
||||
|
||||
inode_ref = btrfs_item_ptr(path->nodes[0],
|
||||
|
@ -1586,14 +1586,9 @@ again:
|
||||
key.offset = search_start;
|
||||
key.type = BTRFS_DEV_EXTENT_KEY;
|
||||
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
ret = btrfs_search_backwards(root, &key, path);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (ret > 0) {
|
||||
ret = btrfs_previous_item(root, path, key.objectid, key.type);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
l = path->nodes[0];
|
||||
|
Loading…
Reference in New Issue
Block a user