3 #include "kerncompat.h"
4 #include "radix-tree.h"
7 #include "print-tree.h"
9 static int split_node(struct ctree_root *root, struct ctree_path *path,
11 static int split_leaf(struct ctree_root *root, struct ctree_path *path,
13 static int push_node_left(struct ctree_root *root, struct tree_buffer *dst,
14 struct tree_buffer *src);
15 static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
18 inline void init_path(struct ctree_path *p)
20 memset(p, 0, sizeof(*p));
23 void release_path(struct ctree_root *root, struct ctree_path *p)
26 for (i = 0; i < MAX_LEVEL; i++) {
29 tree_block_release(root, p->nodes[i]);
31 memset(p, 0, sizeof(*p));
35 * The leaf data grows from end-to-front in the node.
36 * this returns the address of the start of the last item,
37 * which is the stop of the leaf data stack
39 static inline unsigned int leaf_data_end(struct leaf *leaf)
41 unsigned int nr = leaf->header.nritems;
43 return sizeof(leaf->data);
44 return leaf->items[nr-1].offset;
48 * The space between the end of the leaf items and
49 * the start of the leaf data. IOW, how much room
50 * the leaf has left for both items and data
52 int leaf_free_space(struct leaf *leaf)
54 int data_end = leaf_data_end(leaf);
55 int nritems = leaf->header.nritems;
56 char *items_end = (char *)(leaf->items + nritems + 1);
57 return (char *)(leaf->data + data_end) - (char *)items_end;
61 * compare two keys in a memcmp fashion
63 int comp_keys(struct key *k1, struct key *k2)
65 if (k1->objectid > k2->objectid)
67 if (k1->objectid < k2->objectid)
69 if (k1->flags > k2->flags)
71 if (k1->flags < k2->flags)
73 if (k1->offset > k2->offset)
75 if (k1->offset < k2->offset)
80 int check_node(struct ctree_path *path, int level)
83 struct node *parent = NULL;
84 struct node *node = &path->nodes[level]->node;
87 if (path->nodes[level + 1])
88 parent = &path->nodes[level + 1]->node;
89 parent_slot = path->slots[level + 1];
90 if (parent && node->header.nritems > 0) {
91 struct key *parent_key;
92 parent_key = &parent->keys[parent_slot];
93 BUG_ON(memcmp(parent_key, node->keys, sizeof(struct key)));
94 BUG_ON(parent->blockptrs[parent_slot] != node->header.blocknr);
96 BUG_ON(node->header.nritems > NODEPTRS_PER_BLOCK);
97 for (i = 0; i < node->header.nritems - 2; i++) {
98 BUG_ON(comp_keys(&node->keys[i], &node->keys[i+1]) >= 0);
103 int check_leaf(struct ctree_path *path, int level)
106 struct leaf *leaf = &path->nodes[level]->leaf;
107 struct node *parent = NULL;
110 if (path->nodes[level + 1])
111 parent = &path->nodes[level + 1]->node;
112 parent_slot = path->slots[level + 1];
113 if (parent && leaf->header.nritems > 0) {
114 struct key *parent_key;
115 parent_key = &parent->keys[parent_slot];
116 BUG_ON(memcmp(parent_key, &leaf->items[0].key,
117 sizeof(struct key)));
118 BUG_ON(parent->blockptrs[parent_slot] != leaf->header.blocknr);
120 for (i = 0; i < leaf->header.nritems - 2; i++) {
121 BUG_ON(comp_keys(&leaf->items[i].key,
122 &leaf->items[i+1].key) >= 0);
123 BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset +
124 leaf->items[i + 1].size);
126 BUG_ON(leaf->items[i].offset + leaf->items[i].size !=
130 BUG_ON(leaf_free_space(leaf) < 0);
134 int check_block(struct ctree_path *path, int level)
137 return check_leaf(path, level);
138 return check_node(path, level);
142 * search for key in the array p. items p are item_size apart
143 * and there are 'max' items in p
144 * the slot in the array is returned via slot, and it points to
145 * the place where you would insert key if it is not found in
148 * slot may point to max if the key is bigger than all of the keys
150 int generic_bin_search(char *p, int item_size, struct key *key,
160 mid = (low + high) / 2;
161 tmp = (struct key *)(p + mid * item_size);
162 ret = comp_keys(tmp, key);
178 * simple bin_search frontend that does the right thing for
181 int bin_search(struct node *c, struct key *key, int *slot)
183 if (is_leaf(c->header.flags)) {
184 struct leaf *l = (struct leaf *)c;
185 return generic_bin_search((void *)l->items, sizeof(struct item),
186 key, c->header.nritems, slot);
188 return generic_bin_search((void *)c->keys, sizeof(struct key),
189 key, c->header.nritems, slot);
194 struct tree_buffer *read_node_slot(struct ctree_root *root,
195 struct tree_buffer *parent_buf,
198 struct node *node = &parent_buf->node;
201 if (slot >= node->header.nritems)
203 return read_tree_block(root, node->blockptrs[slot]);
206 static int balance_level(struct ctree_root *root, struct ctree_path *path,
209 struct tree_buffer *right_buf;
210 struct tree_buffer *mid_buf;
211 struct tree_buffer *left_buf;
212 struct tree_buffer *parent_buf = NULL;
213 struct node *right = NULL;
215 struct node *left = NULL;
216 struct node *parent = NULL;
222 int orig_slot = path->slots[level];
227 mid_buf = path->nodes[level];
228 mid = &mid_buf->node;
229 if (level < MAX_LEVEL - 1)
230 parent_buf = path->nodes[level + 1];
231 pslot = path->slots[level + 1];
234 struct tree_buffer *child;
235 u64 blocknr = mid_buf->blocknr;
237 if (mid->header.nritems != 1)
240 /* promote the child to a root */
241 child = read_node_slot(root, mid_buf, 0);
244 path->nodes[level] = NULL;
245 /* once for the path */
246 tree_block_release(root, mid_buf);
247 /* once for the root ptr */
248 tree_block_release(root, mid_buf);
249 return free_extent(root, blocknr, 1);
251 parent = &parent_buf->node;
253 if (mid->header.nritems > NODEPTRS_PER_BLOCK / 4)
256 // print_tree(root, root->node);
257 left_buf = read_node_slot(root, parent_buf, pslot - 1);
258 right_buf = read_node_slot(root, parent_buf, pslot + 1);
260 right = &right_buf->node;
261 used = right->header.nritems;
265 left = &left_buf->node;
266 used += left->header.nritems;
267 orig_slot += left->header.nritems;
271 push_node_left(root, left_buf, mid_buf);
273 push_node_left(root, mid_buf, right_buf);
274 if (right->header.nritems == 0) {
275 u64 blocknr = right_buf->blocknr;
276 tree_block_release(root, right_buf);
279 wret = del_ptr(root, path, level + 1, pslot + 1);
282 wret = free_extent(root, blocknr, 1);
286 memcpy(parent->keys + pslot + 1, right->keys,
290 if (mid->header.nritems == 0) {
291 u64 blocknr = mid_buf->blocknr;
292 tree_block_release(root, mid_buf);
295 wret = del_ptr(root, path, level + 1, pslot);
298 wret = free_extent(root, blocknr, 1);
302 memcpy(parent->keys + pslot, mid->keys, sizeof(struct key));
305 if (left->header.nritems >= orig_slot) {
306 left_buf->count++; // released below
307 path->nodes[level] = left_buf;
308 path->slots[level + 1] -= 1;
309 path->slots[level] = orig_slot;
311 tree_block_release(root, mid_buf);
313 orig_slot -= left->header.nritems;
314 path->slots[level] = orig_slot;
319 tree_block_release(root, right_buf);
321 tree_block_release(root, left_buf);
327 * look for key in the tree. path is filled in with nodes along the way
328 * if key is found, we return zero and you can find the item in the leaf
329 * level of the path (level 0)
331 * If the key isn't found, the path points to the slot where it should
332 * be inserted, and 1 is returned. If there are other errors during the
333 * search a negative error number is returned.
335 * if ins_len > 0, nodes and leaves will be split as we walk down the
336 * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if
339 int search_slot(struct ctree_root *root, struct key *key,
340 struct ctree_path *p, int ins_len)
342 struct tree_buffer *b;
353 level = node_level(c->header.flags);
355 ret = check_block(p, level);
358 ret = bin_search(c, key, &slot);
359 if (!is_leaf(c->header.flags)) {
362 p->slots[level] = slot;
364 c->header.nritems == NODEPTRS_PER_BLOCK) {
365 int sret = split_node(root, p, level);
371 slot = p->slots[level];
372 } else if (ins_len < 0) {
373 int sret = balance_level(root, p, level);
380 slot = p->slots[level];
382 b = read_tree_block(root, c->blockptrs[slot]);
384 struct leaf *l = (struct leaf *)c;
385 p->slots[level] = slot;
386 if (ins_len > 0 && leaf_free_space(l) <
387 sizeof(struct item) + ins_len) {
388 int sret = split_leaf(root, p, ins_len);
393 BUG_ON(root->node->count == 1);
397 BUG_ON(root->node->count == 1);
402 * adjust the pointers going up the tree, starting at level
403 * making sure the right key of each node is points to 'key'.
404 * This is used after shifting pointers to the left, so it stops
405 * fixing up pointers when a given leaf/node is not in slot 0 of the
408 * If this fails to write a tree block, it returns -1, but continues
409 * fixing up the blocks in ram so the tree is consistent.
411 static int fixup_low_keys(struct ctree_root *root,
412 struct ctree_path *path, struct key *key,
418 for (i = level; i < MAX_LEVEL; i++) {
420 int tslot = path->slots[i];
423 t = &path->nodes[i]->node;
424 memcpy(t->keys + tslot, key, sizeof(*key));
425 wret = write_tree_block(root, path->nodes[i]);
435 * try to push data from one node into the next node left in the
436 * tree. The src node is found at specified level in the path.
437 * If some bytes were pushed, return 0, otherwise return 1.
439 * Lower nodes/leaves in the path are not touched, higher nodes may
440 * be modified to reflect the push.
442 * The path is altered to reflect the push.
444 * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
445 * error, and > 0 if there was no room in the left hand block.
447 static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
448 struct tree_buffer *src_buf)
450 struct node *src = &src_buf->node;
451 struct node *dst = &dst_buf->node;
458 src_nritems = src->header.nritems;
459 dst_nritems = dst->header.nritems;
460 push_items = NODEPTRS_PER_BLOCK - dst_nritems;
461 if (push_items <= 0) {
465 if (src_nritems < push_items)
466 push_items =src_nritems;
467 memcpy(dst->keys + dst_nritems, src->keys,
468 push_items * sizeof(struct key));
469 memcpy(dst->blockptrs + dst_nritems, src->blockptrs,
470 push_items * sizeof(u64));
471 if (push_items < src_nritems) {
472 memmove(src->keys, src->keys + push_items,
473 (src_nritems - push_items) * sizeof(struct key));
474 memmove(src->blockptrs, src->blockptrs + push_items,
475 (src_nritems - push_items) * sizeof(u64));
477 src->header.nritems -= push_items;
478 dst->header.nritems += push_items;
480 wret = write_tree_block(root, src_buf);
484 wret = write_tree_block(root, dst_buf);
491 * helper function to insert a new root level in the tree.
492 * A new node is allocated, and a single item is inserted to
493 * point to the existing root
495 * returns zero on success or < 0 on failure.
497 static int insert_new_root(struct ctree_root *root,
498 struct ctree_path *path, int level)
500 struct tree_buffer *t;
503 struct key *lower_key;
505 BUG_ON(path->nodes[level]);
506 BUG_ON(path->nodes[level-1] != root->node);
508 t = alloc_free_block(root);
510 memset(c, 0, sizeof(c));
511 c->header.nritems = 1;
512 c->header.flags = node_level(level);
513 c->header.blocknr = t->blocknr;
514 c->header.parentid = root->node->node.header.parentid;
515 lower = &path->nodes[level-1]->node;
516 if (is_leaf(lower->header.flags))
517 lower_key = &((struct leaf *)lower)->items[0].key;
519 lower_key = lower->keys;
520 memcpy(c->keys, lower_key, sizeof(struct key));
521 c->blockptrs[0] = path->nodes[level-1]->blocknr;
522 /* the super has an extra ref to root->node */
523 tree_block_release(root, root->node);
526 write_tree_block(root, t);
527 path->nodes[level] = t;
528 path->slots[level] = 0;
533 * worker function to insert a single pointer in a node.
534 * the node should have enough room for the pointer already
536 * slot and level indicate where you want the key to go, and
537 * blocknr is the block the key points to.
539 * returns zero on success and < 0 on any error
541 static int insert_ptr(struct ctree_root *root,
542 struct ctree_path *path, struct key *key,
543 u64 blocknr, int slot, int level)
548 BUG_ON(!path->nodes[level]);
549 lower = &path->nodes[level]->node;
550 nritems = lower->header.nritems;
553 if (nritems == NODEPTRS_PER_BLOCK)
555 if (slot != nritems) {
556 memmove(lower->keys + slot + 1, lower->keys + slot,
557 (nritems - slot) * sizeof(struct key));
558 memmove(lower->blockptrs + slot + 1, lower->blockptrs + slot,
559 (nritems - slot) * sizeof(u64));
561 memcpy(lower->keys + slot, key, sizeof(struct key));
562 lower->blockptrs[slot] = blocknr;
563 lower->header.nritems++;
564 if (lower->keys[1].objectid == 0)
566 write_tree_block(root, path->nodes[level]);
571 * split the node at the specified level in path in two.
572 * The path is corrected to point to the appropriate node after the split
574 * Before splitting this tries to make some room in the node by pushing
575 * left and right, if either one works, it returns right away.
577 * returns 0 on success and < 0 on failure
579 static int split_node(struct ctree_root *root, struct ctree_path *path,
582 struct tree_buffer *t;
584 struct tree_buffer *split_buffer;
590 t = path->nodes[level];
592 if (t == root->node) {
593 /* trying to split the root, lets make a new one */
594 ret = insert_new_root(root, path, level + 1);
598 split_buffer = alloc_free_block(root);
599 split = &split_buffer->node;
600 split->header.flags = c->header.flags;
601 split->header.blocknr = split_buffer->blocknr;
602 split->header.parentid = root->node->node.header.parentid;
603 mid = (c->header.nritems + 1) / 2;
604 memcpy(split->keys, c->keys + mid,
605 (c->header.nritems - mid) * sizeof(struct key));
606 memcpy(split->blockptrs, c->blockptrs + mid,
607 (c->header.nritems - mid) * sizeof(u64));
608 split->header.nritems = c->header.nritems - mid;
609 c->header.nritems = mid;
612 wret = write_tree_block(root, t);
615 wret = write_tree_block(root, split_buffer);
618 wret = insert_ptr(root, path, split->keys, split_buffer->blocknr,
619 path->slots[level + 1] + 1, level + 1);
623 if (path->slots[level] >= mid) {
624 path->slots[level] -= mid;
625 tree_block_release(root, t);
626 path->nodes[level] = split_buffer;
627 path->slots[level + 1] += 1;
629 tree_block_release(root, split_buffer);
635 * how many bytes are required to store the items in a leaf. start
636 * and nr indicate which items in the leaf to check. This totals up the
637 * space used both by the item structs and the item data
639 static int leaf_space_used(struct leaf *l, int start, int nr)
642 int end = start + nr - 1;
646 data_len = l->items[start].offset + l->items[start].size;
647 data_len = data_len - l->items[end].offset;
648 data_len += sizeof(struct item) * nr;
653 * push some data in the path leaf to the right, trying to free up at
654 * least data_size bytes. returns zero if the push worked, nonzero otherwise
656 * returns 1 if the push failed because the other node didn't have enough
657 * room, 0 if everything worked out and < 0 if there were major errors.
659 static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
662 struct tree_buffer *left_buf = path->nodes[0];
663 struct leaf *left = &left_buf->leaf;
665 struct tree_buffer *right_buf;
666 struct tree_buffer *upper;
674 slot = path->slots[1];
675 if (!path->nodes[1]) {
678 upper = path->nodes[1];
679 if (slot >= upper->node.header.nritems - 1) {
682 right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]);
683 right = &right_buf->leaf;
684 free_space = leaf_free_space(right);
685 if (free_space < data_size + sizeof(struct item)) {
686 tree_block_release(root, right_buf);
689 for (i = left->header.nritems - 1; i >= 0; i--) {
690 item = left->items + i;
691 if (path->slots[0] == i)
692 push_space += data_size + sizeof(*item);
693 if (item->size + sizeof(*item) + push_space > free_space)
696 push_space += item->size + sizeof(*item);
698 if (push_items == 0) {
699 tree_block_release(root, right_buf);
702 /* push left to right */
703 push_space = left->items[left->header.nritems - push_items].offset +
704 left->items[left->header.nritems - push_items].size;
705 push_space -= leaf_data_end(left);
706 /* make room in the right data area */
707 memmove(right->data + leaf_data_end(right) - push_space,
708 right->data + leaf_data_end(right),
709 LEAF_DATA_SIZE - leaf_data_end(right));
710 /* copy from the left data area */
711 memcpy(right->data + LEAF_DATA_SIZE - push_space,
712 left->data + leaf_data_end(left),
714 memmove(right->items + push_items, right->items,
715 right->header.nritems * sizeof(struct item));
716 /* copy the items from left to right */
717 memcpy(right->items, left->items + left->header.nritems - push_items,
718 push_items * sizeof(struct item));
720 /* update the item pointers */
721 right->header.nritems += push_items;
722 push_space = LEAF_DATA_SIZE;
723 for (i = 0; i < right->header.nritems; i++) {
724 right->items[i].offset = push_space - right->items[i].size;
725 push_space = right->items[i].offset;
727 left->header.nritems -= push_items;
729 write_tree_block(root, left_buf);
730 write_tree_block(root, right_buf);
731 memcpy(upper->node.keys + slot + 1,
732 &right->items[0].key, sizeof(struct key));
733 write_tree_block(root, upper);
734 /* then fixup the leaf pointer in the path */
735 if (path->slots[0] >= left->header.nritems) {
736 path->slots[0] -= left->header.nritems;
737 tree_block_release(root, path->nodes[0]);
738 path->nodes[0] = right_buf;
741 tree_block_release(root, right_buf);
746 * push some data in the path leaf to the left, trying to free up at
747 * least data_size bytes. returns zero if the push worked, nonzero otherwise
749 static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
752 struct tree_buffer *right_buf = path->nodes[0];
753 struct leaf *right = &right_buf->leaf;
754 struct tree_buffer *t;
762 int old_left_nritems;
766 slot = path->slots[1];
770 if (!path->nodes[1]) {
773 t = read_tree_block(root, path->nodes[1]->node.blockptrs[slot - 1]);
775 free_space = leaf_free_space(left);
776 if (free_space < data_size + sizeof(struct item)) {
777 tree_block_release(root, t);
780 for (i = 0; i < right->header.nritems; i++) {
781 item = right->items + i;
782 if (path->slots[0] == i)
783 push_space += data_size + sizeof(*item);
784 if (item->size + sizeof(*item) + push_space > free_space)
787 push_space += item->size + sizeof(*item);
789 if (push_items == 0) {
790 tree_block_release(root, t);
793 /* push data from right to left */
794 memcpy(left->items + left->header.nritems,
795 right->items, push_items * sizeof(struct item));
796 push_space = LEAF_DATA_SIZE - right->items[push_items -1].offset;
797 memcpy(left->data + leaf_data_end(left) - push_space,
798 right->data + right->items[push_items - 1].offset,
800 old_left_nritems = left->header.nritems;
801 BUG_ON(old_left_nritems < 0);
803 for(i = old_left_nritems; i < old_left_nritems + push_items; i++) {
804 left->items[i].offset -= LEAF_DATA_SIZE -
805 left->items[old_left_nritems -1].offset;
807 left->header.nritems += push_items;
809 /* fixup right node */
810 push_space = right->items[push_items-1].offset - leaf_data_end(right);
811 memmove(right->data + LEAF_DATA_SIZE - push_space, right->data +
812 leaf_data_end(right), push_space);
813 memmove(right->items, right->items + push_items,
814 (right->header.nritems - push_items) * sizeof(struct item));
815 right->header.nritems -= push_items;
816 push_space = LEAF_DATA_SIZE;
818 for (i = 0; i < right->header.nritems; i++) {
819 right->items[i].offset = push_space - right->items[i].size;
820 push_space = right->items[i].offset;
823 wret = write_tree_block(root, t);
826 wret = write_tree_block(root, right_buf);
830 wret = fixup_low_keys(root, path, &right->items[0].key, 1);
834 /* then fixup the leaf pointer in the path */
835 if (path->slots[0] < push_items) {
836 path->slots[0] += old_left_nritems;
837 tree_block_release(root, path->nodes[0]);
841 tree_block_release(root, t);
842 path->slots[0] -= push_items;
844 BUG_ON(path->slots[0] < 0);
849 * split the path's leaf in two, making sure there is at least data_size
850 * available for the resulting leaf level of the path.
852 * returns 0 if all went well and < 0 on failure.
854 static int split_leaf(struct ctree_root *root, struct ctree_path *path,
857 struct tree_buffer *l_buf;
863 struct tree_buffer *right_buffer;
864 int space_needed = data_size + sizeof(struct item);
871 wret = push_leaf_left(root, path, data_size);
875 wret = push_leaf_right(root, path, data_size);
879 l_buf = path->nodes[0];
882 /* did the pushes work? */
883 if (leaf_free_space(l) >= sizeof(struct item) + data_size)
886 if (!path->nodes[1]) {
887 ret = insert_new_root(root, path, 1);
891 slot = path->slots[0];
892 nritems = l->header.nritems;
893 mid = (nritems + 1)/ 2;
895 right_buffer = alloc_free_block(root);
896 BUG_ON(!right_buffer);
897 BUG_ON(mid == nritems);
898 right = &right_buffer->leaf;
899 memset(right, 0, sizeof(*right));
901 /* FIXME, just alloc a new leaf here */
902 if (leaf_space_used(l, mid, nritems - mid) + space_needed >
906 /* FIXME, just alloc a new leaf here */
907 if (leaf_space_used(l, 0, mid + 1) + space_needed >
911 right->header.nritems = nritems - mid;
912 right->header.blocknr = right_buffer->blocknr;
913 right->header.flags = node_level(0);
914 right->header.parentid = root->node->node.header.parentid;
915 data_copy_size = l->items[mid].offset + l->items[mid].size -
917 memcpy(right->items, l->items + mid,
918 (nritems - mid) * sizeof(struct item));
919 memcpy(right->data + LEAF_DATA_SIZE - data_copy_size,
920 l->data + leaf_data_end(l), data_copy_size);
921 rt_data_off = LEAF_DATA_SIZE -
922 (l->items[mid].offset + l->items[mid].size);
924 for (i = 0; i < right->header.nritems; i++)
925 right->items[i].offset += rt_data_off;
927 l->header.nritems = mid;
929 wret = insert_ptr(root, path, &right->items[0].key,
930 right_buffer->blocknr, path->slots[1] + 1, 1);
933 wret = write_tree_block(root, right_buffer);
936 wret = write_tree_block(root, l_buf);
940 BUG_ON(path->slots[0] != slot);
942 tree_block_release(root, path->nodes[0]);
943 path->nodes[0] = right_buffer;
944 path->slots[0] -= mid;
947 tree_block_release(root, right_buffer);
948 BUG_ON(path->slots[0] < 0);
953 * Given a key and some data, insert an item into the tree.
954 * This does all the path init required, making room in the tree if needed.
956 int insert_item(struct ctree_root *root, struct key *key,
957 void *data, int data_size)
964 struct tree_buffer *leaf_buf;
965 unsigned int nritems;
966 unsigned int data_end;
967 struct ctree_path path;
969 /* create a root if there isn't one */
973 ret = search_slot(root, key, &path, data_size);
975 release_path(root, &path);
979 release_path(root, &path);
983 slot_orig = path.slots[0];
984 leaf_buf = path.nodes[0];
985 leaf = &leaf_buf->leaf;
987 nritems = leaf->header.nritems;
988 data_end = leaf_data_end(leaf);
990 if (leaf_free_space(leaf) < sizeof(struct item) + data_size)
993 slot = path.slots[0];
995 if (slot != nritems) {
997 unsigned int old_data = leaf->items[slot].offset +
998 leaf->items[slot].size;
1001 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1003 /* first correct the data pointers */
1004 for (i = slot; i < nritems; i++)
1005 leaf->items[i].offset -= data_size;
1007 /* shift the items */
1008 memmove(leaf->items + slot + 1, leaf->items + slot,
1009 (nritems - slot) * sizeof(struct item));
1011 /* shift the data */
1012 memmove(leaf->data + data_end - data_size, leaf->data +
1013 data_end, old_data - data_end);
1014 data_end = old_data;
1016 /* copy the new data in */
1017 memcpy(&leaf->items[slot].key, key, sizeof(struct key));
1018 leaf->items[slot].offset = data_end - data_size;
1019 leaf->items[slot].size = data_size;
1020 memcpy(leaf->data + data_end - data_size, data, data_size);
1021 leaf->header.nritems += 1;
1025 ret = fixup_low_keys(root, &path, key, 1);
1027 wret = write_tree_block(root, leaf_buf);
1031 if (leaf_free_space(leaf) < 0)
1033 check_leaf(&path, 0);
1034 release_path(root, &path);
1039 * delete the pointer from a given node.
1041 * If the delete empties a node, the node is removed from the tree,
1042 * continuing all the way the root if required. The root is converted into
1043 * a leaf if all the nodes are emptied.
1045 static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
1049 struct tree_buffer *parent = path->nodes[level];
1054 node = &parent->node;
1055 nritems = node->header.nritems;
1057 if (slot != nritems -1) {
1058 memmove(node->keys + slot, node->keys + slot + 1,
1059 sizeof(struct key) * (nritems - slot - 1));
1060 memmove(node->blockptrs + slot,
1061 node->blockptrs + slot + 1,
1062 sizeof(u64) * (nritems - slot - 1));
1064 node->header.nritems--;
1065 if (node->header.nritems == 0 && parent == root->node) {
1066 BUG_ON(node_level(root->node->node.header.flags) != 1);
1067 /* just turn the root into a leaf and break */
1068 root->node->node.header.flags = node_level(0);
1069 } else if (slot == 0) {
1070 wret = fixup_low_keys(root, path, node->keys, level + 1);
1074 wret = write_tree_block(root, parent);
1081 * delete the item at the leaf level in path. If that empties
1082 * the leaf, remove it from the tree
1084 int del_item(struct ctree_root *root, struct ctree_path *path)
1088 struct tree_buffer *leaf_buf;
1094 leaf_buf = path->nodes[0];
1095 leaf = &leaf_buf->leaf;
1096 slot = path->slots[0];
1097 doff = leaf->items[slot].offset;
1098 dsize = leaf->items[slot].size;
1100 if (slot != leaf->header.nritems - 1) {
1102 int data_end = leaf_data_end(leaf);
1103 memmove(leaf->data + data_end + dsize,
1104 leaf->data + data_end,
1106 for (i = slot + 1; i < leaf->header.nritems; i++)
1107 leaf->items[i].offset += dsize;
1108 memmove(leaf->items + slot, leaf->items + slot + 1,
1109 sizeof(struct item) *
1110 (leaf->header.nritems - slot - 1));
1112 leaf->header.nritems -= 1;
1113 /* delete the leaf if we've emptied it */
1114 if (leaf->header.nritems == 0) {
1115 if (leaf_buf == root->node) {
1116 leaf->header.flags = node_level(0);
1117 write_tree_block(root, leaf_buf);
1119 wret = del_ptr(root, path, 1, path->slots[1]);
1122 wret = free_extent(root, leaf_buf->blocknr, 1);
1127 int used = leaf_space_used(leaf, 0, leaf->header.nritems);
1129 wret = fixup_low_keys(root, path,
1130 &leaf->items[0].key, 1);
1134 wret = write_tree_block(root, leaf_buf);
1138 /* delete the leaf if it is mostly empty */
1139 if (used < LEAF_DATA_SIZE / 3) {
1140 /* push_leaf_left fixes the path.
1141 * make sure the path still points to our leaf
1142 * for possible call to del_ptr below
1144 slot = path->slots[1];
1146 wret = push_leaf_left(root, path, 1);
1149 if (leaf->header.nritems) {
1150 wret = push_leaf_right(root, path, 1);
1154 if (leaf->header.nritems == 0) {
1155 u64 blocknr = leaf_buf->blocknr;
1156 wret = del_ptr(root, path, 1, slot);
1159 tree_block_release(root, leaf_buf);
1160 wret = free_extent(root, blocknr, 1);
1164 tree_block_release(root, leaf_buf);
1172 * walk up the tree as far as required to find the next leaf.
1173 * returns 0 if it found something or 1 if there are no greater leaves.
1174 * returns < 0 on io errors.
1176 int next_leaf(struct ctree_root *root, struct ctree_path *path)
1181 struct tree_buffer *c;
1182 struct tree_buffer *next = NULL;
1184 while(level < MAX_LEVEL) {
1185 if (!path->nodes[level])
1187 slot = path->slots[level] + 1;
1188 c = path->nodes[level];
1189 if (slot >= c->node.header.nritems) {
1193 blocknr = c->node.blockptrs[slot];
1195 tree_block_release(root, next);
1196 next = read_tree_block(root, blocknr);
1199 path->slots[level] = slot;
1202 c = path->nodes[level];
1203 tree_block_release(root, c);
1204 path->nodes[level] = next;
1205 path->slots[level] = 0;
1208 next = read_tree_block(root, next->node.blockptrs[0]);