|
@@ -22,10 +22,10 @@
|
|
#include "transaction.h"
|
|
#include "transaction.h"
|
|
#include "print-tree.h"
|
|
#include "print-tree.h"
|
|
|
|
|
|
-static int find_name_in_backref(struct btrfs_path *path, const char *name,
|
|
|
|
- int name_len, struct btrfs_inode_ref **ref_ret)
|
|
|
|
|
|
+int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot,
|
|
|
|
+ const char *name,
|
|
|
|
+ int name_len, struct btrfs_inode_ref **ref_ret)
|
|
{
|
|
{
|
|
- struct extent_buffer *leaf;
|
|
|
|
struct btrfs_inode_ref *ref;
|
|
struct btrfs_inode_ref *ref;
|
|
unsigned long ptr;
|
|
unsigned long ptr;
|
|
unsigned long name_ptr;
|
|
unsigned long name_ptr;
|
|
@@ -33,9 +33,8 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
|
|
u32 cur_offset = 0;
|
|
u32 cur_offset = 0;
|
|
int len;
|
|
int len;
|
|
|
|
|
|
- leaf = path->nodes[0];
|
|
|
|
- item_size = btrfs_item_size_nr(leaf, path->slots[0]);
|
|
|
|
- ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
|
|
|
|
|
|
+ item_size = btrfs_item_size_nr(leaf, slot);
|
|
|
|
+ ptr = btrfs_item_ptr_offset(leaf, slot);
|
|
while (cur_offset < item_size) {
|
|
while (cur_offset < item_size) {
|
|
ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
|
|
ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
|
|
len = btrfs_inode_ref_name_len(leaf, ref);
|
|
len = btrfs_inode_ref_name_len(leaf, ref);
|
|
@@ -44,18 +43,19 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
|
|
if (len != name_len)
|
|
if (len != name_len)
|
|
continue;
|
|
continue;
|
|
if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) {
|
|
if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) {
|
|
- *ref_ret = ref;
|
|
|
|
|
|
+ if (ref_ret)
|
|
|
|
+ *ref_ret = ref;
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
|
|
|
|
|
|
+int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
|
|
|
|
+ u64 ref_objectid,
|
|
const char *name, int name_len,
|
|
const char *name, int name_len,
|
|
struct btrfs_inode_extref **extref_ret)
|
|
struct btrfs_inode_extref **extref_ret)
|
|
{
|
|
{
|
|
- struct extent_buffer *leaf;
|
|
|
|
struct btrfs_inode_extref *extref;
|
|
struct btrfs_inode_extref *extref;
|
|
unsigned long ptr;
|
|
unsigned long ptr;
|
|
unsigned long name_ptr;
|
|
unsigned long name_ptr;
|
|
@@ -63,9 +63,8 @@ int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
|
|
u32 cur_offset = 0;
|
|
u32 cur_offset = 0;
|
|
int ref_name_len;
|
|
int ref_name_len;
|
|
|
|
|
|
- leaf = path->nodes[0];
|
|
|
|
- item_size = btrfs_item_size_nr(leaf, path->slots[0]);
|
|
|
|
- ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
|
|
|
|
|
|
+ item_size = btrfs_item_size_nr(leaf, slot);
|
|
|
|
+ ptr = btrfs_item_ptr_offset(leaf, slot);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Search all extended backrefs in this item. We're only
|
|
* Search all extended backrefs in this item. We're only
|
|
@@ -113,7 +112,9 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
|
|
return ERR_PTR(ret);
|
|
return ERR_PTR(ret);
|
|
if (ret > 0)
|
|
if (ret > 0)
|
|
return NULL;
|
|
return NULL;
|
|
- if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref))
|
|
|
|
|
|
+ if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
|
|
|
|
+ ref_objectid, name, name_len,
|
|
|
|
+ &extref))
|
|
return NULL;
|
|
return NULL;
|
|
return extref;
|
|
return extref;
|
|
}
|
|
}
|
|
@@ -155,7 +156,8 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
|
|
* This should always succeed so error here will make the FS
|
|
* This should always succeed so error here will make the FS
|
|
* readonly.
|
|
* readonly.
|
|
*/
|
|
*/
|
|
- if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
|
|
|
|
|
|
+ if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
|
|
|
|
+ ref_objectid,
|
|
name, name_len, &extref)) {
|
|
name, name_len, &extref)) {
|
|
btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
|
|
btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
|
|
ret = -EROFS;
|
|
ret = -EROFS;
|
|
@@ -225,7 +227,8 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
|
|
} else if (ret < 0) {
|
|
} else if (ret < 0) {
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
- if (!find_name_in_backref(path, name, name_len, &ref)) {
|
|
|
|
|
|
+ if (!btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
|
|
|
|
+ name, name_len, &ref)) {
|
|
ret = -ENOENT;
|
|
ret = -ENOENT;
|
|
search_ext_refs = 1;
|
|
search_ext_refs = 1;
|
|
goto out;
|
|
goto out;
|
|
@@ -293,7 +296,9 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
|
|
ret = btrfs_insert_empty_item(trans, root, path, &key,
|
|
ret = btrfs_insert_empty_item(trans, root, path, &key,
|
|
ins_len);
|
|
ins_len);
|
|
if (ret == -EEXIST) {
|
|
if (ret == -EEXIST) {
|
|
- if (btrfs_find_name_in_ext_backref(path, ref_objectid,
|
|
|
|
|
|
+ if (btrfs_find_name_in_ext_backref(path->nodes[0],
|
|
|
|
+ path->slots[0],
|
|
|
|
+ ref_objectid,
|
|
name, name_len, NULL))
|
|
name, name_len, NULL))
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
@@ -351,7 +356,8 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
|
|
if (ret == -EEXIST) {
|
|
if (ret == -EEXIST) {
|
|
u32 old_size;
|
|
u32 old_size;
|
|
|
|
|
|
- if (find_name_in_backref(path, name, name_len, &ref))
|
|
|
|
|
|
+ if (btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
|
|
|
|
+ name, name_len, &ref))
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
|
|
old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
|
|
@@ -365,7 +371,9 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
|
|
ret = 0;
|
|
ret = 0;
|
|
} else if (ret < 0) {
|
|
} else if (ret < 0) {
|
|
if (ret == -EOVERFLOW) {
|
|
if (ret == -EOVERFLOW) {
|
|
- if (find_name_in_backref(path, name, name_len, &ref))
|
|
|
|
|
|
+ if (btrfs_find_name_in_backref(path->nodes[0],
|
|
|
|
+ path->slots[0],
|
|
|
|
+ name, name_len, &ref))
|
|
ret = -EEXIST;
|
|
ret = -EEXIST;
|
|
else
|
|
else
|
|
ret = -EMLINK;
|
|
ret = -EMLINK;
|