diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:57:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:57:29 -0400 |
commit | dc2af6a6bcf3abdf44ac545759a6547dfe12070e (patch) | |
tree | 068ea2c5f5df55f72167ab3b51e001a98b7300e4 /fs/btrfs/root-tree.c | |
parent | 6c5daf012c9155aafd2c7973e4278766c30dfad0 (diff) | |
parent | 54bcf382daf08c1396edb8b81e650b58930ccaef (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (42 commits)
Btrfs: hash the btree inode during fill_super
Btrfs: relocate file extents in clusters
Btrfs: don't rename file into dummy directory
Btrfs: check size of inode backref before adding hardlink
Btrfs: fix releasepage to avoid unlocking extents we haven't locked
Btrfs: Fix test_range_bit for whole file extents
Btrfs: fix errors handling cached state in set/clear_extent_bit
Btrfs: fix early enospc during balancing
Btrfs: deal with NULL space info
Btrfs: account for space used by the super mirrors
Btrfs: fix extent entry threshold calculation
Btrfs: remove dead code
Btrfs: fix bitmap size tracking
Btrfs: don't keep retrying a block group if we fail to allocate a cluster
Btrfs: make balance code choose more wisely when relocating
Btrfs: fix arithmetic error in clone ioctl
Btrfs: add snapshot/subvolume destroy ioctl
Btrfs: change how subvolumes are organized
Btrfs: do not reuse objectid of deleted snapshot/subvol
Btrfs: speed up snapshot dropping
...
Diffstat (limited to 'fs/btrfs/root-tree.c')
-rw-r--r-- | fs/btrfs/root-tree.c | 138 |
1 files changed, 115 insertions, 23 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 0ddc6d61c55a..9351428f30e2 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -94,17 +94,23 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |||
94 | goto out; | 94 | goto out; |
95 | 95 | ||
96 | BUG_ON(ret == 0); | 96 | BUG_ON(ret == 0); |
97 | if (path->slots[0] == 0) { | ||
98 | ret = 1; | ||
99 | goto out; | ||
100 | } | ||
97 | l = path->nodes[0]; | 101 | l = path->nodes[0]; |
98 | BUG_ON(path->slots[0] == 0); | ||
99 | slot = path->slots[0] - 1; | 102 | slot = path->slots[0] - 1; |
100 | btrfs_item_key_to_cpu(l, &found_key, slot); | 103 | btrfs_item_key_to_cpu(l, &found_key, slot); |
101 | if (found_key.objectid != objectid) { | 104 | if (found_key.objectid != objectid || |
105 | found_key.type != BTRFS_ROOT_ITEM_KEY) { | ||
102 | ret = 1; | 106 | ret = 1; |
103 | goto out; | 107 | goto out; |
104 | } | 108 | } |
105 | read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), | 109 | if (item) |
106 | sizeof(*item)); | 110 | read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), |
107 | memcpy(key, &found_key, sizeof(found_key)); | 111 | sizeof(*item)); |
112 | if (key) | ||
113 | memcpy(key, &found_key, sizeof(found_key)); | ||
108 | ret = 0; | 114 | ret = 0; |
109 | out: | 115 | out: |
110 | btrfs_free_path(path); | 116 | btrfs_free_path(path); |
@@ -249,6 +255,59 @@ err: | |||
249 | return ret; | 255 | return ret; |
250 | } | 256 | } |
251 | 257 | ||
258 | int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | ||
259 | { | ||
260 | struct extent_buffer *leaf; | ||
261 | struct btrfs_path *path; | ||
262 | struct btrfs_key key; | ||
263 | int err = 0; | ||
264 | int ret; | ||
265 | |||
266 | path = btrfs_alloc_path(); | ||
267 | if (!path) | ||
268 | return -ENOMEM; | ||
269 | |||
270 | key.objectid = BTRFS_ORPHAN_OBJECTID; | ||
271 | key.type = BTRFS_ORPHAN_ITEM_KEY; | ||
272 | key.offset = 0; | ||
273 | |||
274 | while (1) { | ||
275 | ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); | ||
276 | if (ret < 0) { | ||
277 | err = ret; | ||
278 | break; | ||
279 | } | ||
280 | |||
281 | leaf = path->nodes[0]; | ||
282 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { | ||
283 | ret = btrfs_next_leaf(tree_root, path); | ||
284 | if (ret < 0) | ||
285 | err = ret; | ||
286 | if (ret != 0) | ||
287 | break; | ||
288 | leaf = path->nodes[0]; | ||
289 | } | ||
290 | |||
291 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
292 | btrfs_release_path(tree_root, path); | ||
293 | |||
294 | if (key.objectid != BTRFS_ORPHAN_OBJECTID || | ||
295 | key.type != BTRFS_ORPHAN_ITEM_KEY) | ||
296 | break; | ||
297 | |||
298 | ret = btrfs_find_dead_roots(tree_root, key.offset); | ||
299 | if (ret) { | ||
300 | err = ret; | ||
301 | break; | ||
302 | } | ||
303 | |||
304 | key.offset++; | ||
305 | } | ||
306 | |||
307 | btrfs_free_path(path); | ||
308 | return err; | ||
309 | } | ||
310 | |||
252 | /* drop the root item for 'key' from 'root' */ | 311 | /* drop the root item for 'key' from 'root' */ |
253 | int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 312 | int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
254 | struct btrfs_key *key) | 313 | struct btrfs_key *key) |
@@ -278,31 +337,57 @@ out: | |||
278 | return ret; | 337 | return ret; |
279 | } | 338 | } |
280 | 339 | ||
281 | #if 0 /* this will get used when snapshot deletion is implemented */ | ||
282 | int btrfs_del_root_ref(struct btrfs_trans_handle *trans, | 340 | int btrfs_del_root_ref(struct btrfs_trans_handle *trans, |
283 | struct btrfs_root *tree_root, | 341 | struct btrfs_root *tree_root, |
284 | u64 root_id, u8 type, u64 ref_id) | 342 | u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, |
343 | const char *name, int name_len) | ||
344 | |||
285 | { | 345 | { |
346 | struct btrfs_path *path; | ||
347 | struct btrfs_root_ref *ref; | ||
348 | struct extent_buffer *leaf; | ||
286 | struct btrfs_key key; | 349 | struct btrfs_key key; |
350 | unsigned long ptr; | ||
351 | int err = 0; | ||
287 | int ret; | 352 | int ret; |
288 | struct btrfs_path *path; | ||
289 | 353 | ||
290 | path = btrfs_alloc_path(); | 354 | path = btrfs_alloc_path(); |
355 | if (!path) | ||
356 | return -ENOMEM; | ||
291 | 357 | ||
292 | key.objectid = root_id; | 358 | key.objectid = root_id; |
293 | key.type = type; | 359 | key.type = BTRFS_ROOT_BACKREF_KEY; |
294 | key.offset = ref_id; | 360 | key.offset = ref_id; |
295 | 361 | again: | |
296 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); | 362 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); |
297 | BUG_ON(ret); | 363 | BUG_ON(ret < 0); |
298 | 364 | if (ret == 0) { | |
299 | ret = btrfs_del_item(trans, tree_root, path); | 365 | leaf = path->nodes[0]; |
300 | BUG_ON(ret); | 366 | ref = btrfs_item_ptr(leaf, path->slots[0], |
367 | struct btrfs_root_ref); | ||
368 | |||
369 | WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid); | ||
370 | WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len); | ||
371 | ptr = (unsigned long)(ref + 1); | ||
372 | WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len)); | ||
373 | *sequence = btrfs_root_ref_sequence(leaf, ref); | ||
374 | |||
375 | ret = btrfs_del_item(trans, tree_root, path); | ||
376 | BUG_ON(ret); | ||
377 | } else | ||
378 | err = -ENOENT; | ||
379 | |||
380 | if (key.type == BTRFS_ROOT_BACKREF_KEY) { | ||
381 | btrfs_release_path(tree_root, path); | ||
382 | key.objectid = ref_id; | ||
383 | key.type = BTRFS_ROOT_REF_KEY; | ||
384 | key.offset = root_id; | ||
385 | goto again; | ||
386 | } | ||
301 | 387 | ||
302 | btrfs_free_path(path); | 388 | btrfs_free_path(path); |
303 | return ret; | 389 | return err; |
304 | } | 390 | } |
305 | #endif | ||
306 | 391 | ||
307 | int btrfs_find_root_ref(struct btrfs_root *tree_root, | 392 | int btrfs_find_root_ref(struct btrfs_root *tree_root, |
308 | struct btrfs_path *path, | 393 | struct btrfs_path *path, |
@@ -319,7 +404,6 @@ int btrfs_find_root_ref(struct btrfs_root *tree_root, | |||
319 | return ret; | 404 | return ret; |
320 | } | 405 | } |
321 | 406 | ||
322 | |||
323 | /* | 407 | /* |
324 | * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY | 408 | * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY |
325 | * or BTRFS_ROOT_BACKREF_KEY. | 409 | * or BTRFS_ROOT_BACKREF_KEY. |
@@ -335,8 +419,7 @@ int btrfs_find_root_ref(struct btrfs_root *tree_root, | |||
335 | */ | 419 | */ |
336 | int btrfs_add_root_ref(struct btrfs_trans_handle *trans, | 420 | int btrfs_add_root_ref(struct btrfs_trans_handle *trans, |
337 | struct btrfs_root *tree_root, | 421 | struct btrfs_root *tree_root, |
338 | u64 root_id, u8 type, u64 ref_id, | 422 | u64 root_id, u64 ref_id, u64 dirid, u64 sequence, |
339 | u64 dirid, u64 sequence, | ||
340 | const char *name, int name_len) | 423 | const char *name, int name_len) |
341 | { | 424 | { |
342 | struct btrfs_key key; | 425 | struct btrfs_key key; |
@@ -346,13 +429,14 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, | |||
346 | struct extent_buffer *leaf; | 429 | struct extent_buffer *leaf; |
347 | unsigned long ptr; | 430 | unsigned long ptr; |
348 | 431 | ||
349 | |||
350 | path = btrfs_alloc_path(); | 432 | path = btrfs_alloc_path(); |
433 | if (!path) | ||
434 | return -ENOMEM; | ||
351 | 435 | ||
352 | key.objectid = root_id; | 436 | key.objectid = root_id; |
353 | key.type = type; | 437 | key.type = BTRFS_ROOT_BACKREF_KEY; |
354 | key.offset = ref_id; | 438 | key.offset = ref_id; |
355 | 439 | again: | |
356 | ret = btrfs_insert_empty_item(trans, tree_root, path, &key, | 440 | ret = btrfs_insert_empty_item(trans, tree_root, path, &key, |
357 | sizeof(*ref) + name_len); | 441 | sizeof(*ref) + name_len); |
358 | BUG_ON(ret); | 442 | BUG_ON(ret); |
@@ -366,6 +450,14 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, | |||
366 | write_extent_buffer(leaf, name, ptr, name_len); | 450 | write_extent_buffer(leaf, name, ptr, name_len); |
367 | btrfs_mark_buffer_dirty(leaf); | 451 | btrfs_mark_buffer_dirty(leaf); |
368 | 452 | ||
453 | if (key.type == BTRFS_ROOT_BACKREF_KEY) { | ||
454 | btrfs_release_path(tree_root, path); | ||
455 | key.objectid = ref_id; | ||
456 | key.type = BTRFS_ROOT_REF_KEY; | ||
457 | key.offset = root_id; | ||
458 | goto again; | ||
459 | } | ||
460 | |||
369 | btrfs_free_path(path); | 461 | btrfs_free_path(path); |
370 | return ret; | 462 | return 0; |
371 | } | 463 | } |