diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-02 16:08:05 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-02 16:08:05 -0500 |
commit | 02217ed299c6340a35696e0610047eb96826de2d (patch) | |
tree | 4a92c16ce2a51f701c829d96f644486fb7b29517 /fs/btrfs/extent-tree.c | |
parent | 77ce6846c40e83193df01295e5af437f8b6c7a2d (diff) |
Btrfs: early reference counting
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index fb2144496215..25d9cd169209 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -15,6 +15,39 @@ | |||
15 | */ | 15 | */ |
16 | #define CTREE_EXTENT_PENDING 0 | 16 | #define CTREE_EXTENT_PENDING 0 |
17 | 17 | ||
18 | static int inc_block_ref(struct ctree_root *root, u64 blocknr) | ||
19 | { | ||
20 | struct ctree_path path; | ||
21 | int ret; | ||
22 | struct key key; | ||
23 | struct leaf *l; | ||
24 | struct extent_item *item; | ||
25 | init_path(&path); | ||
26 | key.objectid = blocknr; | ||
27 | key.flags = 0; | ||
28 | key.offset = 1; | ||
29 | ret = search_slot(root->extent_root, &key, &path, 0, 1); | ||
30 | BUG_ON(ret != 0); | ||
31 | l = &path.nodes[0]->leaf; | ||
32 | item = (struct extent_item *)(l->data + | ||
33 | l->items[path.slots[0]].offset); | ||
34 | item->refs++; | ||
35 | BUG_ON(list_empty(&path.nodes[0]->dirty)); | ||
36 | release_path(root->extent_root, &path); | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf) | ||
41 | { | ||
42 | u64 blocknr; | ||
43 | int i; | ||
44 | for (i = 0; i < buf->node.header.nritems; i++) { | ||
45 | blocknr = buf->node.blockptrs[i]; | ||
46 | inc_block_ref(root, blocknr); | ||
47 | } | ||
48 | return 0; | ||
49 | } | ||
50 | |||
18 | /* | 51 | /* |
19 | * find all the blocks marked as pending in the radix tree and remove | 52 | * find all the blocks marked as pending in the radix tree and remove |
20 | * them from the extent map | 53 | * them from the extent map |
@@ -39,7 +72,7 @@ static int del_pending_extents(struct ctree_root *extent_root) | |||
39 | key.flags = 0; | 72 | key.flags = 0; |
40 | key.offset = 1; | 73 | key.offset = 1; |
41 | init_path(&path); | 74 | init_path(&path); |
42 | ret = search_slot(extent_root, &key, &path, -1); | 75 | ret = search_slot(extent_root, &key, &path, -1, 1); |
43 | if (ret) { | 76 | if (ret) { |
44 | print_tree(extent_root, extent_root->node); | 77 | print_tree(extent_root, extent_root->node); |
45 | printf("unable to find %Lu\n", key.objectid); | 78 | printf("unable to find %Lu\n", key.objectid); |
@@ -83,7 +116,7 @@ int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks) | |||
83 | return 0; | 116 | return 0; |
84 | } | 117 | } |
85 | init_path(&path); | 118 | init_path(&path); |
86 | ret = search_slot(extent_root, &key, &path, -1); | 119 | ret = search_slot(extent_root, &key, &path, -1, 1); |
87 | if (ret) { | 120 | if (ret) { |
88 | print_tree(extent_root, extent_root->node); | 121 | print_tree(extent_root, extent_root->node); |
89 | printf("failed to find %Lu\n", key.objectid); | 122 | printf("failed to find %Lu\n", key.objectid); |
@@ -124,7 +157,7 @@ check_failed: | |||
124 | ins->offset = 0; | 157 | ins->offset = 0; |
125 | ins->flags = 0; | 158 | ins->flags = 0; |
126 | start_found = 0; | 159 | start_found = 0; |
127 | ret = search_slot(root, ins, &path, 0); | 160 | ret = search_slot(root, ins, &path, 0, 0); |
128 | if (ret < 0) | 161 | if (ret < 0) |
129 | goto error; | 162 | goto error; |
130 | 163 | ||
@@ -221,6 +254,8 @@ static int insert_pending_extents(struct ctree_root *extent_root) | |||
221 | ret = insert_item(extent_root, &key, &item, | 254 | ret = insert_item(extent_root, &key, &item, |
222 | sizeof(item)); | 255 | sizeof(item)); |
223 | if (ret) { | 256 | if (ret) { |
257 | printf("%Lu already in tree\n", key.objectid); | ||
258 | print_tree(extent_root, extent_root->node); | ||
224 | BUG(); | 259 | BUG(); |
225 | // FIXME undo it and return sane | 260 | // FIXME undo it and return sane |
226 | return ret; | 261 | return ret; |
@@ -228,6 +263,7 @@ static int insert_pending_extents(struct ctree_root *extent_root) | |||
228 | radix_tree_tag_clear(&extent_root->cache_radix, | 263 | radix_tree_tag_clear(&extent_root->cache_radix, |
229 | gang[i]->blocknr, | 264 | gang[i]->blocknr, |
230 | CTREE_EXTENT_PENDING); | 265 | CTREE_EXTENT_PENDING); |
266 | printf("%Lu is not pending\n", gang[i]->blocknr); | ||
231 | tree_block_release(extent_root, gang[i]); | 267 | tree_block_release(extent_root, gang[i]); |
232 | } | 268 | } |
233 | } | 269 | } |
@@ -266,15 +302,18 @@ int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start, | |||
266 | if (pending_ret) | 302 | if (pending_ret) |
267 | return pending_ret; | 303 | return pending_ret; |
268 | *buf = find_tree_block(root, ins->objectid); | 304 | *buf = find_tree_block(root, ins->objectid); |
305 | dirty_tree_block(root, *buf); | ||
269 | return 0; | 306 | return 0; |
270 | } | 307 | } |
271 | /* we're allocating an extent for the extent tree, don't recurse */ | 308 | /* we're allocating an extent for the extent tree, don't recurse */ |
272 | BUG_ON(ins->offset != 1); | 309 | BUG_ON(ins->offset != 1); |
273 | *buf = find_tree_block(root, ins->objectid); | 310 | *buf = find_tree_block(root, ins->objectid); |
274 | BUG_ON(!*buf); | 311 | BUG_ON(!*buf); |
312 | printf("%Lu is pending\n", ins->objectid); | ||
275 | radix_tree_tag_set(&root->cache_radix, ins->objectid, | 313 | radix_tree_tag_set(&root->cache_radix, ins->objectid, |
276 | CTREE_EXTENT_PENDING); | 314 | CTREE_EXTENT_PENDING); |
277 | (*buf)->count++; | 315 | (*buf)->count++; |
316 | dirty_tree_block(root, *buf); | ||
278 | return 0; | 317 | return 0; |
279 | 318 | ||
280 | } | 319 | } |