diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/btrfs/root-tree.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/btrfs/root-tree.c')
-rw-r--r-- | fs/btrfs/root-tree.c | 87 |
1 files changed, 31 insertions, 56 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 2d958be761c8..ebe45443de06 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -22,53 +22,6 @@ | |||
22 | #include "print-tree.h" | 22 | #include "print-tree.h" |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * search forward for a root, starting with objectid 'search_start' | ||
26 | * if a root key is found, the objectid we find is filled into 'found_objectid' | ||
27 | * and 0 is returned. < 0 is returned on error, 1 if there is nothing | ||
28 | * left in the tree. | ||
29 | */ | ||
30 | int btrfs_search_root(struct btrfs_root *root, u64 search_start, | ||
31 | u64 *found_objectid) | ||
32 | { | ||
33 | struct btrfs_path *path; | ||
34 | struct btrfs_key search_key; | ||
35 | int ret; | ||
36 | |||
37 | root = root->fs_info->tree_root; | ||
38 | search_key.objectid = search_start; | ||
39 | search_key.type = (u8)-1; | ||
40 | search_key.offset = (u64)-1; | ||
41 | |||
42 | path = btrfs_alloc_path(); | ||
43 | BUG_ON(!path); | ||
44 | again: | ||
45 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | ||
46 | if (ret < 0) | ||
47 | goto out; | ||
48 | if (ret == 0) { | ||
49 | ret = 1; | ||
50 | goto out; | ||
51 | } | ||
52 | if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { | ||
53 | ret = btrfs_next_leaf(root, path); | ||
54 | if (ret) | ||
55 | goto out; | ||
56 | } | ||
57 | btrfs_item_key_to_cpu(path->nodes[0], &search_key, path->slots[0]); | ||
58 | if (search_key.type != BTRFS_ROOT_ITEM_KEY) { | ||
59 | search_key.offset++; | ||
60 | btrfs_release_path(root, path); | ||
61 | goto again; | ||
62 | } | ||
63 | ret = 0; | ||
64 | *found_objectid = search_key.objectid; | ||
65 | |||
66 | out: | ||
67 | btrfs_free_path(path); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * lookup the root with the highest offset for a given objectid. The key we do | 25 | * lookup the root with the highest offset for a given objectid. The key we do |
73 | * find is copied into 'key'. If we find something return 0, otherwise 1, < 0 | 26 | * find is copied into 'key'. If we find something return 0, otherwise 1, < 0 |
74 | * on error. | 27 | * on error. |
@@ -88,7 +41,8 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |||
88 | search_key.offset = (u64)-1; | 41 | search_key.offset = (u64)-1; |
89 | 42 | ||
90 | path = btrfs_alloc_path(); | 43 | path = btrfs_alloc_path(); |
91 | BUG_ON(!path); | 44 | if (!path) |
45 | return -ENOMEM; | ||
92 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | 46 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); |
93 | if (ret < 0) | 47 | if (ret < 0) |
94 | goto out; | 48 | goto out; |
@@ -181,7 +135,6 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
181 | int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid) | 135 | int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid) |
182 | { | 136 | { |
183 | struct btrfs_root *dead_root; | 137 | struct btrfs_root *dead_root; |
184 | struct btrfs_item *item; | ||
185 | struct btrfs_root_item *ri; | 138 | struct btrfs_root_item *ri; |
186 | struct btrfs_key key; | 139 | struct btrfs_key key; |
187 | struct btrfs_key found_key; | 140 | struct btrfs_key found_key; |
@@ -214,7 +167,6 @@ again: | |||
214 | nritems = btrfs_header_nritems(leaf); | 167 | nritems = btrfs_header_nritems(leaf); |
215 | slot = path->slots[0]; | 168 | slot = path->slots[0]; |
216 | } | 169 | } |
217 | item = btrfs_item_nr(leaf, slot); | ||
218 | btrfs_item_key_to_cpu(leaf, &key, slot); | 170 | btrfs_item_key_to_cpu(leaf, &key, slot); |
219 | if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY) | 171 | if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY) |
220 | goto next; | 172 | goto next; |
@@ -231,7 +183,7 @@ again: | |||
231 | 183 | ||
232 | memcpy(&found_key, &key, sizeof(key)); | 184 | memcpy(&found_key, &key, sizeof(key)); |
233 | key.offset++; | 185 | key.offset++; |
234 | btrfs_release_path(root, path); | 186 | btrfs_release_path(path); |
235 | dead_root = | 187 | dead_root = |
236 | btrfs_read_fs_root_no_radix(root->fs_info->tree_root, | 188 | btrfs_read_fs_root_no_radix(root->fs_info->tree_root, |
237 | &found_key); | 189 | &found_key); |
@@ -293,7 +245,7 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | |||
293 | } | 245 | } |
294 | 246 | ||
295 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | 247 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); |
296 | btrfs_release_path(tree_root, path); | 248 | btrfs_release_path(path); |
297 | 249 | ||
298 | if (key.objectid != BTRFS_ORPHAN_OBJECTID || | 250 | if (key.objectid != BTRFS_ORPHAN_OBJECTID || |
299 | key.type != BTRFS_ORPHAN_ITEM_KEY) | 251 | key.type != BTRFS_ORPHAN_ITEM_KEY) |
@@ -334,7 +286,8 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
334 | struct extent_buffer *leaf; | 286 | struct extent_buffer *leaf; |
335 | 287 | ||
336 | path = btrfs_alloc_path(); | 288 | path = btrfs_alloc_path(); |
337 | BUG_ON(!path); | 289 | if (!path) |
290 | return -ENOMEM; | ||
338 | ret = btrfs_search_slot(trans, root, key, path, -1, 1); | 291 | ret = btrfs_search_slot(trans, root, key, path, -1, 1); |
339 | if (ret < 0) | 292 | if (ret < 0) |
340 | goto out; | 293 | goto out; |
@@ -385,18 +338,22 @@ again: | |||
385 | *sequence = btrfs_root_ref_sequence(leaf, ref); | 338 | *sequence = btrfs_root_ref_sequence(leaf, ref); |
386 | 339 | ||
387 | ret = btrfs_del_item(trans, tree_root, path); | 340 | ret = btrfs_del_item(trans, tree_root, path); |
388 | BUG_ON(ret); | 341 | if (ret) { |
342 | err = ret; | ||
343 | goto out; | ||
344 | } | ||
389 | } else | 345 | } else |
390 | err = -ENOENT; | 346 | err = -ENOENT; |
391 | 347 | ||
392 | if (key.type == BTRFS_ROOT_BACKREF_KEY) { | 348 | if (key.type == BTRFS_ROOT_BACKREF_KEY) { |
393 | btrfs_release_path(tree_root, path); | 349 | btrfs_release_path(path); |
394 | key.objectid = ref_id; | 350 | key.objectid = ref_id; |
395 | key.type = BTRFS_ROOT_REF_KEY; | 351 | key.type = BTRFS_ROOT_REF_KEY; |
396 | key.offset = root_id; | 352 | key.offset = root_id; |
397 | goto again; | 353 | goto again; |
398 | } | 354 | } |
399 | 355 | ||
356 | out: | ||
400 | btrfs_free_path(path); | 357 | btrfs_free_path(path); |
401 | return err; | 358 | return err; |
402 | } | 359 | } |
@@ -463,7 +420,7 @@ again: | |||
463 | btrfs_mark_buffer_dirty(leaf); | 420 | btrfs_mark_buffer_dirty(leaf); |
464 | 421 | ||
465 | if (key.type == BTRFS_ROOT_BACKREF_KEY) { | 422 | if (key.type == BTRFS_ROOT_BACKREF_KEY) { |
466 | btrfs_release_path(tree_root, path); | 423 | btrfs_release_path(path); |
467 | key.objectid = ref_id; | 424 | key.objectid = ref_id; |
468 | key.type = BTRFS_ROOT_REF_KEY; | 425 | key.type = BTRFS_ROOT_REF_KEY; |
469 | key.offset = root_id; | 426 | key.offset = root_id; |
@@ -473,3 +430,21 @@ again: | |||
473 | btrfs_free_path(path); | 430 | btrfs_free_path(path); |
474 | return 0; | 431 | return 0; |
475 | } | 432 | } |
433 | |||
434 | /* | ||
435 | * Old btrfs forgets to init root_item->flags and root_item->byte_limit | ||
436 | * for subvolumes. To work around this problem, we steal a bit from | ||
437 | * root_item->inode_item->flags, and use it to indicate if those fields | ||
438 | * have been properly initialized. | ||
439 | */ | ||
440 | void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item) | ||
441 | { | ||
442 | u64 inode_flags = le64_to_cpu(root_item->inode.flags); | ||
443 | |||
444 | if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) { | ||
445 | inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT; | ||
446 | root_item->inode.flags = cpu_to_le64(inode_flags); | ||
447 | root_item->flags = 0; | ||
448 | root_item->byte_limit = 0; | ||
449 | } | ||
450 | } | ||