diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-04-02 11:20:42 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-04-02 11:20:42 -0400 |
commit | 5caf2a002901f0fde475371c4bf1c553b51884af (patch) | |
tree | 1c262f723307fe924ea4e960761354f194f3843e /fs/btrfs/super.c | |
parent | 2c90e5d658424bc71b111eb5a972240d5d06fe86 (diff) |
Btrfs: dynamic allocation of path struct
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 198 |
1 files changed, 112 insertions, 86 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 6969b672b570..c260fcad17b3 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -35,25 +35,27 @@ static int check_inode(struct inode *inode) | |||
35 | 35 | ||
36 | static void btrfs_read_locked_inode(struct inode *inode) | 36 | static void btrfs_read_locked_inode(struct inode *inode) |
37 | { | 37 | { |
38 | struct btrfs_path path; | 38 | struct btrfs_path *path; |
39 | struct btrfs_inode_item *inode_item; | 39 | struct btrfs_inode_item *inode_item; |
40 | struct btrfs_root *root = btrfs_sb(inode->i_sb); | 40 | struct btrfs_root *root = btrfs_sb(inode->i_sb); |
41 | int ret; | 41 | int ret; |
42 | 42 | ||
43 | btrfs_init_path(&path); | 43 | path = btrfs_alloc_path(); |
44 | BUG_ON(!path); | ||
45 | btrfs_init_path(path); | ||
44 | mutex_lock(&root->fs_info->fs_mutex); | 46 | mutex_lock(&root->fs_info->fs_mutex); |
45 | 47 | ||
46 | check_inode(inode); | 48 | check_inode(inode); |
47 | ret = btrfs_lookup_inode(NULL, root, &path, inode->i_ino, 0); | 49 | ret = btrfs_lookup_inode(NULL, root, path, inode->i_ino, 0); |
48 | if (ret) { | 50 | if (ret) { |
49 | btrfs_release_path(root, &path); | 51 | btrfs_release_path(root, path); |
50 | mutex_unlock(&root->fs_info->fs_mutex); | 52 | mutex_unlock(&root->fs_info->fs_mutex); |
51 | make_bad_inode(inode); | 53 | make_bad_inode(inode); |
52 | return; | 54 | return; |
53 | } | 55 | } |
54 | check_inode(inode); | 56 | check_inode(inode); |
55 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 57 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
56 | path.slots[0], | 58 | path->slots[0], |
57 | struct btrfs_inode_item); | 59 | struct btrfs_inode_item); |
58 | 60 | ||
59 | inode->i_mode = btrfs_inode_mode(inode_item); | 61 | inode->i_mode = btrfs_inode_mode(inode_item); |
@@ -69,7 +71,11 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
69 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); | 71 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); |
70 | inode->i_blocks = btrfs_inode_nblocks(inode_item); | 72 | inode->i_blocks = btrfs_inode_nblocks(inode_item); |
71 | inode->i_generation = btrfs_inode_generation(inode_item); | 73 | inode->i_generation = btrfs_inode_generation(inode_item); |
72 | btrfs_release_path(root, &path); | 74 | |
75 | btrfs_release_path(root, path); | ||
76 | btrfs_free_path(path); | ||
77 | inode_item = NULL; | ||
78 | |||
73 | mutex_unlock(&root->fs_info->fs_mutex); | 79 | mutex_unlock(&root->fs_info->fs_mutex); |
74 | check_inode(inode); | 80 | check_inode(inode); |
75 | switch (inode->i_mode & S_IFMT) { | 81 | switch (inode->i_mode & S_IFMT) { |
@@ -101,15 +107,17 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
101 | struct inode *dir, | 107 | struct inode *dir, |
102 | struct dentry *dentry) | 108 | struct dentry *dentry) |
103 | { | 109 | { |
104 | struct btrfs_path path; | 110 | struct btrfs_path *path; |
105 | const char *name = dentry->d_name.name; | 111 | const char *name = dentry->d_name.name; |
106 | int name_len = dentry->d_name.len; | 112 | int name_len = dentry->d_name.len; |
107 | int ret; | 113 | int ret; |
108 | u64 objectid; | 114 | u64 objectid; |
109 | struct btrfs_dir_item *di; | 115 | struct btrfs_dir_item *di; |
110 | 116 | ||
111 | btrfs_init_path(&path); | 117 | path = btrfs_alloc_path(); |
112 | ret = btrfs_lookup_dir_item(trans, root, &path, dir->i_ino, | 118 | BUG_ON(!path); |
119 | btrfs_init_path(path); | ||
120 | ret = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, | ||
113 | name, name_len, -1); | 121 | name, name_len, -1); |
114 | if (ret < 0) | 122 | if (ret < 0) |
115 | goto err; | 123 | goto err; |
@@ -117,15 +125,16 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
117 | ret = -ENOENT; | 125 | ret = -ENOENT; |
118 | goto err; | 126 | goto err; |
119 | } | 127 | } |
120 | di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 128 | di = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
121 | struct btrfs_dir_item); | 129 | struct btrfs_dir_item); |
122 | objectid = btrfs_dir_objectid(di); | 130 | objectid = btrfs_dir_objectid(di); |
123 | 131 | ||
124 | ret = btrfs_del_item(trans, root, &path); | 132 | ret = btrfs_del_item(trans, root, path); |
125 | BUG_ON(ret); | 133 | BUG_ON(ret); |
126 | dentry->d_inode->i_ctime = dir->i_ctime; | 134 | dentry->d_inode->i_ctime = dir->i_ctime; |
127 | err: | 135 | err: |
128 | btrfs_release_path(root, &path); | 136 | btrfs_release_path(root, path); |
137 | btrfs_free_path(path); | ||
129 | if (ret == 0) | 138 | if (ret == 0) |
130 | inode_dec_link_count(dentry->d_inode); | 139 | inode_dec_link_count(dentry->d_inode); |
131 | return ret; | 140 | return ret; |
@@ -152,30 +161,32 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
152 | int err; | 161 | int err; |
153 | int ret; | 162 | int ret; |
154 | struct btrfs_root *root = btrfs_sb(dir->i_sb); | 163 | struct btrfs_root *root = btrfs_sb(dir->i_sb); |
155 | struct btrfs_path path; | 164 | struct btrfs_path *path; |
156 | struct btrfs_key key; | 165 | struct btrfs_key key; |
157 | struct btrfs_trans_handle *trans; | 166 | struct btrfs_trans_handle *trans; |
158 | struct btrfs_disk_key *found_key; | 167 | struct btrfs_disk_key *found_key; |
159 | struct btrfs_leaf *leaf; | 168 | struct btrfs_leaf *leaf; |
160 | 169 | ||
161 | btrfs_init_path(&path); | 170 | path = btrfs_alloc_path(); |
171 | BUG_ON(!path); | ||
172 | btrfs_init_path(path); | ||
162 | mutex_lock(&root->fs_info->fs_mutex); | 173 | mutex_lock(&root->fs_info->fs_mutex); |
163 | trans = btrfs_start_transaction(root, 1); | 174 | trans = btrfs_start_transaction(root, 1); |
164 | key.objectid = inode->i_ino; | 175 | key.objectid = inode->i_ino; |
165 | key.offset = (u64)-1; | 176 | key.offset = (u64)-1; |
166 | key.flags = 0; | 177 | key.flags = 0; |
167 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 178 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
168 | ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); | 179 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
169 | if (ret < 0) { | 180 | if (ret < 0) { |
170 | err = ret; | 181 | err = ret; |
171 | goto out; | 182 | goto out; |
172 | } | 183 | } |
173 | 184 | ||
174 | BUG_ON(ret == 0); | 185 | BUG_ON(ret == 0); |
175 | BUG_ON(path.slots[0] == 0); | 186 | BUG_ON(path->slots[0] == 0); |
176 | path.slots[0]--; | 187 | path->slots[0]--; |
177 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 188 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
178 | found_key = &leaf->items[path.slots[0]].key; | 189 | found_key = &leaf->items[path->slots[0]].key; |
179 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) { | 190 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) { |
180 | err = -ENOENT; | 191 | err = -ENOENT; |
181 | goto out; | 192 | goto out; |
@@ -185,11 +196,11 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
185 | err = -ENOTEMPTY; | 196 | err = -ENOTEMPTY; |
186 | goto out; | 197 | goto out; |
187 | } | 198 | } |
188 | ret = btrfs_del_item(trans, root, &path); | 199 | ret = btrfs_del_item(trans, root, path); |
189 | BUG_ON(ret); | 200 | BUG_ON(ret); |
190 | btrfs_release_path(root, &path); | 201 | btrfs_release_path(root, path); |
191 | key.offset = 1; | 202 | key.offset = 1; |
192 | ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); | 203 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
193 | if (ret < 0) { | 204 | if (ret < 0) { |
194 | err = ret; | 205 | err = ret; |
195 | goto out; | 206 | goto out; |
@@ -198,12 +209,13 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
198 | err = -ENOTEMPTY; | 209 | err = -ENOTEMPTY; |
199 | goto out; | 210 | goto out; |
200 | } | 211 | } |
201 | ret = btrfs_del_item(trans, root, &path); | 212 | ret = btrfs_del_item(trans, root, path); |
202 | if (ret) { | 213 | if (ret) { |
203 | err = ret; | 214 | err = ret; |
204 | goto out; | 215 | goto out; |
205 | } | 216 | } |
206 | btrfs_release_path(root, &path); | 217 | btrfs_release_path(root, path); |
218 | btrfs_free_path(path); | ||
207 | 219 | ||
208 | /* now the directory is empty */ | 220 | /* now the directory is empty */ |
209 | err = btrfs_unlink_trans(trans, root, dir, dentry); | 221 | err = btrfs_unlink_trans(trans, root, dir, dentry); |
@@ -223,33 +235,36 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans, | |||
223 | struct inode *inode) | 235 | struct inode *inode) |
224 | { | 236 | { |
225 | u64 objectid = inode->i_ino; | 237 | u64 objectid = inode->i_ino; |
226 | struct btrfs_path path; | 238 | struct btrfs_path *path; |
227 | struct btrfs_inode_map_item *map; | 239 | struct btrfs_inode_map_item *map; |
228 | struct btrfs_key stat_data_key; | 240 | struct btrfs_key stat_data_key; |
229 | int ret; | 241 | int ret; |
242 | |||
230 | clear_inode(inode); | 243 | clear_inode(inode); |
231 | btrfs_init_path(&path); | 244 | |
232 | ret = btrfs_lookup_inode_map(trans, root, &path, objectid, -1); | 245 | path = btrfs_alloc_path(); |
246 | BUG_ON(!path); | ||
247 | btrfs_init_path(path); | ||
248 | ret = btrfs_lookup_inode_map(trans, root, path, objectid, -1); | ||
233 | if (ret) { | 249 | if (ret) { |
234 | if (ret > 0) | 250 | if (ret > 0) |
235 | ret = -ENOENT; | 251 | ret = -ENOENT; |
236 | btrfs_release_path(root, &path); | ||
237 | goto error; | 252 | goto error; |
238 | } | 253 | } |
239 | map = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 254 | map = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
240 | struct btrfs_inode_map_item); | 255 | struct btrfs_inode_map_item); |
241 | btrfs_disk_key_to_cpu(&stat_data_key, &map->key); | 256 | btrfs_disk_key_to_cpu(&stat_data_key, &map->key); |
242 | ret = btrfs_del_item(trans, root->fs_info->inode_root, &path); | 257 | ret = btrfs_del_item(trans, root->fs_info->inode_root, path); |
243 | BUG_ON(ret); | 258 | BUG_ON(ret); |
244 | btrfs_release_path(root, &path); | 259 | btrfs_release_path(root, path); |
245 | btrfs_init_path(&path); | ||
246 | 260 | ||
247 | ret = btrfs_lookup_inode(trans, root, &path, objectid, -1); | 261 | ret = btrfs_lookup_inode(trans, root, path, objectid, -1); |
248 | BUG_ON(ret); | 262 | BUG_ON(ret); |
249 | ret = btrfs_del_item(trans, root, &path); | 263 | ret = btrfs_del_item(trans, root, path); |
250 | BUG_ON(ret); | 264 | BUG_ON(ret); |
251 | btrfs_release_path(root, &path); | ||
252 | error: | 265 | error: |
266 | btrfs_release_path(root, path); | ||
267 | btrfs_free_path(path); | ||
253 | return ret; | 268 | return ret; |
254 | } | 269 | } |
255 | 270 | ||
@@ -258,7 +273,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
258 | struct inode *inode) | 273 | struct inode *inode) |
259 | { | 274 | { |
260 | int ret; | 275 | int ret; |
261 | struct btrfs_path path; | 276 | struct btrfs_path *path; |
262 | struct btrfs_key key; | 277 | struct btrfs_key key; |
263 | struct btrfs_disk_key *found_key; | 278 | struct btrfs_disk_key *found_key; |
264 | struct btrfs_leaf *leaf; | 279 | struct btrfs_leaf *leaf; |
@@ -267,24 +282,25 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
267 | u64 extent_num_blocks = 0; | 282 | u64 extent_num_blocks = 0; |
268 | int found_extent; | 283 | int found_extent; |
269 | 284 | ||
285 | path = btrfs_alloc_path(); | ||
286 | BUG_ON(!path); | ||
270 | /* FIXME, add redo link to tree so we don't leak on crash */ | 287 | /* FIXME, add redo link to tree so we don't leak on crash */ |
271 | key.objectid = inode->i_ino; | 288 | key.objectid = inode->i_ino; |
272 | key.offset = (u64)-1; | 289 | key.offset = (u64)-1; |
273 | key.flags = 0; | 290 | key.flags = 0; |
274 | btrfs_set_key_type(&key, BTRFS_CSUM_ITEM_KEY); | 291 | btrfs_set_key_type(&key, BTRFS_CSUM_ITEM_KEY); |
275 | while(1) { | 292 | while(1) { |
276 | btrfs_init_path(&path); | 293 | btrfs_init_path(path); |
277 | ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); | 294 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
278 | if (ret < 0) { | 295 | if (ret < 0) { |
279 | btrfs_release_path(root, &path); | ||
280 | goto error; | 296 | goto error; |
281 | } | 297 | } |
282 | if (ret > 0) { | 298 | if (ret > 0) { |
283 | BUG_ON(path.slots[0] == 0); | 299 | BUG_ON(path->slots[0] == 0); |
284 | path.slots[0]--; | 300 | path->slots[0]--; |
285 | } | 301 | } |
286 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 302 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
287 | found_key = &leaf->items[path.slots[0]].key; | 303 | found_key = &leaf->items[path->slots[0]].key; |
288 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) | 304 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) |
289 | break; | 305 | break; |
290 | if (btrfs_disk_key_type(found_key) != BTRFS_CSUM_ITEM_KEY && | 306 | if (btrfs_disk_key_type(found_key) != BTRFS_CSUM_ITEM_KEY && |
@@ -293,8 +309,8 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
293 | if (btrfs_disk_key_offset(found_key) < inode->i_size) | 309 | if (btrfs_disk_key_offset(found_key) < inode->i_size) |
294 | break; | 310 | break; |
295 | if (btrfs_disk_key_type(found_key) == BTRFS_EXTENT_DATA_KEY) { | 311 | if (btrfs_disk_key_type(found_key) == BTRFS_EXTENT_DATA_KEY) { |
296 | fi = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 312 | fi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
297 | path.slots[0], | 313 | path->slots[0], |
298 | struct btrfs_file_extent_item); | 314 | struct btrfs_file_extent_item); |
299 | extent_start = btrfs_file_extent_disk_blocknr(fi); | 315 | extent_start = btrfs_file_extent_disk_blocknr(fi); |
300 | extent_num_blocks = | 316 | extent_num_blocks = |
@@ -305,18 +321,19 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
305 | } else { | 321 | } else { |
306 | found_extent = 0; | 322 | found_extent = 0; |
307 | } | 323 | } |
308 | ret = btrfs_del_item(trans, root, &path); | 324 | ret = btrfs_del_item(trans, root, path); |
309 | BUG_ON(ret); | 325 | BUG_ON(ret); |
310 | btrfs_release_path(root, &path); | 326 | btrfs_release_path(root, path); |
311 | if (found_extent) { | 327 | if (found_extent) { |
312 | ret = btrfs_free_extent(trans, root, extent_start, | 328 | ret = btrfs_free_extent(trans, root, extent_start, |
313 | extent_num_blocks, 0); | 329 | extent_num_blocks, 0); |
314 | BUG_ON(ret); | 330 | BUG_ON(ret); |
315 | } | 331 | } |
316 | } | 332 | } |
317 | btrfs_release_path(root, &path); | ||
318 | ret = 0; | 333 | ret = 0; |
319 | error: | 334 | error: |
335 | btrfs_release_path(root, path); | ||
336 | btrfs_free_path(path); | ||
320 | return ret; | 337 | return ret; |
321 | } | 338 | } |
322 | 339 | ||
@@ -351,23 +368,26 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, | |||
351 | const char *name = dentry->d_name.name; | 368 | const char *name = dentry->d_name.name; |
352 | int namelen = dentry->d_name.len; | 369 | int namelen = dentry->d_name.len; |
353 | struct btrfs_dir_item *di; | 370 | struct btrfs_dir_item *di; |
354 | struct btrfs_path path; | 371 | struct btrfs_path *path; |
355 | struct btrfs_root *root = btrfs_sb(dir->i_sb); | 372 | struct btrfs_root *root = btrfs_sb(dir->i_sb); |
356 | int ret; | 373 | int ret; |
357 | 374 | ||
358 | btrfs_init_path(&path); | 375 | path = btrfs_alloc_path(); |
359 | ret = btrfs_lookup_dir_item(NULL, root, &path, dir->i_ino, name, | 376 | BUG_ON(!path); |
377 | btrfs_init_path(path); | ||
378 | ret = btrfs_lookup_dir_item(NULL, root, path, dir->i_ino, name, | ||
360 | namelen, 0); | 379 | namelen, 0); |
361 | if (ret || !btrfs_match_dir_item_name(root, &path, name, namelen)) { | 380 | if (ret || !btrfs_match_dir_item_name(root, path, name, namelen)) { |
362 | *ino = 0; | 381 | *ino = 0; |
363 | ret = 0; | 382 | ret = 0; |
364 | goto out; | 383 | goto out; |
365 | } | 384 | } |
366 | di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 385 | di = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
367 | struct btrfs_dir_item); | 386 | struct btrfs_dir_item); |
368 | *ino = btrfs_dir_objectid(di); | 387 | *ino = btrfs_dir_objectid(di); |
369 | out: | 388 | out: |
370 | btrfs_release_path(root, &path); | 389 | btrfs_release_path(root, path); |
390 | btrfs_free_path(path); | ||
371 | check_inode(dir); | 391 | check_inode(dir); |
372 | return ret; | 392 | return ret; |
373 | } | 393 | } |
@@ -405,7 +425,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
405 | struct btrfs_item *item; | 425 | struct btrfs_item *item; |
406 | struct btrfs_dir_item *di; | 426 | struct btrfs_dir_item *di; |
407 | struct btrfs_key key; | 427 | struct btrfs_key key; |
408 | struct btrfs_path path; | 428 | struct btrfs_path *path; |
409 | int ret; | 429 | int ret; |
410 | u32 nritems; | 430 | u32 nritems; |
411 | struct btrfs_leaf *leaf; | 431 | struct btrfs_leaf *leaf; |
@@ -419,27 +439,28 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
419 | key.flags = 0; | 439 | key.flags = 0; |
420 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 440 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
421 | key.offset = filp->f_pos; | 441 | key.offset = filp->f_pos; |
422 | btrfs_init_path(&path); | 442 | path = btrfs_alloc_path(); |
423 | ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); | 443 | btrfs_init_path(path); |
444 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
424 | if (ret < 0) { | 445 | if (ret < 0) { |
425 | goto err; | 446 | goto err; |
426 | } | 447 | } |
427 | advance = 0; | 448 | advance = 0; |
428 | while(1) { | 449 | while(1) { |
429 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 450 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
430 | nritems = btrfs_header_nritems(&leaf->header); | 451 | nritems = btrfs_header_nritems(&leaf->header); |
431 | slot = path.slots[0]; | 452 | slot = path->slots[0]; |
432 | if (advance || slot >= nritems) { | 453 | if (advance || slot >= nritems) { |
433 | if (slot >= nritems -1) { | 454 | if (slot >= nritems -1) { |
434 | ret = btrfs_next_leaf(root, &path); | 455 | ret = btrfs_next_leaf(root, path); |
435 | if (ret) | 456 | if (ret) |
436 | break; | 457 | break; |
437 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 458 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
438 | nritems = btrfs_header_nritems(&leaf->header); | 459 | nritems = btrfs_header_nritems(&leaf->header); |
439 | slot = path.slots[0]; | 460 | slot = path->slots[0]; |
440 | } else { | 461 | } else { |
441 | slot++; | 462 | slot++; |
442 | path.slots[0]++; | 463 | path->slots[0]++; |
443 | } | 464 | } |
444 | } | 465 | } |
445 | advance = 1; | 466 | advance = 1; |
@@ -465,7 +486,8 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
465 | } | 486 | } |
466 | ret = 0; | 487 | ret = 0; |
467 | err: | 488 | err: |
468 | btrfs_release_path(root, &path); | 489 | btrfs_release_path(root, path); |
490 | btrfs_free_path(path); | ||
469 | mutex_unlock(&root->fs_info->fs_mutex); | 491 | mutex_unlock(&root->fs_info->fs_mutex); |
470 | return ret; | 492 | return ret; |
471 | } | 493 | } |
@@ -548,26 +570,29 @@ static int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
548 | struct inode *inode) | 570 | struct inode *inode) |
549 | { | 571 | { |
550 | struct btrfs_inode_item *inode_item; | 572 | struct btrfs_inode_item *inode_item; |
551 | struct btrfs_path path; | 573 | struct btrfs_path *path; |
552 | int ret; | 574 | int ret; |
553 | 575 | ||
554 | btrfs_init_path(&path); | 576 | path = btrfs_alloc_path(); |
577 | BUG_ON(!path); | ||
578 | btrfs_init_path(path); | ||
555 | 579 | ||
556 | ret = btrfs_lookup_inode(trans, root, &path, inode->i_ino, 1); | 580 | ret = btrfs_lookup_inode(trans, root, path, inode->i_ino, 1); |
557 | if (ret) { | 581 | if (ret) { |
558 | if (ret > 0) | 582 | if (ret > 0) |
559 | ret = -ENOENT; | 583 | ret = -ENOENT; |
560 | goto failed; | 584 | goto failed; |
561 | } | 585 | } |
562 | 586 | ||
563 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 587 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
564 | path.slots[0], | 588 | path->slots[0], |
565 | struct btrfs_inode_item); | 589 | struct btrfs_inode_item); |
566 | 590 | ||
567 | fill_inode_item(inode_item, inode); | 591 | fill_inode_item(inode_item, inode); |
568 | btrfs_mark_buffer_dirty(path.nodes[0]); | 592 | btrfs_mark_buffer_dirty(path->nodes[0]); |
569 | failed: | 593 | failed: |
570 | btrfs_release_path(root, &path); | 594 | btrfs_release_path(root, path); |
595 | btrfs_free_path(path); | ||
571 | check_inode(inode); | 596 | check_inode(inode); |
572 | return 0; | 597 | return 0; |
573 | } | 598 | } |
@@ -799,38 +824,39 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, | |||
799 | u64 extent_start = 0; | 824 | u64 extent_start = 0; |
800 | u64 extent_end = 0; | 825 | u64 extent_end = 0; |
801 | u64 objectid = inode->i_ino; | 826 | u64 objectid = inode->i_ino; |
802 | struct btrfs_path path; | 827 | struct btrfs_path *path; |
803 | struct btrfs_root *root = btrfs_sb(inode->i_sb); | 828 | struct btrfs_root *root = btrfs_sb(inode->i_sb); |
804 | struct btrfs_trans_handle *trans = NULL; | 829 | struct btrfs_trans_handle *trans = NULL; |
805 | struct btrfs_file_extent_item *item; | 830 | struct btrfs_file_extent_item *item; |
806 | struct btrfs_leaf *leaf; | 831 | struct btrfs_leaf *leaf; |
807 | struct btrfs_disk_key *found_key; | 832 | struct btrfs_disk_key *found_key; |
808 | 833 | ||
809 | btrfs_init_path(&path); | 834 | path = btrfs_alloc_path(); |
835 | BUG_ON(!path); | ||
836 | btrfs_init_path(path); | ||
810 | if (create) | 837 | if (create) |
811 | trans = btrfs_start_transaction(root, 1); | 838 | trans = btrfs_start_transaction(root, 1); |
812 | 839 | ||
813 | 840 | ||
814 | ret = btrfs_lookup_file_extent(trans, root, &path, | 841 | ret = btrfs_lookup_file_extent(trans, root, path, |
815 | inode->i_ino, | 842 | inode->i_ino, |
816 | iblock << inode->i_blkbits, 0); | 843 | iblock << inode->i_blkbits, 0); |
817 | if (ret < 0) { | 844 | if (ret < 0) { |
818 | btrfs_release_path(root, &path); | ||
819 | err = ret; | 845 | err = ret; |
820 | goto out; | 846 | goto out; |
821 | } | 847 | } |
822 | 848 | ||
823 | if (ret != 0) { | 849 | if (ret != 0) { |
824 | if (path.slots[0] == 0) { | 850 | if (path->slots[0] == 0) { |
825 | btrfs_release_path(root, &path); | 851 | btrfs_release_path(root, path); |
826 | goto allocate; | 852 | goto allocate; |
827 | } | 853 | } |
828 | path.slots[0]--; | 854 | path->slots[0]--; |
829 | } | 855 | } |
830 | 856 | ||
831 | item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 857 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
832 | struct btrfs_file_extent_item); | 858 | struct btrfs_file_extent_item); |
833 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 859 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
834 | blocknr = btrfs_file_extent_disk_blocknr(item); | 860 | blocknr = btrfs_file_extent_disk_blocknr(item); |
835 | blocknr += btrfs_file_extent_offset(item); | 861 | blocknr += btrfs_file_extent_offset(item); |
836 | 862 | ||
@@ -838,25 +864,23 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, | |||
838 | if (ret == 0) { | 864 | if (ret == 0) { |
839 | err = 0; | 865 | err = 0; |
840 | map_bh(result, inode->i_sb, blocknr); | 866 | map_bh(result, inode->i_sb, blocknr); |
841 | btrfs_release_path(root, &path); | ||
842 | goto out; | 867 | goto out; |
843 | } | 868 | } |
844 | 869 | ||
845 | /* are we inside the extent that was found? */ | 870 | /* are we inside the extent that was found? */ |
846 | found_key = &leaf->items[path.slots[0]].key; | 871 | found_key = &leaf->items[path->slots[0]].key; |
847 | if (btrfs_disk_key_objectid(found_key) != objectid || | 872 | if (btrfs_disk_key_objectid(found_key) != objectid || |
848 | btrfs_disk_key_type(found_key) != BTRFS_EXTENT_DATA_KEY) { | 873 | btrfs_disk_key_type(found_key) != BTRFS_EXTENT_DATA_KEY) { |
849 | extent_end = 0; | 874 | extent_end = 0; |
850 | extent_start = 0; | 875 | extent_start = 0; |
851 | btrfs_release_path(root, &path); | 876 | btrfs_release_path(root, path); |
852 | goto allocate; | 877 | goto allocate; |
853 | } | 878 | } |
854 | 879 | ||
855 | extent_start = btrfs_disk_key_offset(&leaf->items[path.slots[0]].key); | 880 | extent_start = btrfs_disk_key_offset(&leaf->items[path->slots[0]].key); |
856 | extent_start = extent_start >> inode->i_blkbits; | 881 | extent_start = extent_start >> inode->i_blkbits; |
857 | extent_start += btrfs_file_extent_offset(item); | 882 | extent_start += btrfs_file_extent_offset(item); |
858 | extent_end = extent_start + btrfs_file_extent_num_blocks(item); | 883 | extent_end = extent_start + btrfs_file_extent_num_blocks(item); |
859 | btrfs_release_path(root, &path); | ||
860 | if (iblock >= extent_start && iblock < extent_end) { | 884 | if (iblock >= extent_start && iblock < extent_end) { |
861 | err = 0; | 885 | err = 0; |
862 | map_bh(result, inode->i_sb, blocknr + iblock - extent_start); | 886 | map_bh(result, inode->i_sb, blocknr + iblock - extent_start); |
@@ -880,6 +904,8 @@ allocate: | |||
880 | map_bh(result, inode->i_sb, blocknr); | 904 | map_bh(result, inode->i_sb, blocknr); |
881 | 905 | ||
882 | out: | 906 | out: |
907 | btrfs_release_path(root, path); | ||
908 | btrfs_free_path(path); | ||
883 | if (trans) | 909 | if (trans) |
884 | btrfs_end_transaction(trans, root); | 910 | btrfs_end_transaction(trans, root); |
885 | return err; | 911 | return err; |