diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2013-05-15 03:48:19 -0400 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-06-14 11:29:37 -0400 |
commit | cb517eabba4f109810dba2e5f37b0dcf22103065 (patch) | |
tree | 5c553813bf6fdc41df3912a1146828cba64d3b17 /fs/btrfs/root-tree.c | |
parent | babbf170c781f24095336c82ebf18ad272ddb773 (diff) |
Btrfs: cleanup the similar code of the fs root read
There are several functions whose code is similar, such as
btrfs_find_last_root()
btrfs_read_fs_root_no_radix()
Besides that, some functions are invoked twice, it is unnecessary,
for example, we are sure that all roots which is found in
btrfs_find_orphan_roots()
have their orphan items, so it is unnecessary to check the orphan
item again.
So cleanup it.
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/root-tree.c')
-rw-r--r-- | fs/btrfs/root-tree.c | 170 |
1 files changed, 53 insertions, 117 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 5bf1ed57f178..79e683273de5 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -64,52 +64,59 @@ void btrfs_read_root_item(struct extent_buffer *eb, int slot, | |||
64 | } | 64 | } |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * lookup the root with the highest offset for a given objectid. The key we do | 67 | * btrfs_find_root - lookup the root by the key. |
68 | * find is copied into 'key'. If we find something return 0, otherwise 1, < 0 | 68 | * root: the root of the root tree |
69 | * on error. | 69 | * search_key: the key to search |
70 | * path: the path we search | ||
71 | * root_item: the root item of the tree we look for | ||
72 | * root_key: the reak key of the tree we look for | ||
73 | * | ||
74 | * If ->offset of 'seach_key' is -1ULL, it means we are not sure the offset | ||
75 | * of the search key, just lookup the root with the highest offset for a | ||
76 | * given objectid. | ||
77 | * | ||
78 | * If we find something return 0, otherwise > 0, < 0 on error. | ||
70 | */ | 79 | */ |
71 | int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | 80 | int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key, |
72 | struct btrfs_root_item *item, struct btrfs_key *key) | 81 | struct btrfs_path *path, struct btrfs_root_item *root_item, |
82 | struct btrfs_key *root_key) | ||
73 | { | 83 | { |
74 | struct btrfs_path *path; | ||
75 | struct btrfs_key search_key; | ||
76 | struct btrfs_key found_key; | 84 | struct btrfs_key found_key; |
77 | struct extent_buffer *l; | 85 | struct extent_buffer *l; |
78 | int ret; | 86 | int ret; |
79 | int slot; | 87 | int slot; |
80 | 88 | ||
81 | search_key.objectid = objectid; | 89 | ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0); |
82 | search_key.type = BTRFS_ROOT_ITEM_KEY; | ||
83 | search_key.offset = (u64)-1; | ||
84 | |||
85 | path = btrfs_alloc_path(); | ||
86 | if (!path) | ||
87 | return -ENOMEM; | ||
88 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | ||
89 | if (ret < 0) | 90 | if (ret < 0) |
90 | goto out; | 91 | return ret; |
91 | 92 | ||
92 | BUG_ON(ret == 0); | 93 | if (search_key->offset != -1ULL) { /* the search key is exact */ |
93 | if (path->slots[0] == 0) { | 94 | if (ret > 0) |
94 | ret = 1; | 95 | goto out; |
95 | goto out; | 96 | } else { |
97 | BUG_ON(ret == 0); /* Logical error */ | ||
98 | if (path->slots[0] == 0) | ||
99 | goto out; | ||
100 | path->slots[0]--; | ||
101 | ret = 0; | ||
96 | } | 102 | } |
103 | |||
97 | l = path->nodes[0]; | 104 | l = path->nodes[0]; |
98 | slot = path->slots[0] - 1; | 105 | slot = path->slots[0]; |
106 | |||
99 | btrfs_item_key_to_cpu(l, &found_key, slot); | 107 | btrfs_item_key_to_cpu(l, &found_key, slot); |
100 | if (found_key.objectid != objectid || | 108 | if (found_key.objectid != search_key->objectid || |
101 | found_key.type != BTRFS_ROOT_ITEM_KEY) { | 109 | found_key.type != BTRFS_ROOT_ITEM_KEY) { |
102 | ret = 1; | 110 | ret = 1; |
103 | goto out; | 111 | goto out; |
104 | } | 112 | } |
105 | if (item) | ||
106 | btrfs_read_root_item(l, slot, item); | ||
107 | if (key) | ||
108 | memcpy(key, &found_key, sizeof(found_key)); | ||
109 | 113 | ||
110 | ret = 0; | 114 | if (root_item) |
115 | btrfs_read_root_item(l, slot, root_item); | ||
116 | if (root_key) | ||
117 | memcpy(root_key, &found_key, sizeof(found_key)); | ||
111 | out: | 118 | out: |
112 | btrfs_free_path(path); | 119 | btrfs_release_path(path); |
113 | return ret; | 120 | return ret; |
114 | } | 121 | } |
115 | 122 | ||
@@ -212,86 +219,6 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
212 | return btrfs_insert_item(trans, root, key, item, sizeof(*item)); | 219 | return btrfs_insert_item(trans, root, key, item, sizeof(*item)); |
213 | } | 220 | } |
214 | 221 | ||
215 | /* | ||
216 | * at mount time we want to find all the old transaction snapshots that were in | ||
217 | * the process of being deleted if we crashed. This is any root item with an | ||
218 | * offset lower than the latest root. They need to be queued for deletion to | ||
219 | * finish what was happening when we crashed. | ||
220 | */ | ||
221 | int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid) | ||
222 | { | ||
223 | struct btrfs_root *dead_root; | ||
224 | struct btrfs_root_item *ri; | ||
225 | struct btrfs_key key; | ||
226 | struct btrfs_key found_key; | ||
227 | struct btrfs_path *path; | ||
228 | int ret; | ||
229 | u32 nritems; | ||
230 | struct extent_buffer *leaf; | ||
231 | int slot; | ||
232 | |||
233 | key.objectid = objectid; | ||
234 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | ||
235 | key.offset = 0; | ||
236 | path = btrfs_alloc_path(); | ||
237 | if (!path) | ||
238 | return -ENOMEM; | ||
239 | |||
240 | again: | ||
241 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
242 | if (ret < 0) | ||
243 | goto err; | ||
244 | while (1) { | ||
245 | leaf = path->nodes[0]; | ||
246 | nritems = btrfs_header_nritems(leaf); | ||
247 | slot = path->slots[0]; | ||
248 | if (slot >= nritems) { | ||
249 | ret = btrfs_next_leaf(root, path); | ||
250 | if (ret) | ||
251 | break; | ||
252 | leaf = path->nodes[0]; | ||
253 | nritems = btrfs_header_nritems(leaf); | ||
254 | slot = path->slots[0]; | ||
255 | } | ||
256 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
257 | if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY) | ||
258 | goto next; | ||
259 | |||
260 | if (key.objectid < objectid) | ||
261 | goto next; | ||
262 | |||
263 | if (key.objectid > objectid) | ||
264 | break; | ||
265 | |||
266 | ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item); | ||
267 | if (btrfs_disk_root_refs(leaf, ri) != 0) | ||
268 | goto next; | ||
269 | |||
270 | memcpy(&found_key, &key, sizeof(key)); | ||
271 | key.offset++; | ||
272 | btrfs_release_path(path); | ||
273 | dead_root = | ||
274 | btrfs_read_fs_root_no_radix(root->fs_info->tree_root, | ||
275 | &found_key); | ||
276 | if (IS_ERR(dead_root)) { | ||
277 | ret = PTR_ERR(dead_root); | ||
278 | goto err; | ||
279 | } | ||
280 | |||
281 | ret = btrfs_add_dead_root(dead_root); | ||
282 | if (ret) | ||
283 | goto err; | ||
284 | goto again; | ||
285 | next: | ||
286 | slot++; | ||
287 | path->slots[0]++; | ||
288 | } | ||
289 | ret = 0; | ||
290 | err: | ||
291 | btrfs_free_path(path); | ||
292 | return ret; | ||
293 | } | ||
294 | |||
295 | int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | 222 | int btrfs_find_orphan_roots(struct btrfs_root *tree_root) |
296 | { | 223 | { |
297 | struct extent_buffer *leaf; | 224 | struct extent_buffer *leaf; |
@@ -340,20 +267,29 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | |||
340 | root_key.objectid = key.offset; | 267 | root_key.objectid = key.offset; |
341 | key.offset++; | 268 | key.offset++; |
342 | 269 | ||
343 | root = btrfs_read_fs_root_no_name(tree_root->fs_info, | 270 | root = btrfs_read_fs_root(tree_root, &root_key); |
344 | &root_key); | 271 | if (IS_ERR(root)) { |
345 | if (!IS_ERR(root)) | 272 | err = PTR_ERR(root); |
273 | break; | ||
274 | } | ||
275 | |||
276 | if (btrfs_root_refs(&root->root_item) == 0) { | ||
277 | btrfs_add_dead_root(root); | ||
346 | continue; | 278 | continue; |
279 | } | ||
347 | 280 | ||
348 | ret = PTR_ERR(root); | 281 | err = btrfs_init_fs_root(root); |
349 | if (ret != -ENOENT) { | 282 | if (err) { |
350 | err = ret; | 283 | btrfs_free_fs_root(root); |
351 | break; | 284 | break; |
352 | } | 285 | } |
353 | 286 | ||
354 | ret = btrfs_find_dead_roots(tree_root, root_key.objectid); | 287 | root->orphan_item_inserted = 1; |
355 | if (ret) { | 288 | |
356 | err = ret; | 289 | err = btrfs_insert_fs_root(root->fs_info, root); |
290 | if (err) { | ||
291 | BUG_ON(err == -EEXIST); | ||
292 | btrfs_free_fs_root(root); | ||
357 | break; | 293 | break; |
358 | } | 294 | } |
359 | } | 295 | } |