+/*
+ * worker function to insert a single pointer in a node.
+ * the node should have enough room for the pointer already
+ * slot and level indicate where you want the key to go, and
+ * blocknr is the block the key points to.
+ */
+int __insert_ptr(struct ctree_root *root,
+ struct ctree_path *path, struct key *key,
+ u64 blocknr, int slot, int level)
+{
+ struct node *c;
+ struct node *lower;
+ struct key *lower_key;
+ int nritems;
+ /* need a new root */
+ if (!path->nodes[level]) {
+ struct tree_buffer *t;
+ t = alloc_free_block(root);
+ c = &t->node;
+ memset(c, 0, sizeof(c));
+ c->header.nritems = 2;
+ c->header.flags = node_level(level);
+ c->header.blocknr = t->blocknr;
+ lower = &path->nodes[level-1]->node;
+ if (is_leaf(lower->header.flags))
+ lower_key = &((struct leaf *)lower)->items[0].key;
+ else
+ lower_key = lower->keys;
+ memcpy(c->keys, lower_key, sizeof(struct key));
+ memcpy(c->keys + 1, key, sizeof(struct key));
+ c->blockptrs[0] = path->nodes[level-1]->blocknr;
+ c->blockptrs[1] = blocknr;
+ /* the path has an extra ref to root->node */
+ tree_block_release(root, root->node);
+ root->node = t;
+ t->count++;
+ write_tree_block(root, t);
+ path->nodes[level] = t;
+ path->slots[level] = 0;
+ if (c->keys[1].objectid == 0)
+ BUG();
+ return 0;
+ }
+ lower = &path->nodes[level]->node;
+ nritems = lower->header.nritems;
+ if (slot > nritems)
+ BUG();
+ if (nritems == NODEPTRS_PER_BLOCK)
+ BUG();
+ if (slot != nritems) {
+ memmove(lower->keys + slot + 1, lower->keys + slot,
+ (nritems - slot) * sizeof(struct key));
+ memmove(lower->blockptrs + slot + 1, lower->blockptrs + slot,
+ (nritems - slot) * sizeof(u64));
+ }
+ memcpy(lower->keys + slot, key, sizeof(struct key));
+ lower->blockptrs[slot] = blocknr;
+ lower->header.nritems++;
+ if (lower->keys[1].objectid == 0)
+ BUG();
+ write_tree_block(root, path->nodes[level]);
+ return 0;
+}
+
+
+/*
+ * insert a key,blocknr pair into the tree at a given level
+ * If the node at that level in the path doesn't have room,
+ * it is split or shifted as appropriate.
+ */