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