aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-02 16:08:05 -0500
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-02 16:08:05 -0500
commit02217ed299c6340a35696e0610047eb96826de2d (patch)
tree4a92c16ce2a51f701c829d96f644486fb7b29517 /fs/btrfs/extent-tree.c
parent77ce6846c40e83193df01295e5af437f8b6c7a2d (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.c45
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
18static 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
40int 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}