aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-20 14:38:32 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-20 14:38:32 -0400
commit9f5fae2fe6dc35b46bf56183f11398451851cb3f (patch)
treee72b03149662b8e5d4fe491c36f3cf66c5df5437 /fs/btrfs/extent-tree.c
parent631d7d950a2f2706f5c86858402c1ec50b9801f1 (diff)
Btrfs: Add inode map, and the start of file extent items
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c105
1 files changed, 57 insertions, 48 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c29b92d440e0..09eeeb4d9d28 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -35,13 +35,15 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
35 struct btrfs_key ins; 35 struct btrfs_key ins;
36 u32 refs; 36 u32 refs;
37 37
38 find_free_extent(trans, root->extent_root, 0, 0, (u64)-1, &ins); 38 find_free_extent(trans, root->fs_info->extent_root, 0, 0, (u64)-1,
39 &ins);
39 btrfs_init_path(&path); 40 btrfs_init_path(&path);
40 key.objectid = blocknr; 41 key.objectid = blocknr;
41 key.flags = 0; 42 key.flags = 0;
42 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 43 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
43 key.offset = 1; 44 key.offset = 1;
44 ret = btrfs_search_slot(trans, root->extent_root, &key, &path, 0, 1); 45 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path,
46 0, 1);
45 if (ret != 0) 47 if (ret != 0)
46 BUG(); 48 BUG();
47 BUG_ON(ret != 0); 49 BUG_ON(ret != 0);
@@ -51,9 +53,9 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
51 btrfs_set_extent_refs(item, refs + 1); 53 btrfs_set_extent_refs(item, refs + 1);
52 54
53 BUG_ON(list_empty(&path.nodes[0]->dirty)); 55 BUG_ON(list_empty(&path.nodes[0]->dirty));
54 btrfs_release_path(root->extent_root, &path); 56 btrfs_release_path(root->fs_info->extent_root, &path);
55 finish_current_insert(trans, root->extent_root); 57 finish_current_insert(trans, root->fs_info->extent_root);
56 run_pending(trans, root->extent_root); 58 run_pending(trans, root->fs_info->extent_root);
57 return 0; 59 return 0;
58} 60}
59 61
@@ -70,13 +72,14 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
70 key.offset = 1; 72 key.offset = 1;
71 key.flags = 0; 73 key.flags = 0;
72 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 74 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
73 ret = btrfs_search_slot(trans, root->extent_root, &key, &path, 0, 0); 75 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path,
76 0, 0);
74 if (ret != 0) 77 if (ret != 0)
75 BUG(); 78 BUG();
76 l = &path.nodes[0]->leaf; 79 l = &path.nodes[0]->leaf;
77 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); 80 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item);
78 *refs = btrfs_extent_refs(item); 81 *refs = btrfs_extent_refs(item);
79 btrfs_release_path(root->extent_root, &path); 82 btrfs_release_path(root->fs_info->extent_root, &path);
80 return 0; 83 return 0;
81} 84}
82 85
@@ -107,19 +110,20 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
107 int i; 110 int i;
108 111
109 while(1) { 112 while(1) {
110 ret = radix_tree_gang_lookup(&root->pinned_radix, 113 ret = radix_tree_gang_lookup(&root->fs_info->pinned_radix,
111 (void **)gang, 0, 114 (void **)gang, 0,
112 ARRAY_SIZE(gang)); 115 ARRAY_SIZE(gang));
113 if (!ret) 116 if (!ret)
114 break; 117 break;
115 if (!first) 118 if (!first)
116 first = gang[0]; 119 first = gang[0];
117 for (i = 0; i < ret; i++) { 120 for (i = 0; i < ret; i++) {
118 radix_tree_delete(&root->pinned_radix, gang[i]); 121 radix_tree_delete(&root->fs_info->pinned_radix,
122 gang[i]);
119 } 123 }
120 } 124 }
121 root->last_insert.objectid = first; 125 root->fs_info->last_insert.objectid = first;
122 root->last_insert.offset = 0; 126 root->fs_info->last_insert.offset = 0;
123 return 0; 127 return 0;
124} 128}
125 129
@@ -138,13 +142,14 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
138 ins.flags = 0; 142 ins.flags = 0;
139 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); 143 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY);
140 144
141 for (i = 0; i < extent_root->current_insert.flags; i++) { 145 for (i = 0; i < extent_root->fs_info->current_insert.flags; i++) {
142 ins.objectid = extent_root->current_insert.objectid + i; 146 ins.objectid = extent_root->fs_info->current_insert.objectid +
147 i;
143 ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item, 148 ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item,
144 sizeof(extent_item)); 149 sizeof(extent_item));
145 BUG_ON(ret); 150 BUG_ON(ret);
146 } 151 }
147 extent_root->current_insert.offset = 0; 152 extent_root->fs_info->current_insert.offset = 0;
148 return 0; 153 return 0;
149} 154}
150 155
@@ -156,7 +161,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
156{ 161{
157 struct btrfs_path path; 162 struct btrfs_path path;
158 struct btrfs_key key; 163 struct btrfs_key key;
159 struct btrfs_root *extent_root = root->extent_root; 164 struct btrfs_root *extent_root = root->fs_info->extent_root;
160 int ret; 165 int ret;
161 struct btrfs_extent_item *ei; 166 struct btrfs_extent_item *ei;
162 struct btrfs_key ins; 167 struct btrfs_key ins;
@@ -186,14 +191,16 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
186 if (pin) { 191 if (pin) {
187 int err; 192 int err;
188 radix_tree_preload(GFP_KERNEL); 193 radix_tree_preload(GFP_KERNEL);
189 err = radix_tree_insert(&extent_root->pinned_radix, 194 err = radix_tree_insert(
190 blocknr, (void *)blocknr); 195 &extent_root->fs_info->pinned_radix,
196 blocknr, (void *)blocknr);
191 BUG_ON(err); 197 BUG_ON(err);
192 radix_tree_preload_end(); 198 radix_tree_preload_end();
193 } 199 }
194 ret = btrfs_del_item(trans, extent_root, &path); 200 ret = btrfs_del_item(trans, extent_root, &path);
195 if (!pin && extent_root->last_insert.objectid > blocknr) 201 if (!pin && extent_root->fs_info->last_insert.objectid >
196 extent_root->last_insert.objectid = blocknr; 202 blocknr)
203 extent_root->fs_info->last_insert.objectid = blocknr;
197 if (ret) 204 if (ret)
198 BUG(); 205 BUG();
199 } 206 }
@@ -214,18 +221,19 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
214 int i; 221 int i;
215 222
216 while(1) { 223 while(1) {
217 ret = radix_tree_gang_lookup_tag(&extent_root->cache_radix, 224 ret = radix_tree_gang_lookup_tag(
218 (void **)gang, 0, 225 &extent_root->fs_info->cache_radix,
219 ARRAY_SIZE(gang), 226 (void **)gang, 0,
220 CTREE_EXTENT_PENDING_DEL); 227 ARRAY_SIZE(gang),
228 CTREE_EXTENT_PENDING_DEL);
221 if (!ret) 229 if (!ret)
222 break; 230 break;
223 for (i = 0; i < ret; i++) { 231 for (i = 0; i < ret; i++) {
224 ret = __free_extent(trans, extent_root, 232 ret = __free_extent(trans, extent_root,
225 gang[i]->blocknr, 1, 1); 233 gang[i]->blocknr, 1, 1);
226 radix_tree_tag_clear(&extent_root->cache_radix, 234 radix_tree_tag_clear(&extent_root->fs_info->cache_radix,
227 gang[i]->blocknr, 235 gang[i]->blocknr,
228 CTREE_EXTENT_PENDING_DEL); 236 CTREE_EXTENT_PENDING_DEL);
229 btrfs_block_release(extent_root, gang[i]); 237 btrfs_block_release(extent_root, gang[i]);
230 } 238 }
231 } 239 }
@@ -235,8 +243,8 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
235static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root 243static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
236 *extent_root) 244 *extent_root)
237{ 245{
238 while(radix_tree_tagged(&extent_root->cache_radix, 246 while(radix_tree_tagged(&extent_root->fs_info->cache_radix,
239 CTREE_EXTENT_PENDING_DEL)) 247 CTREE_EXTENT_PENDING_DEL))
240 del_pending_extents(trans, extent_root); 248 del_pending_extents(trans, extent_root);
241 return 0; 249 return 0;
242} 250}
@@ -248,19 +256,19 @@ static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
248int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root 256int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
249 *root, u64 blocknr, u64 num_blocks, int pin) 257 *root, u64 blocknr, u64 num_blocks, int pin)
250{ 258{
251 struct btrfs_root *extent_root = root->extent_root; 259 struct btrfs_root *extent_root = root->fs_info->extent_root;
252 struct btrfs_buffer *t; 260 struct btrfs_buffer *t;
253 int pending_ret; 261 int pending_ret;
254 int ret; 262 int ret;
255 263
256 if (root == extent_root) { 264 if (root == extent_root) {
257 t = find_tree_block(root, blocknr); 265 t = find_tree_block(root, blocknr);
258 radix_tree_tag_set(&root->cache_radix, blocknr, 266 radix_tree_tag_set(&root->fs_info->cache_radix, blocknr,
259 CTREE_EXTENT_PENDING_DEL); 267 CTREE_EXTENT_PENDING_DEL);
260 return 0; 268 return 0;
261 } 269 }
262 ret = __free_extent(trans, root, blocknr, num_blocks, pin); 270 ret = __free_extent(trans, root, blocknr, num_blocks, pin);
263 pending_ret = run_pending(trans, root->extent_root); 271 pending_ret = run_pending(trans, root->fs_info->extent_root);
264 return ret ? ret : pending_ret; 272 return ret ? ret : pending_ret;
265} 273}
266 274
@@ -285,12 +293,12 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
285 u64 test_block; 293 u64 test_block;
286 int start_found; 294 int start_found;
287 struct btrfs_leaf *l; 295 struct btrfs_leaf *l;
288 struct btrfs_root * root = orig_root->extent_root; 296 struct btrfs_root * root = orig_root->fs_info->extent_root;
289 int total_needed = num_blocks; 297 int total_needed = num_blocks;
290 298
291 total_needed += (btrfs_header_level(&root->node->node.header) + 1) * 3; 299 total_needed += (btrfs_header_level(&root->node->node.header) + 1) * 3;
292 if (root->last_insert.objectid > search_start) 300 if (root->fs_info->last_insert.objectid > search_start)
293 search_start = root->last_insert.objectid; 301 search_start = root->fs_info->last_insert.objectid;
294 302
295 ins->flags = 0; 303 ins->flags = 0;
296 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 304 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
@@ -353,16 +361,17 @@ check_pending:
353 BUG_ON(ins->objectid < search_start); 361 BUG_ON(ins->objectid < search_start);
354 for (test_block = ins->objectid; 362 for (test_block = ins->objectid;
355 test_block < ins->objectid + total_needed; test_block++) { 363 test_block < ins->objectid + total_needed; test_block++) {
356 if (radix_tree_lookup(&root->pinned_radix, test_block)) { 364 if (radix_tree_lookup(&root->fs_info->pinned_radix,
365 test_block)) {
357 search_start = test_block + 1; 366 search_start = test_block + 1;
358 goto check_failed; 367 goto check_failed;
359 } 368 }
360 } 369 }
361 BUG_ON(root->current_insert.offset); 370 BUG_ON(root->fs_info->current_insert.offset);
362 root->current_insert.offset = total_needed - num_blocks; 371 root->fs_info->current_insert.offset = total_needed - num_blocks;
363 root->current_insert.objectid = ins->objectid + num_blocks; 372 root->fs_info->current_insert.objectid = ins->objectid + num_blocks;
364 root->current_insert.flags = 0; 373 root->fs_info->current_insert.flags = 0;
365 root->last_insert.objectid = ins->objectid; 374 root->fs_info->last_insert.objectid = ins->objectid;
366 ins->offset = num_blocks; 375 ins->offset = num_blocks;
367 return 0; 376 return 0;
368error: 377error:
@@ -383,20 +392,20 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
383{ 392{
384 int ret; 393 int ret;
385 int pending_ret; 394 int pending_ret;
386 struct btrfs_root *extent_root = root->extent_root; 395 struct btrfs_root *extent_root = root->fs_info->extent_root;
387 struct btrfs_extent_item extent_item; 396 struct btrfs_extent_item extent_item;
388 397
389 btrfs_set_extent_refs(&extent_item, 1); 398 btrfs_set_extent_refs(&extent_item, 1);
390 btrfs_set_extent_owner(&extent_item, owner); 399 btrfs_set_extent_owner(&extent_item, owner);
391 400
392 if (root == extent_root) { 401 if (root == extent_root) {
393 BUG_ON(extent_root->current_insert.offset == 0); 402 BUG_ON(extent_root->fs_info->current_insert.offset == 0);
394 BUG_ON(num_blocks != 1); 403 BUG_ON(num_blocks != 1);
395 BUG_ON(extent_root->current_insert.flags == 404 BUG_ON(extent_root->fs_info->current_insert.flags ==
396 extent_root->current_insert.offset); 405 extent_root->fs_info->current_insert.offset);
397 ins->offset = 1; 406 ins->offset = 1;
398 ins->objectid = extent_root->current_insert.objectid + 407 ins->objectid = extent_root->fs_info->current_insert.objectid +
399 extent_root->current_insert.flags++; 408 extent_root->fs_info->current_insert.flags++;
400 return 0; 409 return 0;
401 } 410 }
402 ret = find_free_extent(trans, root, num_blocks, search_start, 411 ret = find_free_extent(trans, root, num_blocks, search_start,