rename funcs and structs to btrfs
[linux-2.6-block.git] / fs / btrfs / extent-tree.c
CommitLineData
fec577fb
CM
1#include <stdio.h>
2#include <stdlib.h>
3#include "kerncompat.h"
4#include "radix-tree.h"
5#include "ctree.h"
6#include "disk-io.h"
7#include "print-tree.h"
8
234b63a0 9static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks,
e2fa7227
CM
10 u64 search_start, u64 search_end,
11 struct btrfs_key *ins);
234b63a0
CM
12static int finish_current_insert(struct btrfs_root *extent_root);
13static int run_pending(struct btrfs_root *extent_root);
037e6390 14
fec577fb
CM
15/*
16 * pending extents are blocks that we're trying to allocate in the extent
17 * map while trying to grow the map because of other allocations. To avoid
18 * recursing, they are tagged in the radix tree and cleaned up after
19 * other allocations are done. The pending tag is also used in the same
20 * manner for deletes.
21 */
037e6390 22#define CTREE_EXTENT_PENDING_DEL 0
fec577fb 23
234b63a0 24static int inc_block_ref(struct btrfs_root *root, u64 blocknr)
02217ed2 25{
234b63a0 26 struct btrfs_path path;
02217ed2 27 int ret;
e2fa7227 28 struct btrfs_key key;
234b63a0
CM
29 struct btrfs_leaf *l;
30 struct btrfs_extent_item *item;
e2fa7227 31 struct btrfs_key ins;
cf27e1ee 32 u32 refs;
037e6390
CM
33
34 find_free_extent(root->extent_root, 0, 0, (u64)-1, &ins);
234b63a0 35 btrfs_init_path(&path);
02217ed2
CM
36 key.objectid = blocknr;
37 key.flags = 0;
38 key.offset = 1;
234b63a0 39 ret = btrfs_search_slot(root->extent_root, &key, &path, 0, 1);
a28ec197
CM
40 if (ret != 0)
41 BUG();
02217ed2
CM
42 BUG_ON(ret != 0);
43 l = &path.nodes[0]->leaf;
234b63a0
CM
44 item = (struct btrfs_extent_item *)(l->data +
45 btrfs_item_offset(l->items +
46 path.slots[0]));
cf27e1ee
CM
47 refs = btrfs_extent_refs(item);
48 btrfs_set_extent_refs(item, refs + 1);
a28ec197 49
02217ed2 50 BUG_ON(list_empty(&path.nodes[0]->dirty));
234b63a0 51 btrfs_release_path(root->extent_root, &path);
037e6390
CM
52 finish_current_insert(root->extent_root);
53 run_pending(root->extent_root);
02217ed2
CM
54 return 0;
55}
56
234b63a0 57static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs)
a28ec197 58{
234b63a0 59 struct btrfs_path path;
a28ec197 60 int ret;
e2fa7227 61 struct btrfs_key key;
234b63a0
CM
62 struct btrfs_leaf *l;
63 struct btrfs_extent_item *item;
64 btrfs_init_path(&path);
a28ec197
CM
65 key.objectid = blocknr;
66 key.flags = 0;
67 key.offset = 1;
234b63a0 68 ret = btrfs_search_slot(root->extent_root, &key, &path, 0, 0);
a28ec197
CM
69 if (ret != 0)
70 BUG();
71 l = &path.nodes[0]->leaf;
234b63a0 72 item = (struct btrfs_extent_item *)(l->data +
0783fcfc
CM
73 btrfs_item_offset(l->items +
74 path.slots[0]));
cf27e1ee 75 *refs = btrfs_extent_refs(item);
234b63a0 76 btrfs_release_path(root->extent_root, &path);
a28ec197
CM
77 return 0;
78}
79
234b63a0 80int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf)
02217ed2
CM
81{
82 u64 blocknr;
83 int i;
a28ec197
CM
84
85 if (root == root->extent_root)
86 return 0;
7518a238 87 if (btrfs_is_leaf(&buf->node))
a28ec197
CM
88 return 0;
89
7518a238 90 for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) {
1d4f8a0c 91 blocknr = btrfs_node_blockptr(&buf->node, i);
02217ed2
CM
92 inc_block_ref(root, blocknr);
93 }
94 return 0;
95}
96
234b63a0 97int btrfs_finish_extent_commit(struct btrfs_root *root)
a28ec197 98{
234b63a0 99 struct btrfs_root *extent_root = root->extent_root;
a28ec197
CM
100 unsigned long gang[8];
101 int ret;
102 int i;
103
104 while(1) {
105 ret = radix_tree_gang_lookup(&extent_root->pinned_radix,
106 (void **)gang, 0,
107 ARRAY_SIZE(gang));
108 if (!ret)
109 break;
0579da42 110 for (i = 0; i < ret; i++) {
a28ec197 111 radix_tree_delete(&extent_root->pinned_radix, gang[i]);
0579da42 112 }
a28ec197 113 }
0579da42
CM
114 extent_root->last_insert.objectid = 0;
115 extent_root->last_insert.offset = 0;
a28ec197
CM
116 return 0;
117}
118
234b63a0 119static int finish_current_insert(struct btrfs_root *extent_root)
037e6390 120{
e2fa7227 121 struct btrfs_key ins;
234b63a0 122 struct btrfs_extent_item extent_item;
037e6390
CM
123 int i;
124 int ret;
125
cf27e1ee
CM
126 btrfs_set_extent_refs(&extent_item, 1);
127 btrfs_set_extent_owner(&extent_item,
128 btrfs_header_parentid(&extent_root->node->node.header));
037e6390
CM
129 ins.offset = 1;
130 ins.flags = 0;
131
132 for (i = 0; i < extent_root->current_insert.flags; i++) {
133 ins.objectid = extent_root->current_insert.objectid + i;
234b63a0 134 ret = btrfs_insert_item(extent_root, &ins, &extent_item,
037e6390
CM
135 sizeof(extent_item));
136 BUG_ON(ret);
137 }
138 extent_root->current_insert.offset = 0;
139 return 0;
140}
141
fec577fb 142/*
a28ec197 143 * remove an extent from the root, returns 0 on success
fec577fb 144 */
234b63a0 145static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
a28ec197 146{
234b63a0 147 struct btrfs_path path;
e2fa7227 148 struct btrfs_key key;
234b63a0 149 struct btrfs_root *extent_root = root->extent_root;
a28ec197 150 int ret;
0783fcfc 151 struct btrfs_item *item;
234b63a0 152 struct btrfs_extent_item *ei;
e2fa7227 153 struct btrfs_key ins;
cf27e1ee 154 u32 refs;
037e6390 155
a28ec197
CM
156 key.objectid = blocknr;
157 key.flags = 0;
158 key.offset = num_blocks;
159
037e6390 160 find_free_extent(root, 0, 0, (u64)-1, &ins);
234b63a0
CM
161 btrfs_init_path(&path);
162 ret = btrfs_search_slot(extent_root, &key, &path, -1, 1);
a28ec197
CM
163 if (ret) {
164 printf("failed to find %Lu\n", key.objectid);
234b63a0 165 btrfs_print_tree(extent_root, extent_root->node);
a28ec197
CM
166 printf("failed to find %Lu\n", key.objectid);
167 BUG();
168 }
169 item = path.nodes[0]->leaf.items + path.slots[0];
234b63a0 170 ei = (struct btrfs_extent_item *)(path.nodes[0]->leaf.data +
0783fcfc 171 btrfs_item_offset(item));
a28ec197 172 BUG_ON(ei->refs == 0);
cf27e1ee
CM
173 refs = btrfs_extent_refs(ei) - 1;
174 btrfs_set_extent_refs(ei, refs);
175 if (refs == 0) {
a28ec197
CM
176 if (root == extent_root) {
177 int err;
178 radix_tree_preload(GFP_KERNEL);
179 err = radix_tree_insert(&extent_root->pinned_radix,
180 blocknr, (void *)blocknr);
181 BUG_ON(err);
182 radix_tree_preload_end();
183 }
234b63a0 184 ret = btrfs_del_item(extent_root, &path);
0579da42
CM
185 if (root != extent_root &&
186 extent_root->last_insert.objectid < blocknr)
187 extent_root->last_insert.objectid = blocknr;
a28ec197
CM
188 if (ret)
189 BUG();
190 }
234b63a0 191 btrfs_release_path(extent_root, &path);
037e6390 192 finish_current_insert(extent_root);
a28ec197
CM
193 return ret;
194}
195
a28ec197
CM
196/*
197 * find all the blocks marked as pending in the radix tree and remove
198 * them from the extent map
199 */
234b63a0 200static int del_pending_extents(struct btrfs_root *extent_root)
a28ec197
CM
201{
202 int ret;
234b63a0 203 struct btrfs_buffer *gang[4];
a28ec197
CM
204 int i;
205
206 while(1) {
207 ret = radix_tree_gang_lookup_tag(&extent_root->cache_radix,
208 (void **)gang, 0,
209 ARRAY_SIZE(gang),
210 CTREE_EXTENT_PENDING_DEL);
211 if (!ret)
212 break;
213 for (i = 0; i < ret; i++) {
214 ret = __free_extent(extent_root, gang[i]->blocknr, 1);
fec577fb
CM
215 radix_tree_tag_clear(&extent_root->cache_radix,
216 gang[i]->blocknr,
a28ec197 217 CTREE_EXTENT_PENDING_DEL);
234b63a0 218 btrfs_block_release(extent_root, gang[i]);
fec577fb
CM
219 }
220 }
221 return 0;
222}
223
234b63a0 224static int run_pending(struct btrfs_root *extent_root)
a28ec197
CM
225{
226 while(radix_tree_tagged(&extent_root->cache_radix,
037e6390 227 CTREE_EXTENT_PENDING_DEL))
a28ec197 228 del_pending_extents(extent_root);
a28ec197
CM
229 return 0;
230}
231
232
fec577fb
CM
233/*
234 * remove an extent from the root, returns 0 on success
235 */
234b63a0 236int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
fec577fb 237{
e2fa7227 238 struct btrfs_key key;
234b63a0
CM
239 struct btrfs_root *extent_root = root->extent_root;
240 struct btrfs_buffer *t;
fec577fb
CM
241 int pending_ret;
242 int ret;
a28ec197 243
fec577fb 244 if (root == extent_root) {
a28ec197 245 t = find_tree_block(root, blocknr);
037e6390 246 radix_tree_tag_set(&root->cache_radix, blocknr,
a28ec197 247 CTREE_EXTENT_PENDING_DEL);
fec577fb
CM
248 return 0;
249 }
a28ec197
CM
250 key.objectid = blocknr;
251 key.flags = 0;
252 key.offset = num_blocks;
253 ret = __free_extent(root, blocknr, num_blocks);
254 pending_ret = run_pending(root->extent_root);
fec577fb
CM
255 return ret ? ret : pending_ret;
256}
257
258/*
259 * walks the btree of allocated extents and find a hole of a given size.
260 * The key ins is changed to record the hole:
261 * ins->objectid == block start
262 * ins->flags = 0
263 * ins->offset == number of blocks
264 * Any available blocks before search_start are skipped.
265 */
234b63a0 266static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks,
e2fa7227
CM
267 u64 search_start, u64 search_end,
268 struct btrfs_key *ins)
fec577fb 269{
234b63a0 270 struct btrfs_path path;
e2fa7227 271 struct btrfs_key key;
fec577fb
CM
272 int ret;
273 u64 hole_size = 0;
274 int slot = 0;
275 u64 last_block;
037e6390 276 u64 test_block;
fec577fb 277 int start_found;
234b63a0
CM
278 struct btrfs_leaf *l;
279 struct btrfs_root * root = orig_root->extent_root;
0579da42 280 int total_needed = num_blocks;
fec577fb 281
7518a238 282 total_needed += (btrfs_header_level(&root->node->node.header) + 1) * 3;
0579da42
CM
283 if (root->last_insert.objectid > search_start)
284 search_start = root->last_insert.objectid;
fec577fb 285check_failed:
234b63a0 286 btrfs_init_path(&path);
fec577fb
CM
287 ins->objectid = search_start;
288 ins->offset = 0;
289 ins->flags = 0;
290 start_found = 0;
234b63a0 291 ret = btrfs_search_slot(root, ins, &path, 0, 0);
0f70abe2
CM
292 if (ret < 0)
293 goto error;
aa5d6bed 294
0579da42
CM
295 if (path.slots[0] > 0)
296 path.slots[0]--;
297
fec577fb
CM
298 while (1) {
299 l = &path.nodes[0]->leaf;
300 slot = path.slots[0];
7518a238 301 if (slot >= btrfs_header_nritems(&l->header)) {
234b63a0 302 ret = btrfs_next_leaf(root, &path);
fec577fb
CM
303 if (ret == 0)
304 continue;
0f70abe2
CM
305 if (ret < 0)
306 goto error;
fec577fb
CM
307 if (!start_found) {
308 ins->objectid = search_start;
037e6390 309 ins->offset = (u64)-1;
fec577fb
CM
310 start_found = 1;
311 goto check_pending;
312 }
313 ins->objectid = last_block > search_start ?
314 last_block : search_start;
037e6390 315 ins->offset = (u64)-1;
fec577fb
CM
316 goto check_pending;
317 }
e2fa7227
CM
318 btrfs_disk_key_to_cpu(&key, &l->items[slot].key);
319 if (key.objectid >= search_start) {
fec577fb 320 if (start_found) {
0579da42
CM
321 if (last_block < search_start)
322 last_block = search_start;
e2fa7227 323 hole_size = key.objectid - last_block;
037e6390 324 if (hole_size > total_needed) {
fec577fb 325 ins->objectid = last_block;
037e6390 326 ins->offset = hole_size;
fec577fb
CM
327 goto check_pending;
328 }
0579da42 329 }
fec577fb 330 }
0579da42 331 start_found = 1;
e2fa7227 332 last_block = key.objectid + key.offset;
fec577fb
CM
333 path.slots[0]++;
334 }
335 // FIXME -ENOSPC
336check_pending:
337 /* we have to make sure we didn't find an extent that has already
338 * been allocated by the map tree or the original allocation
339 */
234b63a0 340 btrfs_release_path(root, &path);
fec577fb 341 BUG_ON(ins->objectid < search_start);
037e6390
CM
342 for (test_block = ins->objectid;
343 test_block < ins->objectid + total_needed; test_block++) {
344 if (radix_tree_lookup(&root->pinned_radix, test_block)) {
345 search_start = test_block + 1;
fec577fb
CM
346 goto check_failed;
347 }
348 }
037e6390 349 BUG_ON(root->current_insert.offset);
0579da42 350 root->current_insert.offset = total_needed - num_blocks;
037e6390
CM
351 root->current_insert.objectid = ins->objectid + num_blocks;
352 root->current_insert.flags = 0;
0579da42 353 root->last_insert.objectid = ins->objectid;
037e6390 354 ins->offset = num_blocks;
fec577fb 355 return 0;
0f70abe2 356error:
234b63a0 357 btrfs_release_path(root, &path);
0f70abe2 358 return ret;
fec577fb
CM
359}
360
fec577fb
CM
361/*
362 * finds a free extent and does all the dirty work required for allocation
363 * returns the key for the extent through ins, and a tree buffer for
364 * the first block of the extent through buf.
365 *
366 * returns 0 if everything worked, non-zero otherwise.
367 */
234b63a0 368int alloc_extent(struct btrfs_root *root, u64 num_blocks, u64 search_start,
e2fa7227 369 u64 search_end, u64 owner, struct btrfs_key *ins)
fec577fb
CM
370{
371 int ret;
372 int pending_ret;
234b63a0
CM
373 struct btrfs_root *extent_root = root->extent_root;
374 struct btrfs_extent_item extent_item;
037e6390 375
cf27e1ee
CM
376 btrfs_set_extent_refs(&extent_item, 1);
377 btrfs_set_extent_owner(&extent_item, owner);
fec577fb 378
037e6390
CM
379 if (root == extent_root) {
380 BUG_ON(extent_root->current_insert.offset == 0);
381 BUG_ON(num_blocks != 1);
382 BUG_ON(extent_root->current_insert.flags ==
383 extent_root->current_insert.offset);
384 ins->offset = 1;
385 ins->objectid = extent_root->current_insert.objectid +
386 extent_root->current_insert.flags++;
fec577fb
CM
387 return 0;
388 }
037e6390
CM
389 ret = find_free_extent(root, num_blocks, search_start,
390 search_end, ins);
391 if (ret)
392 return ret;
fec577fb 393
234b63a0 394 ret = btrfs_insert_item(extent_root, ins, &extent_item,
037e6390
CM
395 sizeof(extent_item));
396
397 finish_current_insert(extent_root);
398 pending_ret = run_pending(extent_root);
399 if (ret)
400 return ret;
401 if (pending_ret)
402 return pending_ret;
403 return 0;
fec577fb
CM
404}
405
406/*
407 * helper function to allocate a block for a given tree
408 * returns the tree buffer or NULL.
409 */
234b63a0 410struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root)
fec577fb 411{
e2fa7227 412 struct btrfs_key ins;
fec577fb 413 int ret;
234b63a0 414 struct btrfs_buffer *buf;
fec577fb
CM
415
416 ret = alloc_extent(root, 1, 0, (unsigned long)-1,
7518a238 417 btrfs_header_parentid(&root->node->node.header),
037e6390 418 &ins);
fec577fb
CM
419 if (ret) {
420 BUG();
421 return NULL;
422 }
037e6390
CM
423 buf = find_tree_block(root, ins.objectid);
424 dirty_tree_block(root, buf);
fec577fb
CM
425 return buf;
426}
a28ec197 427
234b63a0 428int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, int *level)
20524f02 429{
234b63a0
CM
430 struct btrfs_buffer *next;
431 struct btrfs_buffer *cur;
20524f02
CM
432 u64 blocknr;
433 int ret;
434 u32 refs;
435
436 ret = lookup_block_ref(root, path->nodes[*level]->blocknr, &refs);
437 BUG_ON(ret);
438 if (refs > 1)
439 goto out;
440 while(*level > 0) {
441 cur = path->nodes[*level];
7518a238
CM
442 if (path->slots[*level] >=
443 btrfs_header_nritems(&cur->node.header))
20524f02 444 break;
1d4f8a0c 445 blocknr = btrfs_node_blockptr(&cur->node, path->slots[*level]);
20524f02
CM
446 ret = lookup_block_ref(root, blocknr, &refs);
447 if (refs != 1 || *level == 1) {
448 path->slots[*level]++;
234b63a0 449 ret = btrfs_free_extent(root, blocknr, 1);
20524f02
CM
450 BUG_ON(ret);
451 continue;
452 }
453 BUG_ON(ret);
454 next = read_tree_block(root, blocknr);
83e15a28 455 if (path->nodes[*level-1])
234b63a0 456 btrfs_block_release(root, path->nodes[*level-1]);
20524f02 457 path->nodes[*level-1] = next;
7518a238 458 *level = btrfs_header_level(&next->node.header);
20524f02
CM
459 path->slots[*level] = 0;
460 }
461out:
234b63a0
CM
462 ret = btrfs_free_extent(root, path->nodes[*level]->blocknr, 1);
463 btrfs_block_release(root, path->nodes[*level]);
20524f02
CM
464 path->nodes[*level] = NULL;
465 *level += 1;
466 BUG_ON(ret);
467 return 0;
468}
469
234b63a0 470int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path, int *level)
20524f02
CM
471{
472 int i;
473 int slot;
474 int ret;
234b63a0 475 for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
20524f02 476 slot = path->slots[i];
7518a238
CM
477 if (slot <
478 btrfs_header_nritems(&path->nodes[i]->node.header)- 1) {
20524f02
CM
479 path->slots[i]++;
480 *level = i;
481 return 0;
482 } else {
234b63a0 483 ret = btrfs_free_extent(root,
20524f02 484 path->nodes[*level]->blocknr, 1);
234b63a0 485 btrfs_block_release(root, path->nodes[*level]);
83e15a28 486 path->nodes[*level] = NULL;
20524f02
CM
487 *level = i + 1;
488 BUG_ON(ret);
489 }
490 }
491 return 1;
492}
493
234b63a0 494int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap)
20524f02
CM
495{
496 int ret;
497 int level;
234b63a0 498 struct btrfs_path path;
20524f02
CM
499 int i;
500 int orig_level;
501
234b63a0 502 btrfs_init_path(&path);
20524f02 503
7518a238 504 level = btrfs_header_level(&snap->node.header);
20524f02
CM
505 orig_level = level;
506 path.nodes[level] = snap;
507 path.slots[level] = 0;
508 while(1) {
509 ret = walk_down_tree(root, &path, &level);
510 if (ret > 0)
511 break;
512 ret = walk_up_tree(root, &path, &level);
513 if (ret > 0)
514 break;
515 }
83e15a28
CM
516 for (i = 0; i <= orig_level; i++) {
517 if (path.nodes[i]) {
234b63a0 518 btrfs_block_release(root, path.nodes[i]);
83e15a28 519 }
20524f02
CM
520 }
521
522 return 0;
523}