diff options
Diffstat (limited to 'fs/btrfs/dir-item.c')
-rw-r--r-- | fs/btrfs/dir-item.c | 102 |
1 files changed, 56 insertions, 46 deletions
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 49db5fa7ced3..6f19de41b878 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c | |||
@@ -33,7 +33,7 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle | |||
33 | int ret; | 33 | int ret; |
34 | char *ptr; | 34 | char *ptr; |
35 | struct btrfs_item *item; | 35 | struct btrfs_item *item; |
36 | struct btrfs_leaf *leaf; | 36 | struct extent_buffer *leaf; |
37 | 37 | ||
38 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); | 38 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); |
39 | if (ret == -EEXIST) { | 39 | if (ret == -EEXIST) { |
@@ -49,11 +49,11 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle | |||
49 | if (ret < 0) | 49 | if (ret < 0) |
50 | return ERR_PTR(ret); | 50 | return ERR_PTR(ret); |
51 | WARN_ON(ret > 0); | 51 | WARN_ON(ret > 0); |
52 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 52 | leaf = path->nodes[0]; |
53 | item = leaf->items + path->slots[0]; | 53 | item = btrfs_item_nr(leaf, path->slots[0]); |
54 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); | 54 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); |
55 | BUG_ON(data_size > btrfs_item_size(item)); | 55 | BUG_ON(data_size > btrfs_item_size(leaf, item)); |
56 | ptr += btrfs_item_size(item) - data_size; | 56 | ptr += btrfs_item_size(leaf, item) - data_size; |
57 | return (struct btrfs_dir_item *)ptr; | 57 | return (struct btrfs_dir_item *)ptr; |
58 | } | 58 | } |
59 | 59 | ||
@@ -65,12 +65,13 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
65 | int ret2 = 0; | 65 | int ret2 = 0; |
66 | struct btrfs_path *path; | 66 | struct btrfs_path *path; |
67 | struct btrfs_dir_item *dir_item; | 67 | struct btrfs_dir_item *dir_item; |
68 | char *name_ptr; | 68 | struct extent_buffer *leaf; |
69 | unsigned long name_ptr; | ||
69 | struct btrfs_key key; | 70 | struct btrfs_key key; |
71 | struct btrfs_disk_key disk_key; | ||
70 | u32 data_size; | 72 | u32 data_size; |
71 | 73 | ||
72 | key.objectid = dir; | 74 | key.objectid = dir; |
73 | key.flags = 0; | ||
74 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 75 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
75 | ret = btrfs_name_hash(name, name_len, &key.offset); | 76 | ret = btrfs_name_hash(name, name_len, &key.offset); |
76 | BUG_ON(ret); | 77 | BUG_ON(ret); |
@@ -85,14 +86,16 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
85 | goto out; | 86 | goto out; |
86 | } | 87 | } |
87 | 88 | ||
88 | btrfs_cpu_key_to_disk(&dir_item->location, location); | 89 | leaf = path->nodes[0]; |
89 | btrfs_set_dir_type(dir_item, type); | 90 | btrfs_cpu_key_to_disk(&disk_key, location); |
90 | btrfs_set_dir_flags(dir_item, 0); | 91 | btrfs_set_dir_item_key(leaf, dir_item, &disk_key); |
91 | btrfs_set_dir_name_len(dir_item, name_len); | 92 | btrfs_set_dir_type(leaf, dir_item, type); |
92 | name_ptr = (char *)(dir_item + 1); | 93 | btrfs_set_dir_flags(leaf, dir_item, 0); |
94 | btrfs_set_dir_name_len(leaf, dir_item, name_len); | ||
95 | name_ptr = (unsigned long)(dir_item + 1); | ||
93 | 96 | ||
94 | btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); | 97 | write_extent_buffer(leaf, name, name_ptr, name_len); |
95 | btrfs_mark_buffer_dirty(path->nodes[0]); | 98 | btrfs_mark_buffer_dirty(leaf); |
96 | 99 | ||
97 | second_insert: | 100 | second_insert: |
98 | /* FIXME, use some real flag for selecting the extra index */ | 101 | /* FIXME, use some real flag for selecting the extra index */ |
@@ -110,13 +113,15 @@ second_insert: | |||
110 | ret2 = PTR_ERR(dir_item); | 113 | ret2 = PTR_ERR(dir_item); |
111 | goto out; | 114 | goto out; |
112 | } | 115 | } |
113 | btrfs_cpu_key_to_disk(&dir_item->location, location); | 116 | leaf = path->nodes[0]; |
114 | btrfs_set_dir_type(dir_item, type); | 117 | btrfs_cpu_key_to_disk(&disk_key, location); |
115 | btrfs_set_dir_flags(dir_item, 0); | 118 | btrfs_set_dir_item_key(leaf, dir_item, &disk_key); |
116 | btrfs_set_dir_name_len(dir_item, name_len); | 119 | btrfs_set_dir_type(leaf, dir_item, type); |
117 | name_ptr = (char *)(dir_item + 1); | 120 | btrfs_set_dir_flags(leaf, dir_item, 0); |
118 | btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); | 121 | btrfs_set_dir_name_len(leaf, dir_item, name_len); |
119 | btrfs_mark_buffer_dirty(path->nodes[0]); | 122 | name_ptr = (unsigned long)(dir_item + 1); |
123 | write_extent_buffer(leaf, name, name_ptr, name_len); | ||
124 | btrfs_mark_buffer_dirty(leaf); | ||
120 | out: | 125 | out: |
121 | btrfs_free_path(path); | 126 | btrfs_free_path(path); |
122 | if (ret) | 127 | if (ret) |
@@ -136,14 +141,15 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, | |||
136 | struct btrfs_key key; | 141 | struct btrfs_key key; |
137 | int ins_len = mod < 0 ? -1 : 0; | 142 | int ins_len = mod < 0 ? -1 : 0; |
138 | int cow = mod != 0; | 143 | int cow = mod != 0; |
139 | struct btrfs_disk_key *found_key; | 144 | struct btrfs_key found_key; |
140 | struct btrfs_leaf *leaf; | 145 | struct extent_buffer *leaf; |
141 | 146 | ||
142 | key.objectid = dir; | 147 | key.objectid = dir; |
143 | key.flags = 0; | ||
144 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 148 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
149 | |||
145 | ret = btrfs_name_hash(name, name_len, &key.offset); | 150 | ret = btrfs_name_hash(name, name_len, &key.offset); |
146 | BUG_ON(ret); | 151 | BUG_ON(ret); |
152 | |||
147 | ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); | 153 | ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); |
148 | if (ret < 0) | 154 | if (ret < 0) |
149 | return ERR_PTR(ret); | 155 | return ERR_PTR(ret); |
@@ -152,12 +158,13 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, | |||
152 | return NULL; | 158 | return NULL; |
153 | path->slots[0]--; | 159 | path->slots[0]--; |
154 | } | 160 | } |
155 | leaf = btrfs_buffer_leaf(path->nodes[0]); | ||
156 | found_key = &leaf->items[path->slots[0]].key; | ||
157 | 161 | ||
158 | if (btrfs_disk_key_objectid(found_key) != dir || | 162 | leaf = path->nodes[0]; |
159 | btrfs_disk_key_type(found_key) != BTRFS_DIR_ITEM_KEY || | 163 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
160 | btrfs_disk_key_offset(found_key) != key.offset) | 164 | |
165 | if (found_key.objectid != dir || | ||
166 | btrfs_key_type(&found_key) != BTRFS_DIR_ITEM_KEY || | ||
167 | found_key.offset != key.offset) | ||
161 | return NULL; | 168 | return NULL; |
162 | 169 | ||
163 | return btrfs_match_dir_item_name(root, path, name, name_len); | 170 | return btrfs_match_dir_item_name(root, path, name, name_len); |
@@ -176,7 +183,6 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, | |||
176 | int cow = mod != 0; | 183 | int cow = mod != 0; |
177 | 184 | ||
178 | key.objectid = dir; | 185 | key.objectid = dir; |
179 | key.flags = 0; | ||
180 | btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY); | 186 | btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY); |
181 | key.offset = objectid; | 187 | key.offset = objectid; |
182 | 188 | ||
@@ -193,21 +199,22 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, | |||
193 | const char *name, int name_len) | 199 | const char *name, int name_len) |
194 | { | 200 | { |
195 | struct btrfs_dir_item *dir_item; | 201 | struct btrfs_dir_item *dir_item; |
196 | char *name_ptr; | 202 | unsigned long name_ptr; |
197 | u32 total_len; | 203 | u32 total_len; |
198 | u32 cur = 0; | 204 | u32 cur = 0; |
199 | u32 this_len; | 205 | u32 this_len; |
200 | struct btrfs_leaf *leaf; | 206 | struct extent_buffer *leaf; |
201 | 207 | ||
202 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 208 | leaf = path->nodes[0]; |
203 | dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); | 209 | dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); |
204 | total_len = btrfs_item_size(leaf->items + path->slots[0]); | 210 | total_len = btrfs_item_size_nr(leaf, path->slots[0]); |
205 | while(cur < total_len) { | 211 | while(cur < total_len) { |
206 | this_len = sizeof(*dir_item) + btrfs_dir_name_len(dir_item); | 212 | this_len = sizeof(*dir_item) + |
207 | name_ptr = (char *)(dir_item + 1); | 213 | btrfs_dir_name_len(leaf, dir_item); |
214 | name_ptr = (unsigned long)(dir_item + 1); | ||
208 | 215 | ||
209 | if (btrfs_dir_name_len(dir_item) == name_len && | 216 | if (btrfs_dir_name_len(leaf, dir_item) == name_len && |
210 | memcmp(name_ptr, name, name_len) == 0) | 217 | memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) |
211 | return dir_item; | 218 | return dir_item; |
212 | 219 | ||
213 | cur += this_len; | 220 | cur += this_len; |
@@ -223,20 +230,23 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, | |||
223 | struct btrfs_dir_item *di) | 230 | struct btrfs_dir_item *di) |
224 | { | 231 | { |
225 | 232 | ||
226 | struct btrfs_leaf *leaf; | 233 | struct extent_buffer *leaf; |
227 | u32 sub_item_len; | 234 | u32 sub_item_len; |
228 | u32 item_len; | 235 | u32 item_len; |
229 | int ret = 0; | 236 | int ret = 0; |
230 | 237 | ||
231 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 238 | leaf = path->nodes[0]; |
232 | sub_item_len = sizeof(*di) + btrfs_dir_name_len(di); | 239 | sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di); |
233 | item_len = btrfs_item_size(leaf->items + path->slots[0]); | 240 | item_len = btrfs_item_size_nr(leaf, path->slots[0]); |
234 | if (sub_item_len == btrfs_item_size(leaf->items + path->slots[0])) { | 241 | if (sub_item_len == item_len) { |
235 | ret = btrfs_del_item(trans, root, path); | 242 | ret = btrfs_del_item(trans, root, path); |
236 | } else { | 243 | } else { |
237 | char *ptr = (char *)di; | 244 | /* MARKER */ |
238 | char *start = btrfs_item_ptr(leaf, path->slots[0], char); | 245 | unsigned long ptr = (unsigned long)di; |
239 | btrfs_memmove(root, leaf, ptr, ptr + sub_item_len, | 246 | unsigned long start; |
247 | |||
248 | start = btrfs_item_ptr_offset(leaf, path->slots[0]); | ||
249 | memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, | ||
240 | item_len - (ptr + sub_item_len - start)); | 250 | item_len - (ptr + sub_item_len - start)); |
241 | ret = btrfs_truncate_item(trans, root, path, | 251 | ret = btrfs_truncate_item(trans, root, path, |
242 | item_len - sub_item_len); | 252 | item_len - sub_item_len); |