12e635a27SChris Mason #include <linux/module.h> 2eb60ceacSChris Mason #include "ctree.h" 3eb60ceacSChris Mason #include "disk-io.h" 47f5c1516SChris Mason #include "transaction.h" 59a8dd150SChris Mason 6e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 7e089f05cSChris Mason *root, struct btrfs_path *path, int level); 8e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 9d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 10d4dbff95SChris Mason struct btrfs_path *path, int data_size); 11e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 12e20d96d6SChris Mason *root, struct buffer_head *dst, struct buffer_head 13e089f05cSChris Mason *src); 14e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 15e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 16e20d96d6SChris Mason struct buffer_head *src_buf); 17e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 18e089f05cSChris Mason struct btrfs_path *path, int level, int slot); 19d97e63b6SChris Mason 20df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p) 21df24a2b9SChris Mason { 22df24a2b9SChris Mason memset(p, 0, sizeof(*p)); 23df24a2b9SChris Mason } 24df24a2b9SChris Mason 252c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void) 262c90e5d6SChris Mason { 27df24a2b9SChris Mason struct btrfs_path *path; 28df24a2b9SChris Mason path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); 29df24a2b9SChris Mason if (path) 30df24a2b9SChris Mason btrfs_init_path(path); 31df24a2b9SChris Mason return path; 322c90e5d6SChris Mason } 332c90e5d6SChris Mason 342c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p) 352c90e5d6SChris Mason { 36df24a2b9SChris Mason btrfs_release_path(NULL, p); 372c90e5d6SChris Mason kmem_cache_free(btrfs_path_cachep, p); 382c90e5d6SChris Mason } 392c90e5d6SChris Mason 40234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) 41eb60ceacSChris Mason { 42eb60ceacSChris Mason int i; 43234b63a0SChris Mason for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 44eb60ceacSChris Mason if (!p->nodes[i]) 45eb60ceacSChris Mason break; 46234b63a0SChris Mason btrfs_block_release(root, p->nodes[i]); 47eb60ceacSChris Mason } 48aa5d6bedSChris Mason memset(p, 0, sizeof(*p)); 49eb60ceacSChris Mason } 50eb60ceacSChris Mason 51e089f05cSChris Mason static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 52e20d96d6SChris Mason *root, struct buffer_head *buf, struct buffer_head 53e20d96d6SChris Mason *parent, int parent_slot, struct buffer_head 54e089f05cSChris Mason **cow_ret) 5502217ed2SChris Mason { 56e20d96d6SChris Mason struct buffer_head *cow; 57e20d96d6SChris Mason struct btrfs_node *cow_node; 5802217ed2SChris Mason 597f5c1516SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) == 607f5c1516SChris Mason trans->transid) { 6102217ed2SChris Mason *cow_ret = buf; 6202217ed2SChris Mason return 0; 6302217ed2SChris Mason } 64e089f05cSChris Mason cow = btrfs_alloc_free_block(trans, root); 65e20d96d6SChris Mason cow_node = btrfs_buffer_node(cow); 662c90e5d6SChris Mason if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) 672c90e5d6SChris Mason WARN_ON(1); 68e20d96d6SChris Mason memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 697eccb903SChris Mason btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); 707f5c1516SChris Mason btrfs_set_header_generation(&cow_node->header, trans->transid); 71e089f05cSChris Mason btrfs_inc_ref(trans, root, buf); 7202217ed2SChris Mason if (buf == root->node) { 7302217ed2SChris Mason root->node = cow; 74e20d96d6SChris Mason get_bh(cow); 752c90e5d6SChris Mason if (buf != root->commit_root) { 767eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 772c90e5d6SChris Mason } 78234b63a0SChris Mason btrfs_block_release(root, buf); 7902217ed2SChris Mason } else { 80e20d96d6SChris Mason btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 817eccb903SChris Mason bh_blocknr(cow)); 82d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 837eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 8402217ed2SChris Mason } 85234b63a0SChris Mason btrfs_block_release(root, buf); 86df24a2b9SChris Mason mark_buffer_dirty(cow); 872c90e5d6SChris Mason *cow_ret = cow; 8802217ed2SChris Mason return 0; 8902217ed2SChris Mason } 9002217ed2SChris Mason 9174123bd7SChris Mason /* 9274123bd7SChris Mason * The leaf data grows from end-to-front in the node. 9374123bd7SChris Mason * this returns the address of the start of the last item, 9474123bd7SChris Mason * which is the stop of the leaf data stack 9574123bd7SChris Mason */ 96123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 97123abc88SChris Mason struct btrfs_leaf *leaf) 98be0e5c09SChris Mason { 997518a238SChris Mason u32 nr = btrfs_header_nritems(&leaf->header); 100be0e5c09SChris Mason if (nr == 0) 101123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 1020783fcfcSChris Mason return btrfs_item_offset(leaf->items + nr - 1); 103be0e5c09SChris Mason } 104be0e5c09SChris Mason 10574123bd7SChris Mason /* 10674123bd7SChris Mason * compare two keys in a memcmp fashion 10774123bd7SChris Mason */ 1089aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 109be0e5c09SChris Mason { 110e2fa7227SChris Mason struct btrfs_key k1; 111e2fa7227SChris Mason 112e2fa7227SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 113e2fa7227SChris Mason 114e2fa7227SChris Mason if (k1.objectid > k2->objectid) 115be0e5c09SChris Mason return 1; 116e2fa7227SChris Mason if (k1.objectid < k2->objectid) 117be0e5c09SChris Mason return -1; 118f254e52cSChris Mason if (k1.flags > k2->flags) 119f254e52cSChris Mason return 1; 120f254e52cSChris Mason if (k1.flags < k2->flags) 121f254e52cSChris Mason return -1; 12270b2befdSChris Mason if (k1.offset > k2->offset) 12370b2befdSChris Mason return 1; 12470b2befdSChris Mason if (k1.offset < k2->offset) 12570b2befdSChris Mason return -1; 126be0e5c09SChris Mason return 0; 127be0e5c09SChris Mason } 12874123bd7SChris Mason 129123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 130123abc88SChris Mason int level) 131aa5d6bedSChris Mason { 132aa5d6bedSChris Mason int i; 133234b63a0SChris Mason struct btrfs_node *parent = NULL; 134e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 135aa5d6bedSChris Mason int parent_slot; 1367518a238SChris Mason u32 nritems = btrfs_header_nritems(&node->header); 137aa5d6bedSChris Mason 138aa5d6bedSChris Mason if (path->nodes[level + 1]) 139e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 140aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 1417518a238SChris Mason BUG_ON(nritems == 0); 1427518a238SChris Mason if (parent) { 143e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 144123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 145123abc88SChris Mason BUG_ON(memcmp(parent_key, &node->ptrs[0].key, 146e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1471d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1487518a238SChris Mason btrfs_header_blocknr(&node->header)); 149aa5d6bedSChris Mason } 150123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 1517518a238SChris Mason for (i = 0; nritems > 1 && i < nritems - 2; i++) { 152e2fa7227SChris Mason struct btrfs_key cpukey; 153123abc88SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[i + 1].key); 154*e66f709bSChris Mason if (comp_keys(&node->ptrs[i].key, &cpukey) >= 0) { 155*e66f709bSChris Mason struct btrfs_key bad; 156*e66f709bSChris Mason btrfs_disk_key_to_cpu(&bad, &node->ptrs[i].key); 157*e66f709bSChris Mason printk("check_node level %d i is %d bad comp %Lu %u %Lu, %Lu %u %Lu\n",level, i, bad.objectid, bad.flags, bad.offset, cpukey.objectid, cpukey.flags, cpukey.offset); 158*e66f709bSChris Mason } 159123abc88SChris Mason BUG_ON(comp_keys(&node->ptrs[i].key, &cpukey) >= 0); 160aa5d6bedSChris Mason } 161aa5d6bedSChris Mason return 0; 162aa5d6bedSChris Mason } 163aa5d6bedSChris Mason 164123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 165123abc88SChris Mason int level) 166aa5d6bedSChris Mason { 167aa5d6bedSChris Mason int i; 168e20d96d6SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); 169234b63a0SChris Mason struct btrfs_node *parent = NULL; 170aa5d6bedSChris Mason int parent_slot; 1717518a238SChris Mason u32 nritems = btrfs_header_nritems(&leaf->header); 172aa5d6bedSChris Mason 173aa5d6bedSChris Mason if (path->nodes[level + 1]) 174e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 175aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 176123abc88SChris Mason BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 1777518a238SChris Mason 1787518a238SChris Mason if (nritems == 0) 1797518a238SChris Mason return 0; 1807518a238SChris Mason 1817518a238SChris Mason if (parent) { 182e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 183123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 184aa5d6bedSChris Mason BUG_ON(memcmp(parent_key, &leaf->items[0].key, 185e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1861d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1877518a238SChris Mason btrfs_header_blocknr(&leaf->header)); 188aa5d6bedSChris Mason } 1897518a238SChris Mason for (i = 0; nritems > 1 && i < nritems - 2; i++) { 190e2fa7227SChris Mason struct btrfs_key cpukey; 191e2fa7227SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key); 192aa5d6bedSChris Mason BUG_ON(comp_keys(&leaf->items[i].key, 193e2fa7227SChris Mason &cpukey) >= 0); 1940783fcfcSChris Mason BUG_ON(btrfs_item_offset(leaf->items + i) != 1950783fcfcSChris Mason btrfs_item_end(leaf->items + i + 1)); 196aa5d6bedSChris Mason if (i == 0) { 1970783fcfcSChris Mason BUG_ON(btrfs_item_offset(leaf->items + i) + 1980783fcfcSChris Mason btrfs_item_size(leaf->items + i) != 199123abc88SChris Mason BTRFS_LEAF_DATA_SIZE(root)); 200aa5d6bedSChris Mason } 201aa5d6bedSChris Mason } 202aa5d6bedSChris Mason return 0; 203aa5d6bedSChris Mason } 204aa5d6bedSChris Mason 205123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 206123abc88SChris Mason int level) 207aa5d6bedSChris Mason { 2083eb0314dSChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 2093eb0314dSChris Mason if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, 2103eb0314dSChris Mason sizeof(node->header.fsid))) 2113eb0314dSChris Mason BUG(); 212aa5d6bedSChris Mason if (level == 0) 213123abc88SChris Mason return check_leaf(root, path, level); 214123abc88SChris Mason return check_node(root, path, level); 215aa5d6bedSChris Mason } 216aa5d6bedSChris Mason 21774123bd7SChris Mason /* 21874123bd7SChris Mason * search for key in the array p. items p are item_size apart 21974123bd7SChris Mason * and there are 'max' items in p 22074123bd7SChris Mason * the slot in the array is returned via slot, and it points to 22174123bd7SChris Mason * the place where you would insert key if it is not found in 22274123bd7SChris Mason * the array. 22374123bd7SChris Mason * 22474123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 22574123bd7SChris Mason */ 2269aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, 227be0e5c09SChris Mason int max, int *slot) 228be0e5c09SChris Mason { 229be0e5c09SChris Mason int low = 0; 230be0e5c09SChris Mason int high = max; 231be0e5c09SChris Mason int mid; 232be0e5c09SChris Mason int ret; 233e2fa7227SChris Mason struct btrfs_disk_key *tmp; 234be0e5c09SChris Mason 235be0e5c09SChris Mason while(low < high) { 236be0e5c09SChris Mason mid = (low + high) / 2; 237e2fa7227SChris Mason tmp = (struct btrfs_disk_key *)(p + mid * item_size); 238be0e5c09SChris Mason ret = comp_keys(tmp, key); 239be0e5c09SChris Mason 240be0e5c09SChris Mason if (ret < 0) 241be0e5c09SChris Mason low = mid + 1; 242be0e5c09SChris Mason else if (ret > 0) 243be0e5c09SChris Mason high = mid; 244be0e5c09SChris Mason else { 245be0e5c09SChris Mason *slot = mid; 246be0e5c09SChris Mason return 0; 247be0e5c09SChris Mason } 248be0e5c09SChris Mason } 249be0e5c09SChris Mason *slot = low; 250be0e5c09SChris Mason return 1; 251be0e5c09SChris Mason } 252be0e5c09SChris Mason 25397571fd0SChris Mason /* 25497571fd0SChris Mason * simple bin_search frontend that does the right thing for 25597571fd0SChris Mason * leaves vs nodes 25697571fd0SChris Mason */ 2579aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) 258be0e5c09SChris Mason { 2597518a238SChris Mason if (btrfs_is_leaf(c)) { 260234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 2610783fcfcSChris Mason return generic_bin_search((void *)l->items, 2620783fcfcSChris Mason sizeof(struct btrfs_item), 2637518a238SChris Mason key, btrfs_header_nritems(&c->header), 2647518a238SChris Mason slot); 265be0e5c09SChris Mason } else { 266123abc88SChris Mason return generic_bin_search((void *)c->ptrs, 267123abc88SChris Mason sizeof(struct btrfs_key_ptr), 2687518a238SChris Mason key, btrfs_header_nritems(&c->header), 2697518a238SChris Mason slot); 270be0e5c09SChris Mason } 271be0e5c09SChris Mason return -1; 272be0e5c09SChris Mason } 273be0e5c09SChris Mason 274e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root, 275e20d96d6SChris Mason struct buffer_head *parent_buf, 276bb803951SChris Mason int slot) 277bb803951SChris Mason { 278e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(parent_buf); 279bb803951SChris Mason if (slot < 0) 280bb803951SChris Mason return NULL; 2817518a238SChris Mason if (slot >= btrfs_header_nritems(&node->header)) 282bb803951SChris Mason return NULL; 2831d4f8a0cSChris Mason return read_tree_block(root, btrfs_node_blockptr(node, slot)); 284bb803951SChris Mason } 285bb803951SChris Mason 286e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 287e089f05cSChris Mason *root, struct btrfs_path *path, int level) 288bb803951SChris Mason { 289e20d96d6SChris Mason struct buffer_head *right_buf; 290e20d96d6SChris Mason struct buffer_head *mid_buf; 291e20d96d6SChris Mason struct buffer_head *left_buf; 292e20d96d6SChris Mason struct buffer_head *parent_buf = NULL; 293234b63a0SChris Mason struct btrfs_node *right = NULL; 294234b63a0SChris Mason struct btrfs_node *mid; 295234b63a0SChris Mason struct btrfs_node *left = NULL; 296234b63a0SChris Mason struct btrfs_node *parent = NULL; 297bb803951SChris Mason int ret = 0; 298bb803951SChris Mason int wret; 299bb803951SChris Mason int pslot; 300bb803951SChris Mason int orig_slot = path->slots[level]; 30179f95c82SChris Mason u64 orig_ptr; 302bb803951SChris Mason 303bb803951SChris Mason if (level == 0) 304bb803951SChris Mason return 0; 305bb803951SChris Mason 306bb803951SChris Mason mid_buf = path->nodes[level]; 307e20d96d6SChris Mason mid = btrfs_buffer_node(mid_buf); 3081d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 30979f95c82SChris Mason 310234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 311bb803951SChris Mason parent_buf = path->nodes[level + 1]; 312bb803951SChris Mason pslot = path->slots[level + 1]; 313bb803951SChris Mason 31440689478SChris Mason /* 31540689478SChris Mason * deal with the case where there is only one pointer in the root 31640689478SChris Mason * by promoting the node below to a root 31740689478SChris Mason */ 318bb803951SChris Mason if (!parent_buf) { 319e20d96d6SChris Mason struct buffer_head *child; 3207eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 321bb803951SChris Mason 3227518a238SChris Mason if (btrfs_header_nritems(&mid->header) != 1) 323bb803951SChris Mason return 0; 324bb803951SChris Mason 325bb803951SChris Mason /* promote the child to a root */ 326bb803951SChris Mason child = read_node_slot(root, mid_buf, 0); 327bb803951SChris Mason BUG_ON(!child); 328bb803951SChris Mason root->node = child; 329bb803951SChris Mason path->nodes[level] = NULL; 330d6025579SChris Mason clean_tree_block(trans, root, mid_buf); 331d6025579SChris Mason wait_on_buffer(mid_buf); 332bb803951SChris Mason /* once for the path */ 333234b63a0SChris Mason btrfs_block_release(root, mid_buf); 334bb803951SChris Mason /* once for the root ptr */ 335234b63a0SChris Mason btrfs_block_release(root, mid_buf); 336e089f05cSChris Mason return btrfs_free_extent(trans, root, blocknr, 1, 1); 337bb803951SChris Mason } 338e20d96d6SChris Mason parent = btrfs_buffer_node(parent_buf); 339bb803951SChris Mason 340123abc88SChris Mason if (btrfs_header_nritems(&mid->header) > 341123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 342bb803951SChris Mason return 0; 343bb803951SChris Mason 344bb803951SChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 345bb803951SChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 34679f95c82SChris Mason 34779f95c82SChris Mason /* first, try to make some room in the middle buffer */ 348bb803951SChris Mason if (left_buf) { 349e089f05cSChris Mason btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, 350e089f05cSChris Mason &left_buf); 351e20d96d6SChris Mason left = btrfs_buffer_node(left_buf); 3527518a238SChris Mason orig_slot += btrfs_header_nritems(&left->header); 353e089f05cSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 35479f95c82SChris Mason if (wret < 0) 35579f95c82SChris Mason ret = wret; 356bb803951SChris Mason } 35779f95c82SChris Mason 35879f95c82SChris Mason /* 35979f95c82SChris Mason * then try to empty the right most buffer into the middle 36079f95c82SChris Mason */ 361bb803951SChris Mason if (right_buf) { 362e089f05cSChris Mason btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, 363e089f05cSChris Mason &right_buf); 364e20d96d6SChris Mason right = btrfs_buffer_node(right_buf); 365e089f05cSChris Mason wret = push_node_left(trans, root, mid_buf, right_buf); 36679f95c82SChris Mason if (wret < 0) 36779f95c82SChris Mason ret = wret; 3687518a238SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 3697eccb903SChris Mason u64 blocknr = bh_blocknr(right_buf); 370e089f05cSChris Mason clean_tree_block(trans, root, right_buf); 371d6025579SChris Mason wait_on_buffer(right_buf); 372d6025579SChris Mason btrfs_block_release(root, right_buf); 373bb803951SChris Mason right_buf = NULL; 374bb803951SChris Mason right = NULL; 375e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 376e089f05cSChris Mason 1); 377bb803951SChris Mason if (wret) 378bb803951SChris Mason ret = wret; 379e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 380bb803951SChris Mason if (wret) 381bb803951SChris Mason ret = wret; 382bb803951SChris Mason } else { 383d6025579SChris Mason btrfs_memcpy(root, parent, 384d6025579SChris Mason &parent->ptrs[pslot + 1].key, 385123abc88SChris Mason &right->ptrs[0].key, 386e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 387d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 388bb803951SChris Mason } 389bb803951SChris Mason } 3907518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 1) { 39179f95c82SChris Mason /* 39279f95c82SChris Mason * we're not allowed to leave a node with one item in the 39379f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 39479f95c82SChris Mason * could try to delete the only pointer in this node. 39579f95c82SChris Mason * So, pull some keys from the left. 39679f95c82SChris Mason * There has to be a left pointer at this point because 39779f95c82SChris Mason * otherwise we would have pulled some pointers from the 39879f95c82SChris Mason * right 39979f95c82SChris Mason */ 40079f95c82SChris Mason BUG_ON(!left_buf); 401e089f05cSChris Mason wret = balance_node_right(trans, root, mid_buf, left_buf); 40279f95c82SChris Mason if (wret < 0) 40379f95c82SChris Mason ret = wret; 40479f95c82SChris Mason BUG_ON(wret == 1); 40579f95c82SChris Mason } 4067518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 0) { 40779f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 4087eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 409e089f05cSChris Mason clean_tree_block(trans, root, mid_buf); 410d6025579SChris Mason wait_on_buffer(mid_buf); 411d6025579SChris Mason btrfs_block_release(root, mid_buf); 412bb803951SChris Mason mid_buf = NULL; 413bb803951SChris Mason mid = NULL; 414e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 415bb803951SChris Mason if (wret) 416bb803951SChris Mason ret = wret; 417e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 418bb803951SChris Mason if (wret) 419bb803951SChris Mason ret = wret; 42079f95c82SChris Mason } else { 42179f95c82SChris Mason /* update the parent key to reflect our changes */ 422d6025579SChris Mason btrfs_memcpy(root, parent, 423d6025579SChris Mason &parent->ptrs[pslot].key, &mid->ptrs[0].key, 424e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 425d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 42679f95c82SChris Mason } 427bb803951SChris Mason 42879f95c82SChris Mason /* update the path */ 429bb803951SChris Mason if (left_buf) { 4307518a238SChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 431e20d96d6SChris Mason get_bh(left_buf); 432bb803951SChris Mason path->nodes[level] = left_buf; 433bb803951SChris Mason path->slots[level + 1] -= 1; 434bb803951SChris Mason path->slots[level] = orig_slot; 435bb803951SChris Mason if (mid_buf) 436234b63a0SChris Mason btrfs_block_release(root, mid_buf); 437bb803951SChris Mason } else { 4387518a238SChris Mason orig_slot -= btrfs_header_nritems(&left->header); 439bb803951SChris Mason path->slots[level] = orig_slot; 440bb803951SChris Mason } 441bb803951SChris Mason } 44279f95c82SChris Mason /* double check we haven't messed things up */ 443123abc88SChris Mason check_block(root, path, level); 444e20d96d6SChris Mason if (orig_ptr != 445e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 4461d4f8a0cSChris Mason path->slots[level])) 44779f95c82SChris Mason BUG(); 448bb803951SChris Mason 449bb803951SChris Mason if (right_buf) 450234b63a0SChris Mason btrfs_block_release(root, right_buf); 451bb803951SChris Mason if (left_buf) 452234b63a0SChris Mason btrfs_block_release(root, left_buf); 453bb803951SChris Mason return ret; 454bb803951SChris Mason } 455bb803951SChris Mason 456*e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 457*e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 458*e66f709bSChris Mason struct btrfs_root *root, 459*e66f709bSChris Mason struct btrfs_path *path, int level) 460*e66f709bSChris Mason { 461*e66f709bSChris Mason struct buffer_head *right_buf; 462*e66f709bSChris Mason struct buffer_head *mid_buf; 463*e66f709bSChris Mason struct buffer_head *left_buf; 464*e66f709bSChris Mason struct buffer_head *parent_buf = NULL; 465*e66f709bSChris Mason struct btrfs_node *right = NULL; 466*e66f709bSChris Mason struct btrfs_node *mid; 467*e66f709bSChris Mason struct btrfs_node *left = NULL; 468*e66f709bSChris Mason struct btrfs_node *parent = NULL; 469*e66f709bSChris Mason int ret = 0; 470*e66f709bSChris Mason int wret; 471*e66f709bSChris Mason int pslot; 472*e66f709bSChris Mason int orig_slot = path->slots[level]; 473*e66f709bSChris Mason u64 orig_ptr; 474*e66f709bSChris Mason 475*e66f709bSChris Mason if (level == 0) 476*e66f709bSChris Mason return 1; 477*e66f709bSChris Mason 478*e66f709bSChris Mason mid_buf = path->nodes[level]; 479*e66f709bSChris Mason mid = btrfs_buffer_node(mid_buf); 480*e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 481*e66f709bSChris Mason 482*e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 483*e66f709bSChris Mason parent_buf = path->nodes[level + 1]; 484*e66f709bSChris Mason pslot = path->slots[level + 1]; 485*e66f709bSChris Mason 486*e66f709bSChris Mason if (!parent_buf) 487*e66f709bSChris Mason return 1; 488*e66f709bSChris Mason parent = btrfs_buffer_node(parent_buf); 489*e66f709bSChris Mason 490*e66f709bSChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 491*e66f709bSChris Mason 492*e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 493*e66f709bSChris Mason if (left_buf) { 494*e66f709bSChris Mason u32 left_nr; 495*e66f709bSChris Mason btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, 496*e66f709bSChris Mason &left_buf); 497*e66f709bSChris Mason left = btrfs_buffer_node(left_buf); 498*e66f709bSChris Mason left_nr = btrfs_header_nritems(&left->header); 499*e66f709bSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 500*e66f709bSChris Mason if (wret < 0) 501*e66f709bSChris Mason ret = wret; 502*e66f709bSChris Mason if (wret == 0) { 503*e66f709bSChris Mason orig_slot += left_nr; 504*e66f709bSChris Mason btrfs_memcpy(root, parent, 505*e66f709bSChris Mason &parent->ptrs[pslot].key, 506*e66f709bSChris Mason &mid->ptrs[0].key, 507*e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 508*e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 509*e66f709bSChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 510*e66f709bSChris Mason path->nodes[level] = left_buf; 511*e66f709bSChris Mason path->slots[level + 1] -= 1; 512*e66f709bSChris Mason path->slots[level] = orig_slot; 513*e66f709bSChris Mason btrfs_block_release(root, mid_buf); 514*e66f709bSChris Mason } else { 515*e66f709bSChris Mason orig_slot -= 516*e66f709bSChris Mason btrfs_header_nritems(&left->header); 517*e66f709bSChris Mason path->slots[level] = orig_slot; 518*e66f709bSChris Mason btrfs_block_release(root, left_buf); 519*e66f709bSChris Mason } 520*e66f709bSChris Mason check_node(root, path, level); 521*e66f709bSChris Mason return 0; 522*e66f709bSChris Mason } 523*e66f709bSChris Mason btrfs_block_release(root, left_buf); 524*e66f709bSChris Mason } 525*e66f709bSChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 526*e66f709bSChris Mason 527*e66f709bSChris Mason /* 528*e66f709bSChris Mason * then try to empty the right most buffer into the middle 529*e66f709bSChris Mason */ 530*e66f709bSChris Mason if (right_buf) { 531*e66f709bSChris Mason btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, 532*e66f709bSChris Mason &right_buf); 533*e66f709bSChris Mason right = btrfs_buffer_node(right_buf); 534*e66f709bSChris Mason wret = balance_node_right(trans, root, right_buf, mid_buf); 535*e66f709bSChris Mason if (wret < 0) 536*e66f709bSChris Mason ret = wret; 537*e66f709bSChris Mason if (wret == 0) { 538*e66f709bSChris Mason btrfs_memcpy(root, parent, 539*e66f709bSChris Mason &parent->ptrs[pslot + 1].key, 540*e66f709bSChris Mason &right->ptrs[0].key, 541*e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 542*e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 543*e66f709bSChris Mason if (btrfs_header_nritems(&mid->header) <= orig_slot) { 544*e66f709bSChris Mason path->nodes[level] = right_buf; 545*e66f709bSChris Mason path->slots[level + 1] += 1; 546*e66f709bSChris Mason path->slots[level] = orig_slot - 547*e66f709bSChris Mason btrfs_header_nritems(&mid->header); 548*e66f709bSChris Mason btrfs_block_release(root, mid_buf); 549*e66f709bSChris Mason } else { 550*e66f709bSChris Mason btrfs_block_release(root, right_buf); 551*e66f709bSChris Mason } 552*e66f709bSChris Mason check_node(root, path, level); 553*e66f709bSChris Mason return 0; 554*e66f709bSChris Mason } 555*e66f709bSChris Mason btrfs_block_release(root, right_buf); 556*e66f709bSChris Mason } 557*e66f709bSChris Mason check_node(root, path, level); 558*e66f709bSChris Mason return 1; 559*e66f709bSChris Mason } 560*e66f709bSChris Mason 56174123bd7SChris Mason /* 56274123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 56374123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 56474123bd7SChris Mason * level of the path (level 0) 56574123bd7SChris Mason * 56674123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 567aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 568aa5d6bedSChris Mason * search a negative error number is returned. 56997571fd0SChris Mason * 57097571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 57197571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 57297571fd0SChris Mason * possible) 57374123bd7SChris Mason */ 574e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 575e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 576e089f05cSChris Mason ins_len, int cow) 577be0e5c09SChris Mason { 578e20d96d6SChris Mason struct buffer_head *b; 579e20d96d6SChris Mason struct buffer_head *cow_buf; 580234b63a0SChris Mason struct btrfs_node *c; 581be0e5c09SChris Mason int slot; 582be0e5c09SChris Mason int ret; 583be0e5c09SChris Mason int level; 5845c680ed6SChris Mason 58522b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 58622b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 587bb803951SChris Mason again: 588bb803951SChris Mason b = root->node; 589e20d96d6SChris Mason get_bh(b); 590eb60ceacSChris Mason while (b) { 591e20d96d6SChris Mason c = btrfs_buffer_node(b); 592e20d96d6SChris Mason level = btrfs_header_level(&c->header); 59302217ed2SChris Mason if (cow) { 59402217ed2SChris Mason int wret; 595e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 596e20d96d6SChris Mason p->nodes[level + 1], 597e20d96d6SChris Mason p->slots[level + 1], 598e089f05cSChris Mason &cow_buf); 59902217ed2SChris Mason b = cow_buf; 6002c90e5d6SChris Mason c = btrfs_buffer_node(b); 60102217ed2SChris Mason } 60202217ed2SChris Mason BUG_ON(!cow && ins_len); 6032c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 6042c90e5d6SChris Mason WARN_ON(1); 6052c90e5d6SChris Mason level = btrfs_header_level(&c->header); 606eb60ceacSChris Mason p->nodes[level] = b; 607123abc88SChris Mason ret = check_block(root, p, level); 608aa5d6bedSChris Mason if (ret) 609aa5d6bedSChris Mason return -1; 610be0e5c09SChris Mason ret = bin_search(c, key, &slot); 6117518a238SChris Mason if (!btrfs_is_leaf(c)) { 612be0e5c09SChris Mason if (ret && slot > 0) 613be0e5c09SChris Mason slot -= 1; 614be0e5c09SChris Mason p->slots[level] = slot; 615d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 616d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 617e089f05cSChris Mason int sret = split_node(trans, root, p, level); 6185c680ed6SChris Mason BUG_ON(sret > 0); 6195c680ed6SChris Mason if (sret) 6205c680ed6SChris Mason return sret; 6215c680ed6SChris Mason b = p->nodes[level]; 622e20d96d6SChris Mason c = btrfs_buffer_node(b); 6235c680ed6SChris Mason slot = p->slots[level]; 624bb803951SChris Mason } else if (ins_len < 0) { 625e089f05cSChris Mason int sret = balance_level(trans, root, p, 626e089f05cSChris Mason level); 627bb803951SChris Mason if (sret) 628bb803951SChris Mason return sret; 629bb803951SChris Mason b = p->nodes[level]; 630bb803951SChris Mason if (!b) 631bb803951SChris Mason goto again; 632e20d96d6SChris Mason c = btrfs_buffer_node(b); 633bb803951SChris Mason slot = p->slots[level]; 6347518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 6355c680ed6SChris Mason } 6361d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 637be0e5c09SChris Mason } else { 638234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 639be0e5c09SChris Mason p->slots[level] = slot; 640123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 6410783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 642d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 643d4dbff95SChris Mason p, ins_len); 6445c680ed6SChris Mason BUG_ON(sret > 0); 6455c680ed6SChris Mason if (sret) 6465c680ed6SChris Mason return sret; 6475c680ed6SChris Mason } 648be0e5c09SChris Mason return ret; 649be0e5c09SChris Mason } 650be0e5c09SChris Mason } 651aa5d6bedSChris Mason return 1; 652be0e5c09SChris Mason } 653be0e5c09SChris Mason 65474123bd7SChris Mason /* 65574123bd7SChris Mason * adjust the pointers going up the tree, starting at level 65674123bd7SChris Mason * making sure the right key of each node is points to 'key'. 65774123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 65874123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 65974123bd7SChris Mason * higher levels 660aa5d6bedSChris Mason * 661aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 662aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 66374123bd7SChris Mason */ 664e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 665e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 666e089f05cSChris Mason *key, int level) 667be0e5c09SChris Mason { 668be0e5c09SChris Mason int i; 669aa5d6bedSChris Mason int ret = 0; 670234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 671234b63a0SChris Mason struct btrfs_node *t; 672be0e5c09SChris Mason int tslot = path->slots[i]; 673eb60ceacSChris Mason if (!path->nodes[i]) 674be0e5c09SChris Mason break; 675e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 676d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 677d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 678be0e5c09SChris Mason if (tslot != 0) 679be0e5c09SChris Mason break; 680be0e5c09SChris Mason } 681aa5d6bedSChris Mason return ret; 682be0e5c09SChris Mason } 683be0e5c09SChris Mason 68474123bd7SChris Mason /* 68574123bd7SChris Mason * try to push data from one node into the next node left in the 68679f95c82SChris Mason * tree. 687aa5d6bedSChris Mason * 688aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 689aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 69074123bd7SChris Mason */ 691e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 692e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 693e20d96d6SChris Mason buffer_head *src_buf) 694be0e5c09SChris Mason { 695e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 696e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 697be0e5c09SChris Mason int push_items = 0; 698bb803951SChris Mason int src_nritems; 699bb803951SChris Mason int dst_nritems; 700aa5d6bedSChris Mason int ret = 0; 701be0e5c09SChris Mason 7027518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7037518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 704123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 705eb60ceacSChris Mason if (push_items <= 0) { 706be0e5c09SChris Mason return 1; 707eb60ceacSChris Mason } 708be0e5c09SChris Mason 709be0e5c09SChris Mason if (src_nritems < push_items) 710be0e5c09SChris Mason push_items = src_nritems; 71179f95c82SChris Mason 712d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 713123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 714bb803951SChris Mason if (push_items < src_nritems) { 715d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 716e2fa7227SChris Mason (src_nritems - push_items) * 717123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 718bb803951SChris Mason } 7197518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 7207518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 721d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 722d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 723bb803951SChris Mason return ret; 724be0e5c09SChris Mason } 725be0e5c09SChris Mason 72697571fd0SChris Mason /* 72779f95c82SChris Mason * try to push data from one node into the next node right in the 72879f95c82SChris Mason * tree. 72979f95c82SChris Mason * 73079f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 73179f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 73279f95c82SChris Mason * 73379f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 73479f95c82SChris Mason */ 735e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 736e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 737e20d96d6SChris Mason struct buffer_head *src_buf) 73879f95c82SChris Mason { 739e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 740e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 74179f95c82SChris Mason int push_items = 0; 74279f95c82SChris Mason int max_push; 74379f95c82SChris Mason int src_nritems; 74479f95c82SChris Mason int dst_nritems; 74579f95c82SChris Mason int ret = 0; 74679f95c82SChris Mason 7477518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7487518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 749123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 75079f95c82SChris Mason if (push_items <= 0) { 75179f95c82SChris Mason return 1; 75279f95c82SChris Mason } 75379f95c82SChris Mason 75479f95c82SChris Mason max_push = src_nritems / 2 + 1; 75579f95c82SChris Mason /* don't try to empty the node */ 75679f95c82SChris Mason if (max_push > src_nritems) 75779f95c82SChris Mason return 1; 75879f95c82SChris Mason if (max_push < push_items) 75979f95c82SChris Mason push_items = max_push; 76079f95c82SChris Mason 761d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 762123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 763d6025579SChris Mason 764d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 765d6025579SChris Mason src->ptrs + src_nritems - push_items, 766123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 76779f95c82SChris Mason 7687518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 7697518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 77079f95c82SChris Mason 771d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 772d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 77379f95c82SChris Mason return ret; 77479f95c82SChris Mason } 77579f95c82SChris Mason 77679f95c82SChris Mason /* 77797571fd0SChris Mason * helper function to insert a new root level in the tree. 77897571fd0SChris Mason * A new node is allocated, and a single item is inserted to 77997571fd0SChris Mason * point to the existing root 780aa5d6bedSChris Mason * 781aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 78297571fd0SChris Mason */ 783e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 784e089f05cSChris Mason *root, struct btrfs_path *path, int level) 78574123bd7SChris Mason { 786e20d96d6SChris Mason struct buffer_head *t; 787234b63a0SChris Mason struct btrfs_node *lower; 788234b63a0SChris Mason struct btrfs_node *c; 789e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 7905c680ed6SChris Mason 7915c680ed6SChris Mason BUG_ON(path->nodes[level]); 7925c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 7935c680ed6SChris Mason 794e089f05cSChris Mason t = btrfs_alloc_free_block(trans, root); 795e20d96d6SChris Mason c = btrfs_buffer_node(t); 796123abc88SChris Mason memset(c, 0, root->blocksize); 7977518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 7987518a238SChris Mason btrfs_set_header_level(&c->header, level); 7997eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 8007f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 801e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 8023eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 8033eb0314dSChris Mason sizeof(c->header.fsid)); 8047518a238SChris Mason if (btrfs_is_leaf(lower)) 805234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 80674123bd7SChris Mason else 807123abc88SChris Mason lower_key = &lower->ptrs[0].key; 808d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 809d6025579SChris Mason sizeof(struct btrfs_disk_key)); 8107eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 811d5719762SChris Mason 812d6025579SChris Mason btrfs_mark_buffer_dirty(t); 813d5719762SChris Mason 814cfaa7295SChris Mason /* the super has an extra ref to root->node */ 815234b63a0SChris Mason btrfs_block_release(root, root->node); 81674123bd7SChris Mason root->node = t; 817e20d96d6SChris Mason get_bh(t); 81874123bd7SChris Mason path->nodes[level] = t; 81974123bd7SChris Mason path->slots[level] = 0; 82074123bd7SChris Mason return 0; 82174123bd7SChris Mason } 8225c680ed6SChris Mason 8235c680ed6SChris Mason /* 8245c680ed6SChris Mason * worker function to insert a single pointer in a node. 8255c680ed6SChris Mason * the node should have enough room for the pointer already 82697571fd0SChris Mason * 8275c680ed6SChris Mason * slot and level indicate where you want the key to go, and 8285c680ed6SChris Mason * blocknr is the block the key points to. 829aa5d6bedSChris Mason * 830aa5d6bedSChris Mason * returns zero on success and < 0 on any error 8315c680ed6SChris Mason */ 832e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 833e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 834e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 8355c680ed6SChris Mason { 836234b63a0SChris Mason struct btrfs_node *lower; 8375c680ed6SChris Mason int nritems; 8385c680ed6SChris Mason 8395c680ed6SChris Mason BUG_ON(!path->nodes[level]); 840e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 8417518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 84274123bd7SChris Mason if (slot > nritems) 84374123bd7SChris Mason BUG(); 844123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 84574123bd7SChris Mason BUG(); 84674123bd7SChris Mason if (slot != nritems) { 847d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 848d6025579SChris Mason lower->ptrs + slot, 849123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 85074123bd7SChris Mason } 851d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 852d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 8531d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 8547518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 855d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 85674123bd7SChris Mason return 0; 85774123bd7SChris Mason } 85874123bd7SChris Mason 85997571fd0SChris Mason /* 86097571fd0SChris Mason * split the node at the specified level in path in two. 86197571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 86297571fd0SChris Mason * 86397571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 86497571fd0SChris Mason * left and right, if either one works, it returns right away. 865aa5d6bedSChris Mason * 866aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 86797571fd0SChris Mason */ 868e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 869e089f05cSChris Mason *root, struct btrfs_path *path, int level) 870be0e5c09SChris Mason { 871e20d96d6SChris Mason struct buffer_head *t; 872234b63a0SChris Mason struct btrfs_node *c; 873e20d96d6SChris Mason struct buffer_head *split_buffer; 874234b63a0SChris Mason struct btrfs_node *split; 875be0e5c09SChris Mason int mid; 8765c680ed6SChris Mason int ret; 877aa5d6bedSChris Mason int wret; 8787518a238SChris Mason u32 c_nritems; 879be0e5c09SChris Mason 8805c680ed6SChris Mason t = path->nodes[level]; 881e20d96d6SChris Mason c = btrfs_buffer_node(t); 8825c680ed6SChris Mason if (t == root->node) { 8835c680ed6SChris Mason /* trying to split the root, lets make a new one */ 884e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 8855c680ed6SChris Mason if (ret) 8865c680ed6SChris Mason return ret; 887*e66f709bSChris Mason } else { 888*e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 889*e66f709bSChris Mason t = path->nodes[level]; 890*e66f709bSChris Mason c = btrfs_buffer_node(t); 891*e66f709bSChris Mason if (!ret && 892*e66f709bSChris Mason btrfs_header_nritems(&c->header) < 893*e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 894*e66f709bSChris Mason return 0; 8955c680ed6SChris Mason } 896*e66f709bSChris Mason 8977518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 898e089f05cSChris Mason split_buffer = btrfs_alloc_free_block(trans, root); 899e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 9007518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 9019a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 9027eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 9037f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 9043eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 9053eb0314dSChris Mason sizeof(split->header.fsid)); 9067518a238SChris Mason mid = (c_nritems + 1) / 2; 907d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 908123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 9097518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 9107518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 911aa5d6bedSChris Mason ret = 0; 912aa5d6bedSChris Mason 913d6025579SChris Mason btrfs_mark_buffer_dirty(t); 914d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 915e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 9167eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 917123abc88SChris Mason level + 1); 918aa5d6bedSChris Mason if (wret) 919aa5d6bedSChris Mason ret = wret; 920aa5d6bedSChris Mason 9215de08d7dSChris Mason if (path->slots[level] >= mid) { 9225c680ed6SChris Mason path->slots[level] -= mid; 923234b63a0SChris Mason btrfs_block_release(root, t); 9245c680ed6SChris Mason path->nodes[level] = split_buffer; 9255c680ed6SChris Mason path->slots[level + 1] += 1; 926eb60ceacSChris Mason } else { 927234b63a0SChris Mason btrfs_block_release(root, split_buffer); 928be0e5c09SChris Mason } 929aa5d6bedSChris Mason return ret; 930be0e5c09SChris Mason } 931be0e5c09SChris Mason 93274123bd7SChris Mason /* 93374123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 93474123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 93574123bd7SChris Mason * space used both by the item structs and the item data 93674123bd7SChris Mason */ 937234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 938be0e5c09SChris Mason { 939be0e5c09SChris Mason int data_len; 940d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 941d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 942be0e5c09SChris Mason 943be0e5c09SChris Mason if (!nr) 944be0e5c09SChris Mason return 0; 9450783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 9460783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 9470783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 948d4dbff95SChris Mason WARN_ON(data_len < 0); 949be0e5c09SChris Mason return data_len; 950be0e5c09SChris Mason } 951be0e5c09SChris Mason 95274123bd7SChris Mason /* 953d4dbff95SChris Mason * The space between the end of the leaf items and 954d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 955d4dbff95SChris Mason * the leaf has left for both items and data 956d4dbff95SChris Mason */ 957d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 958d4dbff95SChris Mason { 959d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 960d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 961d4dbff95SChris Mason } 962d4dbff95SChris Mason 963d4dbff95SChris Mason /* 96400ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 96500ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 966aa5d6bedSChris Mason * 967aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 968aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 96900ec4c51SChris Mason */ 970e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 971e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 97200ec4c51SChris Mason { 973e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 974e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 975234b63a0SChris Mason struct btrfs_leaf *right; 976e20d96d6SChris Mason struct buffer_head *right_buf; 977e20d96d6SChris Mason struct buffer_head *upper; 978e20d96d6SChris Mason struct btrfs_node *upper_node; 97900ec4c51SChris Mason int slot; 98000ec4c51SChris Mason int i; 98100ec4c51SChris Mason int free_space; 98200ec4c51SChris Mason int push_space = 0; 98300ec4c51SChris Mason int push_items = 0; 9840783fcfcSChris Mason struct btrfs_item *item; 9857518a238SChris Mason u32 left_nritems; 9867518a238SChris Mason u32 right_nritems; 98700ec4c51SChris Mason 98800ec4c51SChris Mason slot = path->slots[1]; 98900ec4c51SChris Mason if (!path->nodes[1]) { 99000ec4c51SChris Mason return 1; 99100ec4c51SChris Mason } 99200ec4c51SChris Mason upper = path->nodes[1]; 993e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 994e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 99500ec4c51SChris Mason return 1; 99600ec4c51SChris Mason } 997e20d96d6SChris Mason right_buf = read_tree_block(root, 998e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 999e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1000123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10010783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1002234b63a0SChris Mason btrfs_block_release(root, right_buf); 100300ec4c51SChris Mason return 1; 100400ec4c51SChris Mason } 100502217ed2SChris Mason /* cow and double check */ 1006e089f05cSChris Mason btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); 1007e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1008123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10090783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1010234b63a0SChris Mason btrfs_block_release(root, right_buf); 101102217ed2SChris Mason return 1; 101202217ed2SChris Mason } 101302217ed2SChris Mason 10147518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1015a429e513SChris Mason if (left_nritems == 0) { 1016a429e513SChris Mason btrfs_block_release(root, right_buf); 1017a429e513SChris Mason return 1; 1018a429e513SChris Mason } 1019a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 102000ec4c51SChris Mason item = left->items + i; 102100ec4c51SChris Mason if (path->slots[0] == i) 102200ec4c51SChris Mason push_space += data_size + sizeof(*item); 10230783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 10240783fcfcSChris Mason free_space) 102500ec4c51SChris Mason break; 102600ec4c51SChris Mason push_items++; 10270783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 102800ec4c51SChris Mason } 102900ec4c51SChris Mason if (push_items == 0) { 1030234b63a0SChris Mason btrfs_block_release(root, right_buf); 103100ec4c51SChris Mason return 1; 103200ec4c51SChris Mason } 1033a429e513SChris Mason if (push_items == left_nritems) 1034a429e513SChris Mason WARN_ON(1); 10357518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 103600ec4c51SChris Mason /* push left to right */ 10370783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1038123abc88SChris Mason push_space -= leaf_data_end(root, left); 103900ec4c51SChris Mason /* make room in the right data area */ 1040d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1041d6025579SChris Mason leaf_data_end(root, right) - push_space, 1042d6025579SChris Mason btrfs_leaf_data(right) + 1043d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1044d6025579SChris Mason leaf_data_end(root, right)); 104500ec4c51SChris Mason /* copy from the left data area */ 1046d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1047d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1048d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1049d6025579SChris Mason push_space); 1050d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 10510783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 105200ec4c51SChris Mason /* copy the items from left to right */ 1053d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1054d6025579SChris Mason left_nritems - push_items, 10550783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 105600ec4c51SChris Mason 105700ec4c51SChris Mason /* update the item pointers */ 10587518a238SChris Mason right_nritems += push_items; 10597518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1060123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 10617518a238SChris Mason for (i = 0; i < right_nritems; i++) { 10620783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 10630783fcfcSChris Mason btrfs_item_size(right->items + i)); 10640783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 106500ec4c51SChris Mason } 10667518a238SChris Mason left_nritems -= push_items; 10677518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 106800ec4c51SChris Mason 1069d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1070d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1071a429e513SChris Mason 1072d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1073e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1074d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 107502217ed2SChris Mason 107600ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 10777518a238SChris Mason if (path->slots[0] >= left_nritems) { 10787518a238SChris Mason path->slots[0] -= left_nritems; 1079234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 108000ec4c51SChris Mason path->nodes[0] = right_buf; 108100ec4c51SChris Mason path->slots[1] += 1; 108200ec4c51SChris Mason } else { 1083234b63a0SChris Mason btrfs_block_release(root, right_buf); 108400ec4c51SChris Mason } 108500ec4c51SChris Mason return 0; 108600ec4c51SChris Mason } 108700ec4c51SChris Mason /* 108874123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 108974123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 109074123bd7SChris Mason */ 1091e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1092e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1093be0e5c09SChris Mason { 1094e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1095e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1096e20d96d6SChris Mason struct buffer_head *t; 1097234b63a0SChris Mason struct btrfs_leaf *left; 1098be0e5c09SChris Mason int slot; 1099be0e5c09SChris Mason int i; 1100be0e5c09SChris Mason int free_space; 1101be0e5c09SChris Mason int push_space = 0; 1102be0e5c09SChris Mason int push_items = 0; 11030783fcfcSChris Mason struct btrfs_item *item; 11047518a238SChris Mason u32 old_left_nritems; 1105aa5d6bedSChris Mason int ret = 0; 1106aa5d6bedSChris Mason int wret; 1107be0e5c09SChris Mason 1108be0e5c09SChris Mason slot = path->slots[1]; 1109be0e5c09SChris Mason if (slot == 0) { 1110be0e5c09SChris Mason return 1; 1111be0e5c09SChris Mason } 1112be0e5c09SChris Mason if (!path->nodes[1]) { 1113be0e5c09SChris Mason return 1; 1114be0e5c09SChris Mason } 1115e20d96d6SChris Mason t = read_tree_block(root, 1116e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1117e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1118123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11190783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1120234b63a0SChris Mason btrfs_block_release(root, t); 1121be0e5c09SChris Mason return 1; 1122be0e5c09SChris Mason } 112302217ed2SChris Mason 112402217ed2SChris Mason /* cow and double check */ 1125e089f05cSChris Mason btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 1126e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1127123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11280783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1129234b63a0SChris Mason btrfs_block_release(root, t); 113002217ed2SChris Mason return 1; 113102217ed2SChris Mason } 113202217ed2SChris Mason 1133a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1134a429e513SChris Mason btrfs_block_release(root, t); 1135a429e513SChris Mason return 1; 1136a429e513SChris Mason } 1137a429e513SChris Mason 1138a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1139be0e5c09SChris Mason item = right->items + i; 1140be0e5c09SChris Mason if (path->slots[0] == i) 1141be0e5c09SChris Mason push_space += data_size + sizeof(*item); 11420783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 11430783fcfcSChris Mason free_space) 1144be0e5c09SChris Mason break; 1145be0e5c09SChris Mason push_items++; 11460783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1147be0e5c09SChris Mason } 1148be0e5c09SChris Mason if (push_items == 0) { 1149234b63a0SChris Mason btrfs_block_release(root, t); 1150be0e5c09SChris Mason return 1; 1151be0e5c09SChris Mason } 1152a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1153a429e513SChris Mason WARN_ON(1); 1154be0e5c09SChris Mason /* push data from right to left */ 1155d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1156d6025579SChris Mason btrfs_header_nritems(&left->header), 11570783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1158123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 11590783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1160d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1161d6025579SChris Mason leaf_data_end(root, left) - push_space, 1162123abc88SChris Mason btrfs_leaf_data(right) + 1163123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1164be0e5c09SChris Mason push_space); 11657518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1166eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1167eb60ceacSChris Mason 1168be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1169123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1170123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1171123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 11720783fcfcSChris Mason btrfs_item_offset(left->items + 11730783fcfcSChris Mason old_left_nritems - 1))); 1174be0e5c09SChris Mason } 11757518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1176be0e5c09SChris Mason 1177be0e5c09SChris Mason /* fixup right node */ 11780783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1179123abc88SChris Mason leaf_data_end(root, right); 1180d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1181d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1182d6025579SChris Mason btrfs_leaf_data(right) + 1183123abc88SChris Mason leaf_data_end(root, right), push_space); 1184d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 11857518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 11860783fcfcSChris Mason sizeof(struct btrfs_item)); 11877518a238SChris Mason btrfs_set_header_nritems(&right->header, 11887518a238SChris Mason btrfs_header_nritems(&right->header) - 11897518a238SChris Mason push_items); 1190123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1191eb60ceacSChris Mason 11927518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 11930783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 11940783fcfcSChris Mason btrfs_item_size(right->items + i)); 11950783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1196be0e5c09SChris Mason } 1197eb60ceacSChris Mason 1198d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1199d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1200e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1201aa5d6bedSChris Mason if (wret) 1202aa5d6bedSChris Mason ret = wret; 1203be0e5c09SChris Mason 1204be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1205be0e5c09SChris Mason if (path->slots[0] < push_items) { 1206be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1207234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1208eb60ceacSChris Mason path->nodes[0] = t; 1209be0e5c09SChris Mason path->slots[1] -= 1; 1210be0e5c09SChris Mason } else { 1211234b63a0SChris Mason btrfs_block_release(root, t); 1212be0e5c09SChris Mason path->slots[0] -= push_items; 1213be0e5c09SChris Mason } 1214eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1215aa5d6bedSChris Mason return ret; 1216be0e5c09SChris Mason } 1217be0e5c09SChris Mason 121874123bd7SChris Mason /* 121974123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 122074123bd7SChris Mason * available for the resulting leaf level of the path. 1221aa5d6bedSChris Mason * 1222aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 122374123bd7SChris Mason */ 1224e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1225d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1226d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1227be0e5c09SChris Mason { 1228e20d96d6SChris Mason struct buffer_head *l_buf; 1229234b63a0SChris Mason struct btrfs_leaf *l; 12307518a238SChris Mason u32 nritems; 1231eb60ceacSChris Mason int mid; 1232eb60ceacSChris Mason int slot; 1233234b63a0SChris Mason struct btrfs_leaf *right; 1234e20d96d6SChris Mason struct buffer_head *right_buffer; 12350783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1236be0e5c09SChris Mason int data_copy_size; 1237be0e5c09SChris Mason int rt_data_off; 1238be0e5c09SChris Mason int i; 1239d4dbff95SChris Mason int ret = 0; 1240aa5d6bedSChris Mason int wret; 1241d4dbff95SChris Mason int double_split = 0; 1242d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1243be0e5c09SChris Mason 124440689478SChris Mason /* first try to make some room by pushing left and right */ 1245e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1246eaee50e8SChris Mason if (wret < 0) 1247eaee50e8SChris Mason return wret; 1248eaee50e8SChris Mason if (wret) { 1249e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1250eaee50e8SChris Mason if (wret < 0) 1251eaee50e8SChris Mason return wret; 1252eaee50e8SChris Mason } 1253eb60ceacSChris Mason l_buf = path->nodes[0]; 1254e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1255aa5d6bedSChris Mason 1256aa5d6bedSChris Mason /* did the pushes work? */ 1257123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1258123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1259be0e5c09SChris Mason return 0; 1260aa5d6bedSChris Mason 12615c680ed6SChris Mason if (!path->nodes[1]) { 1262e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 12635c680ed6SChris Mason if (ret) 12645c680ed6SChris Mason return ret; 12655c680ed6SChris Mason } 1266eb60ceacSChris Mason slot = path->slots[0]; 12677518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1268eb60ceacSChris Mason mid = (nritems + 1)/ 2; 1269e089f05cSChris Mason right_buffer = btrfs_alloc_free_block(trans, root); 1270eb60ceacSChris Mason BUG_ON(!right_buffer); 1271e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1272123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 12737eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 12747f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 12757518a238SChris Mason btrfs_set_header_level(&right->header, 0); 12763eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 12773eb0314dSChris Mason sizeof(right->header.fsid)); 1278d4dbff95SChris Mason if (mid <= slot) { 1279d4dbff95SChris Mason if (nritems == 1 || 1280d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1281d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1282d4dbff95SChris Mason if (slot >= nritems) { 1283d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1284d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1285d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1286d4dbff95SChris Mason &disk_key, 12877eccb903SChris Mason bh_blocknr(right_buffer), 1288d4dbff95SChris Mason path->slots[1] + 1, 1); 1289d4dbff95SChris Mason if (wret) 1290d4dbff95SChris Mason ret = wret; 1291d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1292d4dbff95SChris Mason path->nodes[0] = right_buffer; 1293d4dbff95SChris Mason path->slots[0] = 0; 1294d4dbff95SChris Mason path->slots[1] += 1; 1295d4dbff95SChris Mason return ret; 1296d4dbff95SChris Mason } 1297d4dbff95SChris Mason mid = slot; 1298d4dbff95SChris Mason double_split = 1; 1299d4dbff95SChris Mason } 1300d4dbff95SChris Mason } else { 1301d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1302d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1303d4dbff95SChris Mason if (slot == 0) { 1304d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1305d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1306d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1307d4dbff95SChris Mason &disk_key, 13087eccb903SChris Mason bh_blocknr(right_buffer), 1309d4dbff95SChris Mason path->slots[1] - 1, 1); 1310d4dbff95SChris Mason if (wret) 1311d4dbff95SChris Mason ret = wret; 1312d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1313d4dbff95SChris Mason path->nodes[0] = right_buffer; 1314d4dbff95SChris Mason path->slots[0] = 0; 1315d4dbff95SChris Mason path->slots[1] -= 1; 1316a429e513SChris Mason if (path->slots[1] == 0) { 1317a429e513SChris Mason wret = fixup_low_keys(trans, root, 1318a429e513SChris Mason path, &disk_key, 1); 1319a429e513SChris Mason if (wret) 1320a429e513SChris Mason ret = wret; 1321a429e513SChris Mason } 1322d4dbff95SChris Mason return ret; 1323d4dbff95SChris Mason } 1324d4dbff95SChris Mason mid = slot; 1325d4dbff95SChris Mason double_split = 1; 1326d4dbff95SChris Mason } 1327d4dbff95SChris Mason } 1328d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1329123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1330123abc88SChris Mason leaf_data_end(root, l); 1331d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 13320783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1333d6025579SChris Mason btrfs_memcpy(root, right, 1334d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1335123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1336123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1337123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1338123abc88SChris Mason btrfs_item_end(l->items + mid); 133974123bd7SChris Mason 13400783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1341123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 13420783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 13430783fcfcSChris Mason } 134474123bd7SChris Mason 13457518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1346aa5d6bedSChris Mason ret = 0; 1347e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 13487eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1349aa5d6bedSChris Mason if (wret) 1350aa5d6bedSChris Mason ret = wret; 1351d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1352d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1353eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1354be0e5c09SChris Mason if (mid <= slot) { 1355234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1356eb60ceacSChris Mason path->nodes[0] = right_buffer; 1357be0e5c09SChris Mason path->slots[0] -= mid; 1358be0e5c09SChris Mason path->slots[1] += 1; 1359eb60ceacSChris Mason } else 1360234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1361eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1362d4dbff95SChris Mason 1363d4dbff95SChris Mason if (!double_split) 1364d4dbff95SChris Mason return ret; 1365d4dbff95SChris Mason right_buffer = btrfs_alloc_free_block(trans, root); 1366d4dbff95SChris Mason BUG_ON(!right_buffer); 1367d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1368d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 13697eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1370d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 1371d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 13723eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 13733eb0314dSChris Mason sizeof(right->header.fsid)); 1374d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1375d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1376d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1377d4dbff95SChris Mason &disk_key, 13787eccb903SChris Mason bh_blocknr(right_buffer), 1379d4dbff95SChris Mason path->slots[1], 1); 1380d4dbff95SChris Mason if (wret) 1381d4dbff95SChris Mason ret = wret; 1382a429e513SChris Mason if (path->slots[1] == 0) { 1383a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1384a429e513SChris Mason if (wret) 1385a429e513SChris Mason ret = wret; 1386a429e513SChris Mason } 1387d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1388d4dbff95SChris Mason path->nodes[0] = right_buffer; 1389d4dbff95SChris Mason path->slots[0] = 0; 1390d4dbff95SChris Mason check_node(root, path, 1); 1391d4dbff95SChris Mason check_leaf(root, path, 0); 1392be0e5c09SChris Mason return ret; 1393be0e5c09SChris Mason } 1394be0e5c09SChris Mason 1395b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1396b18c6685SChris Mason struct btrfs_root *root, 1397b18c6685SChris Mason struct btrfs_path *path, 1398b18c6685SChris Mason u32 new_size) 1399b18c6685SChris Mason { 1400b18c6685SChris Mason int ret = 0; 1401b18c6685SChris Mason int slot; 1402b18c6685SChris Mason int slot_orig; 1403b18c6685SChris Mason struct btrfs_leaf *leaf; 1404b18c6685SChris Mason struct buffer_head *leaf_buf; 1405b18c6685SChris Mason u32 nritems; 1406b18c6685SChris Mason unsigned int data_end; 1407b18c6685SChris Mason unsigned int old_data_start; 1408b18c6685SChris Mason unsigned int old_size; 1409b18c6685SChris Mason unsigned int size_diff; 1410b18c6685SChris Mason int i; 1411b18c6685SChris Mason 1412b18c6685SChris Mason slot_orig = path->slots[0]; 1413b18c6685SChris Mason leaf_buf = path->nodes[0]; 1414b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1415b18c6685SChris Mason 1416b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1417b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1418b18c6685SChris Mason 1419b18c6685SChris Mason slot = path->slots[0]; 1420b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1421b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1422b18c6685SChris Mason BUG_ON(old_size <= new_size); 1423b18c6685SChris Mason size_diff = old_size - new_size; 1424b18c6685SChris Mason 1425b18c6685SChris Mason BUG_ON(slot < 0); 1426b18c6685SChris Mason BUG_ON(slot >= nritems); 1427b18c6685SChris Mason 1428b18c6685SChris Mason /* 1429b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1430b18c6685SChris Mason */ 1431b18c6685SChris Mason /* first correct the data pointers */ 1432b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1433b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1434b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1435b18c6685SChris Mason ioff + size_diff); 1436b18c6685SChris Mason } 1437b18c6685SChris Mason /* shift the data */ 1438b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1439b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1440b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1441b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1442b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1443b18c6685SChris Mason 1444b18c6685SChris Mason ret = 0; 1445b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1446b18c6685SChris Mason BUG(); 1447b18c6685SChris Mason check_leaf(root, path, 0); 1448b18c6685SChris Mason return ret; 1449b18c6685SChris Mason } 1450b18c6685SChris Mason 14516567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 14526567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 14536567e837SChris Mason { 14546567e837SChris Mason int ret = 0; 14556567e837SChris Mason int slot; 14566567e837SChris Mason int slot_orig; 14576567e837SChris Mason struct btrfs_leaf *leaf; 14586567e837SChris Mason struct buffer_head *leaf_buf; 14596567e837SChris Mason u32 nritems; 14606567e837SChris Mason unsigned int data_end; 14616567e837SChris Mason unsigned int old_data; 14626567e837SChris Mason unsigned int old_size; 14636567e837SChris Mason int i; 14646567e837SChris Mason 14656567e837SChris Mason slot_orig = path->slots[0]; 14666567e837SChris Mason leaf_buf = path->nodes[0]; 14676567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 14686567e837SChris Mason 14696567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 14706567e837SChris Mason data_end = leaf_data_end(root, leaf); 14716567e837SChris Mason 14726567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 14736567e837SChris Mason BUG(); 14746567e837SChris Mason slot = path->slots[0]; 14756567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 14766567e837SChris Mason 14776567e837SChris Mason BUG_ON(slot < 0); 14786567e837SChris Mason BUG_ON(slot >= nritems); 14796567e837SChris Mason 14806567e837SChris Mason /* 14816567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 14826567e837SChris Mason */ 14836567e837SChris Mason /* first correct the data pointers */ 14846567e837SChris Mason for (i = slot; i < nritems; i++) { 14856567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 14866567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 14876567e837SChris Mason ioff - data_size); 14886567e837SChris Mason } 14896567e837SChris Mason /* shift the data */ 14906567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 14916567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 14926567e837SChris Mason data_end, old_data - data_end); 14936567e837SChris Mason data_end = old_data; 14946567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 14956567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 14966567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 14976567e837SChris Mason 14986567e837SChris Mason ret = 0; 14996567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 15006567e837SChris Mason BUG(); 15016567e837SChris Mason check_leaf(root, path, 0); 15026567e837SChris Mason return ret; 15036567e837SChris Mason } 15046567e837SChris Mason 150574123bd7SChris Mason /* 150674123bd7SChris Mason * Given a key and some data, insert an item into the tree. 150774123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 150874123bd7SChris Mason */ 1509e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1510e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1511e089f05cSChris Mason *cpu_key, u32 data_size) 1512be0e5c09SChris Mason { 1513aa5d6bedSChris Mason int ret = 0; 1514be0e5c09SChris Mason int slot; 1515eb60ceacSChris Mason int slot_orig; 1516234b63a0SChris Mason struct btrfs_leaf *leaf; 1517e20d96d6SChris Mason struct buffer_head *leaf_buf; 15187518a238SChris Mason u32 nritems; 1519be0e5c09SChris Mason unsigned int data_end; 1520e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1521e2fa7227SChris Mason 1522e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1523be0e5c09SChris Mason 152474123bd7SChris Mason /* create a root if there isn't one */ 15255c680ed6SChris Mason if (!root->node) 1526cfaa7295SChris Mason BUG(); 1527e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1528eb60ceacSChris Mason if (ret == 0) { 1529f0930a37SChris Mason return -EEXIST; 1530aa5d6bedSChris Mason } 1531ed2ff2cbSChris Mason if (ret < 0) 1532ed2ff2cbSChris Mason goto out; 1533be0e5c09SChris Mason 153462e2749eSChris Mason slot_orig = path->slots[0]; 153562e2749eSChris Mason leaf_buf = path->nodes[0]; 1536e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 153774123bd7SChris Mason 15387518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1539123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1540eb60ceacSChris Mason 1541123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1542d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1543be0e5c09SChris Mason BUG(); 1544d4dbff95SChris Mason } 154562e2749eSChris Mason slot = path->slots[0]; 1546eb60ceacSChris Mason BUG_ON(slot < 0); 1547be0e5c09SChris Mason if (slot != nritems) { 1548be0e5c09SChris Mason int i; 15490783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1550be0e5c09SChris Mason 1551be0e5c09SChris Mason /* 1552be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1553be0e5c09SChris Mason */ 1554be0e5c09SChris Mason /* first correct the data pointers */ 15550783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1556123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 15570783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 15580783fcfcSChris Mason ioff - data_size); 15590783fcfcSChris Mason } 1560be0e5c09SChris Mason 1561be0e5c09SChris Mason /* shift the items */ 1562d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1563d6025579SChris Mason leaf->items + slot, 15640783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1565be0e5c09SChris Mason 1566be0e5c09SChris Mason /* shift the data */ 1567d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1568d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1569be0e5c09SChris Mason data_end, old_data - data_end); 1570be0e5c09SChris Mason data_end = old_data; 1571be0e5c09SChris Mason } 157262e2749eSChris Mason /* setup the item for the new data */ 1573d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1574e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 15750783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 15760783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 15777518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1578d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1579aa5d6bedSChris Mason 1580aa5d6bedSChris Mason ret = 0; 15818e19f2cdSChris Mason if (slot == 0) 1582e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1583aa5d6bedSChris Mason 1584123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1585be0e5c09SChris Mason BUG(); 158662e2749eSChris Mason check_leaf(root, path, 0); 1587ed2ff2cbSChris Mason out: 158862e2749eSChris Mason return ret; 158962e2749eSChris Mason } 159062e2749eSChris Mason 159162e2749eSChris Mason /* 159262e2749eSChris Mason * Given a key and some data, insert an item into the tree. 159362e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 159462e2749eSChris Mason */ 1595e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1596e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1597e089f05cSChris Mason data_size) 159862e2749eSChris Mason { 159962e2749eSChris Mason int ret = 0; 16002c90e5d6SChris Mason struct btrfs_path *path; 160162e2749eSChris Mason u8 *ptr; 160262e2749eSChris Mason 16032c90e5d6SChris Mason path = btrfs_alloc_path(); 16042c90e5d6SChris Mason BUG_ON(!path); 16052c90e5d6SChris Mason btrfs_init_path(path); 16062c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 160762e2749eSChris Mason if (!ret) { 16082c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 16092c90e5d6SChris Mason path->slots[0], u8); 16102c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1611d6025579SChris Mason ptr, data, data_size); 16122c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 161362e2749eSChris Mason } 16142c90e5d6SChris Mason btrfs_release_path(root, path); 16152c90e5d6SChris Mason btrfs_free_path(path); 1616aa5d6bedSChris Mason return ret; 1617be0e5c09SChris Mason } 1618be0e5c09SChris Mason 161974123bd7SChris Mason /* 16205de08d7dSChris Mason * delete the pointer from a given node. 162174123bd7SChris Mason * 162274123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 162374123bd7SChris Mason * continuing all the way the root if required. The root is converted into 162474123bd7SChris Mason * a leaf if all the nodes are emptied. 162574123bd7SChris Mason */ 1626e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1627e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1628be0e5c09SChris Mason { 1629234b63a0SChris Mason struct btrfs_node *node; 1630e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 16317518a238SChris Mason u32 nritems; 1632aa5d6bedSChris Mason int ret = 0; 1633bb803951SChris Mason int wret; 1634be0e5c09SChris Mason 1635e20d96d6SChris Mason node = btrfs_buffer_node(parent); 16367518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1637be0e5c09SChris Mason if (slot != nritems -1) { 1638d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1639d6025579SChris Mason node->ptrs + slot + 1, 1640d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1641d6025579SChris Mason (nritems - slot - 1)); 1642be0e5c09SChris Mason } 16437518a238SChris Mason nritems--; 16447518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 16457518a238SChris Mason if (nritems == 0 && parent == root->node) { 1646e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1647e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1648eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1649e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1650bb803951SChris Mason } else if (slot == 0) { 1651e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1652123abc88SChris Mason level + 1); 16530f70abe2SChris Mason if (wret) 16540f70abe2SChris Mason ret = wret; 1655be0e5c09SChris Mason } 1656d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1657aa5d6bedSChris Mason return ret; 1658be0e5c09SChris Mason } 1659be0e5c09SChris Mason 166074123bd7SChris Mason /* 166174123bd7SChris Mason * delete the item at the leaf level in path. If that empties 166274123bd7SChris Mason * the leaf, remove it from the tree 166374123bd7SChris Mason */ 1664e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1665e089f05cSChris Mason struct btrfs_path *path) 1666be0e5c09SChris Mason { 1667be0e5c09SChris Mason int slot; 1668234b63a0SChris Mason struct btrfs_leaf *leaf; 1669e20d96d6SChris Mason struct buffer_head *leaf_buf; 1670be0e5c09SChris Mason int doff; 1671be0e5c09SChris Mason int dsize; 1672aa5d6bedSChris Mason int ret = 0; 1673aa5d6bedSChris Mason int wret; 16747518a238SChris Mason u32 nritems; 1675be0e5c09SChris Mason 1676eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1677e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 16784920c9acSChris Mason slot = path->slots[0]; 16790783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 16800783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 16817518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1682be0e5c09SChris Mason 16837518a238SChris Mason if (slot != nritems - 1) { 1684be0e5c09SChris Mason int i; 1685123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 1686d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1687d6025579SChris Mason data_end + dsize, 1688123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 1689be0e5c09SChris Mason doff - data_end); 16900783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 1691123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 16920783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 16930783fcfcSChris Mason } 1694d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 1695d6025579SChris Mason leaf->items + slot + 1, 16960783fcfcSChris Mason sizeof(struct btrfs_item) * 16977518a238SChris Mason (nritems - slot - 1)); 1698be0e5c09SChris Mason } 16997518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 17007518a238SChris Mason nritems--; 170174123bd7SChris Mason /* delete the leaf if we've emptied it */ 17027518a238SChris Mason if (nritems == 0) { 1703eb60ceacSChris Mason if (leaf_buf == root->node) { 17047518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 17059a8dd150SChris Mason } else { 1706e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1707d6025579SChris Mason wait_on_buffer(leaf_buf); 1708e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 1709aa5d6bedSChris Mason if (wret) 1710aa5d6bedSChris Mason ret = wret; 1711e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 17127eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 17130f70abe2SChris Mason if (wret) 17140f70abe2SChris Mason ret = wret; 17159a8dd150SChris Mason } 1716be0e5c09SChris Mason } else { 17177518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 1718aa5d6bedSChris Mason if (slot == 0) { 1719e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 1720aa5d6bedSChris Mason &leaf->items[0].key, 1); 1721aa5d6bedSChris Mason if (wret) 1722aa5d6bedSChris Mason ret = wret; 1723aa5d6bedSChris Mason } 1724aa5d6bedSChris Mason 172574123bd7SChris Mason /* delete the leaf if it is mostly empty */ 1726123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1727be0e5c09SChris Mason /* push_leaf_left fixes the path. 1728be0e5c09SChris Mason * make sure the path still points to our leaf 1729be0e5c09SChris Mason * for possible call to del_ptr below 1730be0e5c09SChris Mason */ 17314920c9acSChris Mason slot = path->slots[1]; 1732e20d96d6SChris Mason get_bh(leaf_buf); 1733e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 1734aa5d6bedSChris Mason if (wret < 0) 1735aa5d6bedSChris Mason ret = wret; 1736f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 17377518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 1738e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 1739aa5d6bedSChris Mason if (wret < 0) 1740aa5d6bedSChris Mason ret = wret; 1741aa5d6bedSChris Mason } 17427518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 17437eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 1744e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1745d6025579SChris Mason wait_on_buffer(leaf_buf); 1746e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 1747aa5d6bedSChris Mason if (wret) 1748aa5d6bedSChris Mason ret = wret; 1749234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1750e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1751e089f05cSChris Mason 1, 1); 17520f70abe2SChris Mason if (wret) 17530f70abe2SChris Mason ret = wret; 17545de08d7dSChris Mason } else { 1755d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1756234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1757be0e5c09SChris Mason } 1758d5719762SChris Mason } else { 1759d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1760be0e5c09SChris Mason } 17619a8dd150SChris Mason } 1762aa5d6bedSChris Mason return ret; 17639a8dd150SChris Mason } 17649a8dd150SChris Mason 176597571fd0SChris Mason /* 176697571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 17670f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 17680f70abe2SChris Mason * returns < 0 on io errors. 176997571fd0SChris Mason */ 1770234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 1771d97e63b6SChris Mason { 1772d97e63b6SChris Mason int slot; 1773d97e63b6SChris Mason int level = 1; 1774d97e63b6SChris Mason u64 blocknr; 1775e20d96d6SChris Mason struct buffer_head *c; 1776e20d96d6SChris Mason struct btrfs_node *c_node; 1777e20d96d6SChris Mason struct buffer_head *next = NULL; 1778d97e63b6SChris Mason 1779234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 1780d97e63b6SChris Mason if (!path->nodes[level]) 17810f70abe2SChris Mason return 1; 1782d97e63b6SChris Mason slot = path->slots[level] + 1; 1783d97e63b6SChris Mason c = path->nodes[level]; 1784e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 1785e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 1786d97e63b6SChris Mason level++; 1787d97e63b6SChris Mason continue; 1788d97e63b6SChris Mason } 1789e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 1790cfaa7295SChris Mason if (next) 1791234b63a0SChris Mason btrfs_block_release(root, next); 1792d97e63b6SChris Mason next = read_tree_block(root, blocknr); 1793d97e63b6SChris Mason break; 1794d97e63b6SChris Mason } 1795d97e63b6SChris Mason path->slots[level] = slot; 1796d97e63b6SChris Mason while(1) { 1797d97e63b6SChris Mason level--; 1798d97e63b6SChris Mason c = path->nodes[level]; 1799234b63a0SChris Mason btrfs_block_release(root, c); 1800d97e63b6SChris Mason path->nodes[level] = next; 1801d97e63b6SChris Mason path->slots[level] = 0; 1802d97e63b6SChris Mason if (!level) 1803d97e63b6SChris Mason break; 18041d4f8a0cSChris Mason next = read_tree_block(root, 1805e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 1806d97e63b6SChris Mason } 1807d97e63b6SChris Mason return 0; 1808d97e63b6SChris Mason } 1809