diff options
Diffstat (limited to 'fs/btrfs/inode-item.c')
-rw-r--r-- | fs/btrfs/inode-item.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c index 39c968f80157..65e1a76bf755 100644 --- a/fs/btrfs/inode-item.c +++ b/fs/btrfs/inode-item.c | |||
@@ -22,10 +22,10 @@ | |||
22 | #include "transaction.h" | 22 | #include "transaction.h" |
23 | #include "print-tree.h" | 23 | #include "print-tree.h" |
24 | 24 | ||
25 | static int find_name_in_backref(struct btrfs_path *path, const char *name, | 25 | int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot, |
26 | int name_len, struct btrfs_inode_ref **ref_ret) | 26 | const char *name, |
27 | int name_len, struct btrfs_inode_ref **ref_ret) | ||
27 | { | 28 | { |
28 | struct extent_buffer *leaf; | ||
29 | struct btrfs_inode_ref *ref; | 29 | struct btrfs_inode_ref *ref; |
30 | unsigned long ptr; | 30 | unsigned long ptr; |
31 | unsigned long name_ptr; | 31 | unsigned long name_ptr; |
@@ -33,9 +33,8 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name, | |||
33 | u32 cur_offset = 0; | 33 | u32 cur_offset = 0; |
34 | int len; | 34 | int len; |
35 | 35 | ||
36 | leaf = path->nodes[0]; | 36 | item_size = btrfs_item_size_nr(leaf, slot); |
37 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 37 | ptr = btrfs_item_ptr_offset(leaf, slot); |
38 | ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); | ||
39 | while (cur_offset < item_size) { | 38 | while (cur_offset < item_size) { |
40 | ref = (struct btrfs_inode_ref *)(ptr + cur_offset); | 39 | ref = (struct btrfs_inode_ref *)(ptr + cur_offset); |
41 | len = btrfs_inode_ref_name_len(leaf, ref); | 40 | 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, | |||
44 | if (len != name_len) | 43 | if (len != name_len) |
45 | continue; | 44 | continue; |
46 | if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) { | 45 | if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) { |
47 | *ref_ret = ref; | 46 | if (ref_ret) |
47 | *ref_ret = ref; | ||
48 | return 1; | 48 | return 1; |
49 | } | 49 | } |
50 | } | 50 | } |
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
53 | 53 | ||
54 | int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid, | 54 | int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot, |
55 | u64 ref_objectid, | ||
55 | const char *name, int name_len, | 56 | const char *name, int name_len, |
56 | struct btrfs_inode_extref **extref_ret) | 57 | struct btrfs_inode_extref **extref_ret) |
57 | { | 58 | { |
58 | struct extent_buffer *leaf; | ||
59 | struct btrfs_inode_extref *extref; | 59 | struct btrfs_inode_extref *extref; |
60 | unsigned long ptr; | 60 | unsigned long ptr; |
61 | unsigned long name_ptr; | 61 | unsigned long name_ptr; |
@@ -63,9 +63,8 @@ int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid, | |||
63 | u32 cur_offset = 0; | 63 | u32 cur_offset = 0; |
64 | int ref_name_len; | 64 | int ref_name_len; |
65 | 65 | ||
66 | leaf = path->nodes[0]; | 66 | item_size = btrfs_item_size_nr(leaf, slot); |
67 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 67 | ptr = btrfs_item_ptr_offset(leaf, slot); |
68 | ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); | ||
69 | 68 | ||
70 | /* | 69 | /* |
71 | * Search all extended backrefs in this item. We're only | 70 | * Search all extended backrefs in this item. We're only |
@@ -113,7 +112,9 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans, | |||
113 | return ERR_PTR(ret); | 112 | return ERR_PTR(ret); |
114 | if (ret > 0) | 113 | if (ret > 0) |
115 | return NULL; | 114 | return NULL; |
116 | if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref)) | 115 | if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0], |
116 | ref_objectid, name, name_len, | ||
117 | &extref)) | ||
117 | return NULL; | 118 | return NULL; |
118 | return extref; | 119 | return extref; |
119 | } | 120 | } |
@@ -155,7 +156,8 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans, | |||
155 | * This should always succeed so error here will make the FS | 156 | * This should always succeed so error here will make the FS |
156 | * readonly. | 157 | * readonly. |
157 | */ | 158 | */ |
158 | if (!btrfs_find_name_in_ext_backref(path, ref_objectid, | 159 | if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0], |
160 | ref_objectid, | ||
159 | name, name_len, &extref)) { | 161 | name, name_len, &extref)) { |
160 | btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL); | 162 | btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL); |
161 | ret = -EROFS; | 163 | ret = -EROFS; |
@@ -225,7 +227,8 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, | |||
225 | } else if (ret < 0) { | 227 | } else if (ret < 0) { |
226 | goto out; | 228 | goto out; |
227 | } | 229 | } |
228 | if (!find_name_in_backref(path, name, name_len, &ref)) { | 230 | if (!btrfs_find_name_in_backref(path->nodes[0], path->slots[0], |
231 | name, name_len, &ref)) { | ||
229 | ret = -ENOENT; | 232 | ret = -ENOENT; |
230 | search_ext_refs = 1; | 233 | search_ext_refs = 1; |
231 | goto out; | 234 | goto out; |
@@ -293,7 +296,9 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, | |||
293 | ret = btrfs_insert_empty_item(trans, root, path, &key, | 296 | ret = btrfs_insert_empty_item(trans, root, path, &key, |
294 | ins_len); | 297 | ins_len); |
295 | if (ret == -EEXIST) { | 298 | if (ret == -EEXIST) { |
296 | if (btrfs_find_name_in_ext_backref(path, ref_objectid, | 299 | if (btrfs_find_name_in_ext_backref(path->nodes[0], |
300 | path->slots[0], | ||
301 | ref_objectid, | ||
297 | name, name_len, NULL)) | 302 | name, name_len, NULL)) |
298 | goto out; | 303 | goto out; |
299 | 304 | ||
@@ -351,7 +356,8 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, | |||
351 | if (ret == -EEXIST) { | 356 | if (ret == -EEXIST) { |
352 | u32 old_size; | 357 | u32 old_size; |
353 | 358 | ||
354 | if (find_name_in_backref(path, name, name_len, &ref)) | 359 | if (btrfs_find_name_in_backref(path->nodes[0], path->slots[0], |
360 | name, name_len, &ref)) | ||
355 | goto out; | 361 | goto out; |
356 | 362 | ||
357 | old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); | 363 | 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, | |||
365 | ret = 0; | 371 | ret = 0; |
366 | } else if (ret < 0) { | 372 | } else if (ret < 0) { |
367 | if (ret == -EOVERFLOW) { | 373 | if (ret == -EOVERFLOW) { |
368 | if (find_name_in_backref(path, name, name_len, &ref)) | 374 | if (btrfs_find_name_in_backref(path->nodes[0], |
375 | path->slots[0], | ||
376 | name, name_len, &ref)) | ||
369 | ret = -EEXIST; | 377 | ret = -EEXIST; |
370 | else | 378 | else |
371 | ret = -EMLINK; | 379 | ret = -EMLINK; |