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 } 6431f3c99bSChris Mason cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr); 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); 714d775673SChris Mason btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); 72e089f05cSChris Mason btrfs_inc_ref(trans, root, buf); 7302217ed2SChris Mason if (buf == root->node) { 7402217ed2SChris Mason root->node = cow; 75e20d96d6SChris Mason get_bh(cow); 762c90e5d6SChris Mason if (buf != root->commit_root) { 777eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 782c90e5d6SChris Mason } 79234b63a0SChris Mason btrfs_block_release(root, buf); 8002217ed2SChris Mason } else { 81e20d96d6SChris Mason btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 827eccb903SChris Mason bh_blocknr(cow)); 83d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 847eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 8502217ed2SChris Mason } 86234b63a0SChris Mason btrfs_block_release(root, buf); 87df24a2b9SChris Mason mark_buffer_dirty(cow); 882c90e5d6SChris Mason *cow_ret = cow; 8902217ed2SChris Mason return 0; 9002217ed2SChris Mason } 9102217ed2SChris Mason 9274123bd7SChris Mason /* 9374123bd7SChris Mason * The leaf data grows from end-to-front in the node. 9474123bd7SChris Mason * this returns the address of the start of the last item, 9574123bd7SChris Mason * which is the stop of the leaf data stack 9674123bd7SChris Mason */ 97123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 98123abc88SChris Mason struct btrfs_leaf *leaf) 99be0e5c09SChris Mason { 1007518a238SChris Mason u32 nr = btrfs_header_nritems(&leaf->header); 101be0e5c09SChris Mason if (nr == 0) 102123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 1030783fcfcSChris Mason return btrfs_item_offset(leaf->items + nr - 1); 104be0e5c09SChris Mason } 105be0e5c09SChris Mason 10674123bd7SChris Mason /* 10774123bd7SChris Mason * compare two keys in a memcmp fashion 10874123bd7SChris Mason */ 1099aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 110be0e5c09SChris Mason { 111e2fa7227SChris Mason struct btrfs_key k1; 112e2fa7227SChris Mason 113e2fa7227SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 114e2fa7227SChris Mason 115e2fa7227SChris Mason if (k1.objectid > k2->objectid) 116be0e5c09SChris Mason return 1; 117e2fa7227SChris Mason if (k1.objectid < k2->objectid) 118be0e5c09SChris Mason return -1; 119f254e52cSChris Mason if (k1.flags > k2->flags) 120f254e52cSChris Mason return 1; 121f254e52cSChris Mason if (k1.flags < k2->flags) 122f254e52cSChris Mason return -1; 12370b2befdSChris Mason if (k1.offset > k2->offset) 12470b2befdSChris Mason return 1; 12570b2befdSChris Mason if (k1.offset < k2->offset) 12670b2befdSChris Mason return -1; 127be0e5c09SChris Mason return 0; 128be0e5c09SChris Mason } 12974123bd7SChris Mason 130123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 131123abc88SChris Mason int level) 132aa5d6bedSChris Mason { 133234b63a0SChris Mason struct btrfs_node *parent = NULL; 134e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 135aa5d6bedSChris Mason int parent_slot; 1368d7be552SChris Mason int slot; 1378d7be552SChris Mason struct btrfs_key cpukey; 1387518a238SChris Mason u32 nritems = btrfs_header_nritems(&node->header); 139aa5d6bedSChris Mason 140aa5d6bedSChris Mason if (path->nodes[level + 1]) 141e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 142aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 1438d7be552SChris Mason slot = path->slots[level]; 1447518a238SChris Mason BUG_ON(nritems == 0); 1457518a238SChris Mason if (parent) { 146e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 147123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 148123abc88SChris Mason BUG_ON(memcmp(parent_key, &node->ptrs[0].key, 149e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1501d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1517518a238SChris Mason btrfs_header_blocknr(&node->header)); 152aa5d6bedSChris Mason } 153123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 1548d7be552SChris Mason if (slot != 0) { 1558d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key); 1568d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0); 1578d7be552SChris Mason } 1588d7be552SChris Mason if (slot < nritems - 1) { 1598d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key); 1608d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0); 161aa5d6bedSChris Mason } 162aa5d6bedSChris Mason return 0; 163aa5d6bedSChris Mason } 164aa5d6bedSChris Mason 165123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 166123abc88SChris Mason int level) 167aa5d6bedSChris Mason { 168e20d96d6SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); 169234b63a0SChris Mason struct btrfs_node *parent = NULL; 170aa5d6bedSChris Mason int parent_slot; 1718d7be552SChris Mason int slot = path->slots[0]; 1728d7be552SChris Mason struct btrfs_key cpukey; 1738d7be552SChris Mason 1747518a238SChris Mason u32 nritems = btrfs_header_nritems(&leaf->header); 175aa5d6bedSChris Mason 176aa5d6bedSChris Mason if (path->nodes[level + 1]) 177e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 178aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 179123abc88SChris Mason BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 1807518a238SChris Mason 1817518a238SChris Mason if (nritems == 0) 1827518a238SChris Mason return 0; 1837518a238SChris Mason 1847518a238SChris Mason if (parent) { 185e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 186123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 187aa5d6bedSChris Mason BUG_ON(memcmp(parent_key, &leaf->items[0].key, 188e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1891d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1907518a238SChris Mason btrfs_header_blocknr(&leaf->header)); 191aa5d6bedSChris Mason } 1928d7be552SChris Mason if (slot != 0) { 1938d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key); 1948d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0); 1958d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot - 1) != 1968d7be552SChris Mason btrfs_item_end(leaf->items + slot)); 197aa5d6bedSChris Mason } 1988d7be552SChris Mason if (slot < nritems - 1) { 1998d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key); 2008d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0); 2018d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot) != 2028d7be552SChris Mason btrfs_item_end(leaf->items + slot + 1)); 203aa5d6bedSChris Mason } 2048d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items) + 2058d7be552SChris Mason btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root)); 206aa5d6bedSChris Mason return 0; 207aa5d6bedSChris Mason } 208aa5d6bedSChris Mason 209123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 210123abc88SChris Mason int level) 211aa5d6bedSChris Mason { 2123eb0314dSChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 2133eb0314dSChris Mason if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, 2143eb0314dSChris Mason sizeof(node->header.fsid))) 2153eb0314dSChris Mason BUG(); 216aa5d6bedSChris Mason if (level == 0) 217123abc88SChris Mason return check_leaf(root, path, level); 218123abc88SChris Mason return check_node(root, path, level); 219aa5d6bedSChris Mason } 220aa5d6bedSChris Mason 22174123bd7SChris Mason /* 22274123bd7SChris Mason * search for key in the array p. items p are item_size apart 22374123bd7SChris Mason * and there are 'max' items in p 22474123bd7SChris Mason * the slot in the array is returned via slot, and it points to 22574123bd7SChris Mason * the place where you would insert key if it is not found in 22674123bd7SChris Mason * the array. 22774123bd7SChris Mason * 22874123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 22974123bd7SChris Mason */ 2309aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, 231be0e5c09SChris Mason int max, int *slot) 232be0e5c09SChris Mason { 233be0e5c09SChris Mason int low = 0; 234be0e5c09SChris Mason int high = max; 235be0e5c09SChris Mason int mid; 236be0e5c09SChris Mason int ret; 237e2fa7227SChris Mason struct btrfs_disk_key *tmp; 238be0e5c09SChris Mason 239be0e5c09SChris Mason while(low < high) { 240be0e5c09SChris Mason mid = (low + high) / 2; 241e2fa7227SChris Mason tmp = (struct btrfs_disk_key *)(p + mid * item_size); 242be0e5c09SChris Mason ret = comp_keys(tmp, key); 243be0e5c09SChris Mason 244be0e5c09SChris Mason if (ret < 0) 245be0e5c09SChris Mason low = mid + 1; 246be0e5c09SChris Mason else if (ret > 0) 247be0e5c09SChris Mason high = mid; 248be0e5c09SChris Mason else { 249be0e5c09SChris Mason *slot = mid; 250be0e5c09SChris Mason return 0; 251be0e5c09SChris Mason } 252be0e5c09SChris Mason } 253be0e5c09SChris Mason *slot = low; 254be0e5c09SChris Mason return 1; 255be0e5c09SChris Mason } 256be0e5c09SChris Mason 25797571fd0SChris Mason /* 25897571fd0SChris Mason * simple bin_search frontend that does the right thing for 25997571fd0SChris Mason * leaves vs nodes 26097571fd0SChris Mason */ 2619aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) 262be0e5c09SChris Mason { 2637518a238SChris Mason if (btrfs_is_leaf(c)) { 264234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 2650783fcfcSChris Mason return generic_bin_search((void *)l->items, 2660783fcfcSChris Mason sizeof(struct btrfs_item), 2677518a238SChris Mason key, btrfs_header_nritems(&c->header), 2687518a238SChris Mason slot); 269be0e5c09SChris Mason } else { 270123abc88SChris Mason return generic_bin_search((void *)c->ptrs, 271123abc88SChris Mason sizeof(struct btrfs_key_ptr), 2727518a238SChris Mason key, btrfs_header_nritems(&c->header), 2737518a238SChris Mason slot); 274be0e5c09SChris Mason } 275be0e5c09SChris Mason return -1; 276be0e5c09SChris Mason } 277be0e5c09SChris Mason 278e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root, 279e20d96d6SChris Mason struct buffer_head *parent_buf, 280bb803951SChris Mason int slot) 281bb803951SChris Mason { 282e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(parent_buf); 283bb803951SChris Mason if (slot < 0) 284bb803951SChris Mason return NULL; 2857518a238SChris Mason if (slot >= btrfs_header_nritems(&node->header)) 286bb803951SChris Mason return NULL; 2871d4f8a0cSChris Mason return read_tree_block(root, btrfs_node_blockptr(node, slot)); 288bb803951SChris Mason } 289bb803951SChris Mason 290e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 291e089f05cSChris Mason *root, struct btrfs_path *path, int level) 292bb803951SChris Mason { 293e20d96d6SChris Mason struct buffer_head *right_buf; 294e20d96d6SChris Mason struct buffer_head *mid_buf; 295e20d96d6SChris Mason struct buffer_head *left_buf; 296e20d96d6SChris Mason struct buffer_head *parent_buf = NULL; 297234b63a0SChris Mason struct btrfs_node *right = NULL; 298234b63a0SChris Mason struct btrfs_node *mid; 299234b63a0SChris Mason struct btrfs_node *left = NULL; 300234b63a0SChris Mason struct btrfs_node *parent = NULL; 301bb803951SChris Mason int ret = 0; 302bb803951SChris Mason int wret; 303bb803951SChris Mason int pslot; 304bb803951SChris Mason int orig_slot = path->slots[level]; 30579f95c82SChris Mason u64 orig_ptr; 306bb803951SChris Mason 307bb803951SChris Mason if (level == 0) 308bb803951SChris Mason return 0; 309bb803951SChris Mason 310bb803951SChris Mason mid_buf = path->nodes[level]; 311e20d96d6SChris Mason mid = btrfs_buffer_node(mid_buf); 3121d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 31379f95c82SChris Mason 314234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 315bb803951SChris Mason parent_buf = path->nodes[level + 1]; 316bb803951SChris Mason pslot = path->slots[level + 1]; 317bb803951SChris Mason 31840689478SChris Mason /* 31940689478SChris Mason * deal with the case where there is only one pointer in the root 32040689478SChris Mason * by promoting the node below to a root 32140689478SChris Mason */ 322bb803951SChris Mason if (!parent_buf) { 323e20d96d6SChris Mason struct buffer_head *child; 3247eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 325bb803951SChris Mason 3267518a238SChris Mason if (btrfs_header_nritems(&mid->header) != 1) 327bb803951SChris Mason return 0; 328bb803951SChris Mason 329bb803951SChris Mason /* promote the child to a root */ 330bb803951SChris Mason child = read_node_slot(root, mid_buf, 0); 331bb803951SChris Mason BUG_ON(!child); 332bb803951SChris Mason root->node = child; 333bb803951SChris Mason path->nodes[level] = NULL; 334d6025579SChris Mason clean_tree_block(trans, root, mid_buf); 335d6025579SChris Mason wait_on_buffer(mid_buf); 336bb803951SChris Mason /* once for the path */ 337234b63a0SChris Mason btrfs_block_release(root, mid_buf); 338bb803951SChris Mason /* once for the root ptr */ 339234b63a0SChris Mason btrfs_block_release(root, mid_buf); 340e089f05cSChris Mason return btrfs_free_extent(trans, root, blocknr, 1, 1); 341bb803951SChris Mason } 342e20d96d6SChris Mason parent = btrfs_buffer_node(parent_buf); 343bb803951SChris Mason 344123abc88SChris Mason if (btrfs_header_nritems(&mid->header) > 345123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 346bb803951SChris Mason return 0; 347bb803951SChris Mason 348bb803951SChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 349bb803951SChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 35079f95c82SChris Mason 35179f95c82SChris Mason /* first, try to make some room in the middle buffer */ 352bb803951SChris Mason if (left_buf) { 353e089f05cSChris Mason btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, 354e089f05cSChris Mason &left_buf); 355e20d96d6SChris Mason left = btrfs_buffer_node(left_buf); 3567518a238SChris Mason orig_slot += btrfs_header_nritems(&left->header); 357e089f05cSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 35879f95c82SChris Mason if (wret < 0) 35979f95c82SChris Mason ret = wret; 360bb803951SChris Mason } 36179f95c82SChris Mason 36279f95c82SChris Mason /* 36379f95c82SChris Mason * then try to empty the right most buffer into the middle 36479f95c82SChris Mason */ 365bb803951SChris Mason if (right_buf) { 366e089f05cSChris Mason btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, 367e089f05cSChris Mason &right_buf); 368e20d96d6SChris Mason right = btrfs_buffer_node(right_buf); 369e089f05cSChris Mason wret = push_node_left(trans, root, mid_buf, right_buf); 37079f95c82SChris Mason if (wret < 0) 37179f95c82SChris Mason ret = wret; 3727518a238SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 3737eccb903SChris Mason u64 blocknr = bh_blocknr(right_buf); 374e089f05cSChris Mason clean_tree_block(trans, root, right_buf); 375d6025579SChris Mason wait_on_buffer(right_buf); 376d6025579SChris Mason btrfs_block_release(root, right_buf); 377bb803951SChris Mason right_buf = NULL; 378bb803951SChris Mason right = NULL; 379e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 380e089f05cSChris Mason 1); 381bb803951SChris Mason if (wret) 382bb803951SChris Mason ret = wret; 383e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 384bb803951SChris Mason if (wret) 385bb803951SChris Mason ret = wret; 386bb803951SChris Mason } else { 387d6025579SChris Mason btrfs_memcpy(root, parent, 388d6025579SChris Mason &parent->ptrs[pslot + 1].key, 389123abc88SChris Mason &right->ptrs[0].key, 390e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 391d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 392bb803951SChris Mason } 393bb803951SChris Mason } 3947518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 1) { 39579f95c82SChris Mason /* 39679f95c82SChris Mason * we're not allowed to leave a node with one item in the 39779f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 39879f95c82SChris Mason * could try to delete the only pointer in this node. 39979f95c82SChris Mason * So, pull some keys from the left. 40079f95c82SChris Mason * There has to be a left pointer at this point because 40179f95c82SChris Mason * otherwise we would have pulled some pointers from the 40279f95c82SChris Mason * right 40379f95c82SChris Mason */ 40479f95c82SChris Mason BUG_ON(!left_buf); 405e089f05cSChris Mason wret = balance_node_right(trans, root, mid_buf, left_buf); 40679f95c82SChris Mason if (wret < 0) 40779f95c82SChris Mason ret = wret; 40879f95c82SChris Mason BUG_ON(wret == 1); 40979f95c82SChris Mason } 4107518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 0) { 41179f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 4127eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 413e089f05cSChris Mason clean_tree_block(trans, root, mid_buf); 414d6025579SChris Mason wait_on_buffer(mid_buf); 415d6025579SChris Mason btrfs_block_release(root, mid_buf); 416bb803951SChris Mason mid_buf = NULL; 417bb803951SChris Mason mid = NULL; 418e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 419bb803951SChris Mason if (wret) 420bb803951SChris Mason ret = wret; 421e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 422bb803951SChris Mason if (wret) 423bb803951SChris Mason ret = wret; 42479f95c82SChris Mason } else { 42579f95c82SChris Mason /* update the parent key to reflect our changes */ 426d6025579SChris Mason btrfs_memcpy(root, parent, 427d6025579SChris Mason &parent->ptrs[pslot].key, &mid->ptrs[0].key, 428e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 429d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 43079f95c82SChris Mason } 431bb803951SChris Mason 43279f95c82SChris Mason /* update the path */ 433bb803951SChris Mason if (left_buf) { 4347518a238SChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 435e20d96d6SChris Mason get_bh(left_buf); 436bb803951SChris Mason path->nodes[level] = left_buf; 437bb803951SChris Mason path->slots[level + 1] -= 1; 438bb803951SChris Mason path->slots[level] = orig_slot; 439bb803951SChris Mason if (mid_buf) 440234b63a0SChris Mason btrfs_block_release(root, mid_buf); 441bb803951SChris Mason } else { 4427518a238SChris Mason orig_slot -= btrfs_header_nritems(&left->header); 443bb803951SChris Mason path->slots[level] = orig_slot; 444bb803951SChris Mason } 445bb803951SChris Mason } 44679f95c82SChris Mason /* double check we haven't messed things up */ 447123abc88SChris Mason check_block(root, path, level); 448e20d96d6SChris Mason if (orig_ptr != 449e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 4501d4f8a0cSChris Mason path->slots[level])) 45179f95c82SChris Mason BUG(); 452bb803951SChris Mason 453bb803951SChris Mason if (right_buf) 454234b63a0SChris Mason btrfs_block_release(root, right_buf); 455bb803951SChris Mason if (left_buf) 456234b63a0SChris Mason btrfs_block_release(root, left_buf); 457bb803951SChris Mason return ret; 458bb803951SChris Mason } 459bb803951SChris Mason 460e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 461e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 462e66f709bSChris Mason struct btrfs_root *root, 463e66f709bSChris Mason struct btrfs_path *path, int level) 464e66f709bSChris Mason { 465e66f709bSChris Mason struct buffer_head *right_buf; 466e66f709bSChris Mason struct buffer_head *mid_buf; 467e66f709bSChris Mason struct buffer_head *left_buf; 468e66f709bSChris Mason struct buffer_head *parent_buf = NULL; 469e66f709bSChris Mason struct btrfs_node *right = NULL; 470e66f709bSChris Mason struct btrfs_node *mid; 471e66f709bSChris Mason struct btrfs_node *left = NULL; 472e66f709bSChris Mason struct btrfs_node *parent = NULL; 473e66f709bSChris Mason int ret = 0; 474e66f709bSChris Mason int wret; 475e66f709bSChris Mason int pslot; 476e66f709bSChris Mason int orig_slot = path->slots[level]; 477e66f709bSChris Mason u64 orig_ptr; 478e66f709bSChris Mason 479e66f709bSChris Mason if (level == 0) 480e66f709bSChris Mason return 1; 481e66f709bSChris Mason 482e66f709bSChris Mason mid_buf = path->nodes[level]; 483e66f709bSChris Mason mid = btrfs_buffer_node(mid_buf); 484e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 485e66f709bSChris Mason 486e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 487e66f709bSChris Mason parent_buf = path->nodes[level + 1]; 488e66f709bSChris Mason pslot = path->slots[level + 1]; 489e66f709bSChris Mason 490e66f709bSChris Mason if (!parent_buf) 491e66f709bSChris Mason return 1; 492e66f709bSChris Mason parent = btrfs_buffer_node(parent_buf); 493e66f709bSChris Mason 494e66f709bSChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 495e66f709bSChris Mason 496e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 497e66f709bSChris Mason if (left_buf) { 498e66f709bSChris Mason u32 left_nr; 499e66f709bSChris Mason left = btrfs_buffer_node(left_buf); 500e66f709bSChris Mason left_nr = btrfs_header_nritems(&left->header); 50133ade1f8SChris Mason if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 50233ade1f8SChris Mason wret = 1; 50333ade1f8SChris Mason } else { 50433ade1f8SChris Mason btrfs_cow_block(trans, root, left_buf, parent_buf, 50533ade1f8SChris Mason pslot - 1, &left_buf); 50633ade1f8SChris Mason left = btrfs_buffer_node(left_buf); 507e66f709bSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 50833ade1f8SChris Mason } 509e66f709bSChris Mason if (wret < 0) 510e66f709bSChris Mason ret = wret; 511e66f709bSChris Mason if (wret == 0) { 512e66f709bSChris Mason orig_slot += left_nr; 513e66f709bSChris Mason btrfs_memcpy(root, parent, 514e66f709bSChris Mason &parent->ptrs[pslot].key, 515e66f709bSChris Mason &mid->ptrs[0].key, 516e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 517e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 518e66f709bSChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 519e66f709bSChris Mason path->nodes[level] = left_buf; 520e66f709bSChris Mason path->slots[level + 1] -= 1; 521e66f709bSChris Mason path->slots[level] = orig_slot; 522e66f709bSChris Mason btrfs_block_release(root, mid_buf); 523e66f709bSChris Mason } else { 524e66f709bSChris Mason orig_slot -= 525e66f709bSChris Mason btrfs_header_nritems(&left->header); 526e66f709bSChris Mason path->slots[level] = orig_slot; 527e66f709bSChris Mason btrfs_block_release(root, left_buf); 528e66f709bSChris Mason } 529e66f709bSChris Mason check_node(root, path, level); 530e66f709bSChris Mason return 0; 531e66f709bSChris Mason } 532e66f709bSChris Mason btrfs_block_release(root, left_buf); 533e66f709bSChris Mason } 534e66f709bSChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 535e66f709bSChris Mason 536e66f709bSChris Mason /* 537e66f709bSChris Mason * then try to empty the right most buffer into the middle 538e66f709bSChris Mason */ 539e66f709bSChris Mason if (right_buf) { 54033ade1f8SChris Mason u32 right_nr; 541e66f709bSChris Mason right = btrfs_buffer_node(right_buf); 54233ade1f8SChris Mason right_nr = btrfs_header_nritems(&right->header); 54333ade1f8SChris Mason if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 54433ade1f8SChris Mason wret = 1; 54533ade1f8SChris Mason } else { 54633ade1f8SChris Mason btrfs_cow_block(trans, root, right_buf, 54733ade1f8SChris Mason parent_buf, pslot + 1, &right_buf); 54833ade1f8SChris Mason right = btrfs_buffer_node(right_buf); 54933ade1f8SChris Mason wret = balance_node_right(trans, root, 55033ade1f8SChris Mason right_buf, mid_buf); 55133ade1f8SChris Mason } 552e66f709bSChris Mason if (wret < 0) 553e66f709bSChris Mason ret = wret; 554e66f709bSChris Mason if (wret == 0) { 555e66f709bSChris Mason btrfs_memcpy(root, parent, 556e66f709bSChris Mason &parent->ptrs[pslot + 1].key, 557e66f709bSChris Mason &right->ptrs[0].key, 558e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 559e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 560e66f709bSChris Mason if (btrfs_header_nritems(&mid->header) <= orig_slot) { 561e66f709bSChris Mason path->nodes[level] = right_buf; 562e66f709bSChris Mason path->slots[level + 1] += 1; 563e66f709bSChris Mason path->slots[level] = orig_slot - 564e66f709bSChris Mason btrfs_header_nritems(&mid->header); 565e66f709bSChris Mason btrfs_block_release(root, mid_buf); 566e66f709bSChris Mason } else { 567e66f709bSChris Mason btrfs_block_release(root, right_buf); 568e66f709bSChris Mason } 569e66f709bSChris Mason check_node(root, path, level); 570e66f709bSChris Mason return 0; 571e66f709bSChris Mason } 572e66f709bSChris Mason btrfs_block_release(root, right_buf); 573e66f709bSChris Mason } 574e66f709bSChris Mason check_node(root, path, level); 575e66f709bSChris Mason return 1; 576e66f709bSChris Mason } 577e66f709bSChris Mason 57874123bd7SChris Mason /* 57974123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 58074123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 58174123bd7SChris Mason * level of the path (level 0) 58274123bd7SChris Mason * 58374123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 584aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 585aa5d6bedSChris Mason * search a negative error number is returned. 58697571fd0SChris Mason * 58797571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 58897571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 58997571fd0SChris Mason * possible) 59074123bd7SChris Mason */ 591e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 592e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 593e089f05cSChris Mason ins_len, int cow) 594be0e5c09SChris Mason { 595e20d96d6SChris Mason struct buffer_head *b; 596e20d96d6SChris Mason struct buffer_head *cow_buf; 597234b63a0SChris Mason struct btrfs_node *c; 598be0e5c09SChris Mason int slot; 599be0e5c09SChris Mason int ret; 600be0e5c09SChris Mason int level; 6015c680ed6SChris Mason 60222b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 60322b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 604bb803951SChris Mason again: 605bb803951SChris Mason b = root->node; 606e20d96d6SChris Mason get_bh(b); 607eb60ceacSChris Mason while (b) { 608e20d96d6SChris Mason c = btrfs_buffer_node(b); 609e20d96d6SChris Mason level = btrfs_header_level(&c->header); 61002217ed2SChris Mason if (cow) { 61102217ed2SChris Mason int wret; 612e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 613e20d96d6SChris Mason p->nodes[level + 1], 614e20d96d6SChris Mason p->slots[level + 1], 615e089f05cSChris Mason &cow_buf); 61602217ed2SChris Mason b = cow_buf; 6172c90e5d6SChris Mason c = btrfs_buffer_node(b); 61802217ed2SChris Mason } 61902217ed2SChris Mason BUG_ON(!cow && ins_len); 6202c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 6212c90e5d6SChris Mason WARN_ON(1); 6222c90e5d6SChris Mason level = btrfs_header_level(&c->header); 623eb60ceacSChris Mason p->nodes[level] = b; 624123abc88SChris Mason ret = check_block(root, p, level); 625aa5d6bedSChris Mason if (ret) 626aa5d6bedSChris Mason return -1; 627be0e5c09SChris Mason ret = bin_search(c, key, &slot); 6287518a238SChris Mason if (!btrfs_is_leaf(c)) { 629be0e5c09SChris Mason if (ret && slot > 0) 630be0e5c09SChris Mason slot -= 1; 631be0e5c09SChris Mason p->slots[level] = slot; 632d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 633d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 634e089f05cSChris Mason int sret = split_node(trans, root, p, level); 6355c680ed6SChris Mason BUG_ON(sret > 0); 6365c680ed6SChris Mason if (sret) 6375c680ed6SChris Mason return sret; 6385c680ed6SChris Mason b = p->nodes[level]; 639e20d96d6SChris Mason c = btrfs_buffer_node(b); 6405c680ed6SChris Mason slot = p->slots[level]; 641bb803951SChris Mason } else if (ins_len < 0) { 642e089f05cSChris Mason int sret = balance_level(trans, root, p, 643e089f05cSChris Mason level); 644bb803951SChris Mason if (sret) 645bb803951SChris Mason return sret; 646bb803951SChris Mason b = p->nodes[level]; 647bb803951SChris Mason if (!b) 648bb803951SChris Mason goto again; 649e20d96d6SChris Mason c = btrfs_buffer_node(b); 650bb803951SChris Mason slot = p->slots[level]; 6517518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 6525c680ed6SChris Mason } 6531d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 654be0e5c09SChris Mason } else { 655234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 656be0e5c09SChris Mason p->slots[level] = slot; 657123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 6580783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 659d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 660d4dbff95SChris Mason p, ins_len); 6615c680ed6SChris Mason BUG_ON(sret > 0); 6625c680ed6SChris Mason if (sret) 6635c680ed6SChris Mason return sret; 6645c680ed6SChris Mason } 665be0e5c09SChris Mason return ret; 666be0e5c09SChris Mason } 667be0e5c09SChris Mason } 668aa5d6bedSChris Mason return 1; 669be0e5c09SChris Mason } 670be0e5c09SChris Mason 67174123bd7SChris Mason /* 67274123bd7SChris Mason * adjust the pointers going up the tree, starting at level 67374123bd7SChris Mason * making sure the right key of each node is points to 'key'. 67474123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 67574123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 67674123bd7SChris Mason * higher levels 677aa5d6bedSChris Mason * 678aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 679aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 68074123bd7SChris Mason */ 681e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 682e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 683e089f05cSChris Mason *key, int level) 684be0e5c09SChris Mason { 685be0e5c09SChris Mason int i; 686aa5d6bedSChris Mason int ret = 0; 687234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 688234b63a0SChris Mason struct btrfs_node *t; 689be0e5c09SChris Mason int tslot = path->slots[i]; 690eb60ceacSChris Mason if (!path->nodes[i]) 691be0e5c09SChris Mason break; 692e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 693d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 694d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 695be0e5c09SChris Mason if (tslot != 0) 696be0e5c09SChris Mason break; 697be0e5c09SChris Mason } 698aa5d6bedSChris Mason return ret; 699be0e5c09SChris Mason } 700be0e5c09SChris Mason 70174123bd7SChris Mason /* 70274123bd7SChris Mason * try to push data from one node into the next node left in the 70379f95c82SChris Mason * tree. 704aa5d6bedSChris Mason * 705aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 706aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 70774123bd7SChris Mason */ 708e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 709e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 710e20d96d6SChris Mason buffer_head *src_buf) 711be0e5c09SChris Mason { 712e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 713e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 714be0e5c09SChris Mason int push_items = 0; 715bb803951SChris Mason int src_nritems; 716bb803951SChris Mason int dst_nritems; 717aa5d6bedSChris Mason int ret = 0; 718be0e5c09SChris Mason 7197518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7207518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 721123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 722eb60ceacSChris Mason if (push_items <= 0) { 723be0e5c09SChris Mason return 1; 724eb60ceacSChris Mason } 725be0e5c09SChris Mason 726be0e5c09SChris Mason if (src_nritems < push_items) 727be0e5c09SChris Mason push_items = src_nritems; 72879f95c82SChris Mason 729d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 730123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 731bb803951SChris Mason if (push_items < src_nritems) { 732d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 733e2fa7227SChris Mason (src_nritems - push_items) * 734123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 735bb803951SChris Mason } 7367518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 7377518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 738d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 739d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 740bb803951SChris Mason return ret; 741be0e5c09SChris Mason } 742be0e5c09SChris Mason 74397571fd0SChris Mason /* 74479f95c82SChris Mason * try to push data from one node into the next node right in the 74579f95c82SChris Mason * tree. 74679f95c82SChris Mason * 74779f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 74879f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 74979f95c82SChris Mason * 75079f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 75179f95c82SChris Mason */ 752e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 753e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 754e20d96d6SChris Mason struct buffer_head *src_buf) 75579f95c82SChris Mason { 756e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 757e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 75879f95c82SChris Mason int push_items = 0; 75979f95c82SChris Mason int max_push; 76079f95c82SChris Mason int src_nritems; 76179f95c82SChris Mason int dst_nritems; 76279f95c82SChris Mason int ret = 0; 76379f95c82SChris Mason 7647518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7657518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 766123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 76779f95c82SChris Mason if (push_items <= 0) { 76879f95c82SChris Mason return 1; 76979f95c82SChris Mason } 77079f95c82SChris Mason 77179f95c82SChris Mason max_push = src_nritems / 2 + 1; 77279f95c82SChris Mason /* don't try to empty the node */ 77379f95c82SChris Mason if (max_push > src_nritems) 77479f95c82SChris Mason return 1; 77579f95c82SChris Mason if (max_push < push_items) 77679f95c82SChris Mason push_items = max_push; 77779f95c82SChris Mason 778d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 779123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 780d6025579SChris Mason 781d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 782d6025579SChris Mason src->ptrs + src_nritems - push_items, 783123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 78479f95c82SChris Mason 7857518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 7867518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 78779f95c82SChris Mason 788d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 789d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 79079f95c82SChris Mason return ret; 79179f95c82SChris Mason } 79279f95c82SChris Mason 79379f95c82SChris Mason /* 79497571fd0SChris Mason * helper function to insert a new root level in the tree. 79597571fd0SChris Mason * A new node is allocated, and a single item is inserted to 79697571fd0SChris Mason * point to the existing root 797aa5d6bedSChris Mason * 798aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 79997571fd0SChris Mason */ 800e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 801e089f05cSChris Mason *root, struct btrfs_path *path, int level) 80274123bd7SChris Mason { 803e20d96d6SChris Mason struct buffer_head *t; 804234b63a0SChris Mason struct btrfs_node *lower; 805234b63a0SChris Mason struct btrfs_node *c; 806e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 8075c680ed6SChris Mason 8085c680ed6SChris Mason BUG_ON(path->nodes[level]); 8095c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 8105c680ed6SChris Mason 81131f3c99bSChris Mason t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr); 812e20d96d6SChris Mason c = btrfs_buffer_node(t); 813123abc88SChris Mason memset(c, 0, root->blocksize); 8147518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 8157518a238SChris Mason btrfs_set_header_level(&c->header, level); 8167eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 8177f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 8184d775673SChris Mason btrfs_set_header_owner(&c->header, root->root_key.objectid); 819e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 8203eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 8213eb0314dSChris Mason sizeof(c->header.fsid)); 8227518a238SChris Mason if (btrfs_is_leaf(lower)) 823234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 82474123bd7SChris Mason else 825123abc88SChris Mason lower_key = &lower->ptrs[0].key; 826d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 827d6025579SChris Mason sizeof(struct btrfs_disk_key)); 8287eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 829d5719762SChris Mason 830d6025579SChris Mason btrfs_mark_buffer_dirty(t); 831d5719762SChris Mason 832cfaa7295SChris Mason /* the super has an extra ref to root->node */ 833234b63a0SChris Mason btrfs_block_release(root, root->node); 83474123bd7SChris Mason root->node = t; 835e20d96d6SChris Mason get_bh(t); 83674123bd7SChris Mason path->nodes[level] = t; 83774123bd7SChris Mason path->slots[level] = 0; 83874123bd7SChris Mason return 0; 83974123bd7SChris Mason } 8405c680ed6SChris Mason 8415c680ed6SChris Mason /* 8425c680ed6SChris Mason * worker function to insert a single pointer in a node. 8435c680ed6SChris Mason * the node should have enough room for the pointer already 84497571fd0SChris Mason * 8455c680ed6SChris Mason * slot and level indicate where you want the key to go, and 8465c680ed6SChris Mason * blocknr is the block the key points to. 847aa5d6bedSChris Mason * 848aa5d6bedSChris Mason * returns zero on success and < 0 on any error 8495c680ed6SChris Mason */ 850e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 851e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 852e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 8535c680ed6SChris Mason { 854234b63a0SChris Mason struct btrfs_node *lower; 8555c680ed6SChris Mason int nritems; 8565c680ed6SChris Mason 8575c680ed6SChris Mason BUG_ON(!path->nodes[level]); 858e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 8597518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 86074123bd7SChris Mason if (slot > nritems) 86174123bd7SChris Mason BUG(); 862123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 86374123bd7SChris Mason BUG(); 86474123bd7SChris Mason if (slot != nritems) { 865d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 866d6025579SChris Mason lower->ptrs + slot, 867123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 86874123bd7SChris Mason } 869d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 870d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 8711d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 8727518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 873d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 874*098f59c2SChris Mason check_node(root, path, level); 87574123bd7SChris Mason return 0; 87674123bd7SChris Mason } 87774123bd7SChris Mason 87897571fd0SChris Mason /* 87997571fd0SChris Mason * split the node at the specified level in path in two. 88097571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 88197571fd0SChris Mason * 88297571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 88397571fd0SChris Mason * left and right, if either one works, it returns right away. 884aa5d6bedSChris Mason * 885aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 88697571fd0SChris Mason */ 887e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 888e089f05cSChris Mason *root, struct btrfs_path *path, int level) 889be0e5c09SChris Mason { 890e20d96d6SChris Mason struct buffer_head *t; 891234b63a0SChris Mason struct btrfs_node *c; 892e20d96d6SChris Mason struct buffer_head *split_buffer; 893234b63a0SChris Mason struct btrfs_node *split; 894be0e5c09SChris Mason int mid; 8955c680ed6SChris Mason int ret; 896aa5d6bedSChris Mason int wret; 8977518a238SChris Mason u32 c_nritems; 898be0e5c09SChris Mason 8995c680ed6SChris Mason t = path->nodes[level]; 900e20d96d6SChris Mason c = btrfs_buffer_node(t); 9015c680ed6SChris Mason if (t == root->node) { 9025c680ed6SChris Mason /* trying to split the root, lets make a new one */ 903e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 9045c680ed6SChris Mason if (ret) 9055c680ed6SChris Mason return ret; 906e66f709bSChris Mason } else { 907e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 908e66f709bSChris Mason t = path->nodes[level]; 909e66f709bSChris Mason c = btrfs_buffer_node(t); 910e66f709bSChris Mason if (!ret && 911e66f709bSChris Mason btrfs_header_nritems(&c->header) < 912e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 913e66f709bSChris Mason return 0; 9145c680ed6SChris Mason } 915e66f709bSChris Mason 9167518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 91731f3c99bSChris Mason split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr); 918e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 9197518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 9209a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 9217eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 9227f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 9234d775673SChris Mason btrfs_set_header_owner(&split->header, root->root_key.objectid); 9243eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 9253eb0314dSChris Mason sizeof(split->header.fsid)); 9267518a238SChris Mason mid = (c_nritems + 1) / 2; 927d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 928123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 9297518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 9307518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 931aa5d6bedSChris Mason ret = 0; 932aa5d6bedSChris Mason 933d6025579SChris Mason btrfs_mark_buffer_dirty(t); 934d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 935e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 9367eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 937123abc88SChris Mason level + 1); 938aa5d6bedSChris Mason if (wret) 939aa5d6bedSChris Mason ret = wret; 940aa5d6bedSChris Mason 9415de08d7dSChris Mason if (path->slots[level] >= mid) { 9425c680ed6SChris Mason path->slots[level] -= mid; 943234b63a0SChris Mason btrfs_block_release(root, t); 9445c680ed6SChris Mason path->nodes[level] = split_buffer; 9455c680ed6SChris Mason path->slots[level + 1] += 1; 946eb60ceacSChris Mason } else { 947234b63a0SChris Mason btrfs_block_release(root, split_buffer); 948be0e5c09SChris Mason } 949aa5d6bedSChris Mason return ret; 950be0e5c09SChris Mason } 951be0e5c09SChris Mason 95274123bd7SChris Mason /* 95374123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 95474123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 95574123bd7SChris Mason * space used both by the item structs and the item data 95674123bd7SChris Mason */ 957234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 958be0e5c09SChris Mason { 959be0e5c09SChris Mason int data_len; 960d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 961d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 962be0e5c09SChris Mason 963be0e5c09SChris Mason if (!nr) 964be0e5c09SChris Mason return 0; 9650783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 9660783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 9670783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 968d4dbff95SChris Mason WARN_ON(data_len < 0); 969be0e5c09SChris Mason return data_len; 970be0e5c09SChris Mason } 971be0e5c09SChris Mason 97274123bd7SChris Mason /* 973d4dbff95SChris Mason * The space between the end of the leaf items and 974d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 975d4dbff95SChris Mason * the leaf has left for both items and data 976d4dbff95SChris Mason */ 977d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 978d4dbff95SChris Mason { 979d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 980d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 981d4dbff95SChris Mason } 982d4dbff95SChris Mason 983d4dbff95SChris Mason /* 98400ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 98500ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 986aa5d6bedSChris Mason * 987aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 988aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 98900ec4c51SChris Mason */ 990e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 991e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 99200ec4c51SChris Mason { 993e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 994e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 995234b63a0SChris Mason struct btrfs_leaf *right; 996e20d96d6SChris Mason struct buffer_head *right_buf; 997e20d96d6SChris Mason struct buffer_head *upper; 998e20d96d6SChris Mason struct btrfs_node *upper_node; 99900ec4c51SChris Mason int slot; 100000ec4c51SChris Mason int i; 100100ec4c51SChris Mason int free_space; 100200ec4c51SChris Mason int push_space = 0; 100300ec4c51SChris Mason int push_items = 0; 10040783fcfcSChris Mason struct btrfs_item *item; 10057518a238SChris Mason u32 left_nritems; 10067518a238SChris Mason u32 right_nritems; 100700ec4c51SChris Mason 100800ec4c51SChris Mason slot = path->slots[1]; 100900ec4c51SChris Mason if (!path->nodes[1]) { 101000ec4c51SChris Mason return 1; 101100ec4c51SChris Mason } 101200ec4c51SChris Mason upper = path->nodes[1]; 1013e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1014e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 101500ec4c51SChris Mason return 1; 101600ec4c51SChris Mason } 1017e20d96d6SChris Mason right_buf = read_tree_block(root, 1018e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 1019e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1020123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10210783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1022234b63a0SChris Mason btrfs_block_release(root, right_buf); 102300ec4c51SChris Mason return 1; 102400ec4c51SChris Mason } 102502217ed2SChris Mason /* cow and double check */ 1026e089f05cSChris Mason btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); 1027e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1028123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10290783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1030234b63a0SChris Mason btrfs_block_release(root, right_buf); 103102217ed2SChris Mason return 1; 103202217ed2SChris Mason } 103302217ed2SChris Mason 10347518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1035a429e513SChris Mason if (left_nritems == 0) { 1036a429e513SChris Mason btrfs_block_release(root, right_buf); 1037a429e513SChris Mason return 1; 1038a429e513SChris Mason } 1039a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 104000ec4c51SChris Mason item = left->items + i; 104100ec4c51SChris Mason if (path->slots[0] == i) 104200ec4c51SChris Mason push_space += data_size + sizeof(*item); 10430783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 10440783fcfcSChris Mason free_space) 104500ec4c51SChris Mason break; 104600ec4c51SChris Mason push_items++; 10470783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 104800ec4c51SChris Mason } 104900ec4c51SChris Mason if (push_items == 0) { 1050234b63a0SChris Mason btrfs_block_release(root, right_buf); 105100ec4c51SChris Mason return 1; 105200ec4c51SChris Mason } 1053a429e513SChris Mason if (push_items == left_nritems) 1054a429e513SChris Mason WARN_ON(1); 10557518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 105600ec4c51SChris Mason /* push left to right */ 10570783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1058123abc88SChris Mason push_space -= leaf_data_end(root, left); 105900ec4c51SChris Mason /* make room in the right data area */ 1060d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1061d6025579SChris Mason leaf_data_end(root, right) - push_space, 1062d6025579SChris Mason btrfs_leaf_data(right) + 1063d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1064d6025579SChris Mason leaf_data_end(root, right)); 106500ec4c51SChris Mason /* copy from the left data area */ 1066d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1067d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1068d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1069d6025579SChris Mason push_space); 1070d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 10710783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 107200ec4c51SChris Mason /* copy the items from left to right */ 1073d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1074d6025579SChris Mason left_nritems - push_items, 10750783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 107600ec4c51SChris Mason 107700ec4c51SChris Mason /* update the item pointers */ 10787518a238SChris Mason right_nritems += push_items; 10797518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1080123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 10817518a238SChris Mason for (i = 0; i < right_nritems; i++) { 10820783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 10830783fcfcSChris Mason btrfs_item_size(right->items + i)); 10840783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 108500ec4c51SChris Mason } 10867518a238SChris Mason left_nritems -= push_items; 10877518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 108800ec4c51SChris Mason 1089d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1090d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1091a429e513SChris Mason 1092d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1093e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1094d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 109502217ed2SChris Mason 109600ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 10977518a238SChris Mason if (path->slots[0] >= left_nritems) { 10987518a238SChris Mason path->slots[0] -= left_nritems; 1099234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 110000ec4c51SChris Mason path->nodes[0] = right_buf; 110100ec4c51SChris Mason path->slots[1] += 1; 110200ec4c51SChris Mason } else { 1103234b63a0SChris Mason btrfs_block_release(root, right_buf); 110400ec4c51SChris Mason } 1105*098f59c2SChris Mason if (path->nodes[1]) 1106*098f59c2SChris Mason check_node(root, path, 1); 110700ec4c51SChris Mason return 0; 110800ec4c51SChris Mason } 110900ec4c51SChris Mason /* 111074123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 111174123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 111274123bd7SChris Mason */ 1113e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1114e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1115be0e5c09SChris Mason { 1116e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1117e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1118e20d96d6SChris Mason struct buffer_head *t; 1119234b63a0SChris Mason struct btrfs_leaf *left; 1120be0e5c09SChris Mason int slot; 1121be0e5c09SChris Mason int i; 1122be0e5c09SChris Mason int free_space; 1123be0e5c09SChris Mason int push_space = 0; 1124be0e5c09SChris Mason int push_items = 0; 11250783fcfcSChris Mason struct btrfs_item *item; 11267518a238SChris Mason u32 old_left_nritems; 1127aa5d6bedSChris Mason int ret = 0; 1128aa5d6bedSChris Mason int wret; 1129be0e5c09SChris Mason 1130be0e5c09SChris Mason slot = path->slots[1]; 1131be0e5c09SChris Mason if (slot == 0) { 1132be0e5c09SChris Mason return 1; 1133be0e5c09SChris Mason } 1134be0e5c09SChris Mason if (!path->nodes[1]) { 1135be0e5c09SChris Mason return 1; 1136be0e5c09SChris Mason } 1137e20d96d6SChris Mason t = read_tree_block(root, 1138e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1139e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1140123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11410783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1142234b63a0SChris Mason btrfs_block_release(root, t); 1143be0e5c09SChris Mason return 1; 1144be0e5c09SChris Mason } 114502217ed2SChris Mason 114602217ed2SChris Mason /* cow and double check */ 1147e089f05cSChris Mason btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 1148e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1149123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11500783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1151234b63a0SChris Mason btrfs_block_release(root, t); 115202217ed2SChris Mason return 1; 115302217ed2SChris Mason } 115402217ed2SChris Mason 1155a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1156a429e513SChris Mason btrfs_block_release(root, t); 1157a429e513SChris Mason return 1; 1158a429e513SChris Mason } 1159a429e513SChris Mason 1160a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1161be0e5c09SChris Mason item = right->items + i; 1162be0e5c09SChris Mason if (path->slots[0] == i) 1163be0e5c09SChris Mason push_space += data_size + sizeof(*item); 11640783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 11650783fcfcSChris Mason free_space) 1166be0e5c09SChris Mason break; 1167be0e5c09SChris Mason push_items++; 11680783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1169be0e5c09SChris Mason } 1170be0e5c09SChris Mason if (push_items == 0) { 1171234b63a0SChris Mason btrfs_block_release(root, t); 1172be0e5c09SChris Mason return 1; 1173be0e5c09SChris Mason } 1174a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1175a429e513SChris Mason WARN_ON(1); 1176be0e5c09SChris Mason /* push data from right to left */ 1177d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1178d6025579SChris Mason btrfs_header_nritems(&left->header), 11790783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1180123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 11810783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1182d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1183d6025579SChris Mason leaf_data_end(root, left) - push_space, 1184123abc88SChris Mason btrfs_leaf_data(right) + 1185123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1186be0e5c09SChris Mason push_space); 11877518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1188eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1189eb60ceacSChris Mason 1190be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1191123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1192123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1193123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 11940783fcfcSChris Mason btrfs_item_offset(left->items + 11950783fcfcSChris Mason old_left_nritems - 1))); 1196be0e5c09SChris Mason } 11977518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1198be0e5c09SChris Mason 1199be0e5c09SChris Mason /* fixup right node */ 12000783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1201123abc88SChris Mason leaf_data_end(root, right); 1202d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1203d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1204d6025579SChris Mason btrfs_leaf_data(right) + 1205123abc88SChris Mason leaf_data_end(root, right), push_space); 1206d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 12077518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 12080783fcfcSChris Mason sizeof(struct btrfs_item)); 12097518a238SChris Mason btrfs_set_header_nritems(&right->header, 12107518a238SChris Mason btrfs_header_nritems(&right->header) - 12117518a238SChris Mason push_items); 1212123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1213eb60ceacSChris Mason 12147518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 12150783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 12160783fcfcSChris Mason btrfs_item_size(right->items + i)); 12170783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1218be0e5c09SChris Mason } 1219eb60ceacSChris Mason 1220d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1221d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1222*098f59c2SChris Mason 1223e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1224aa5d6bedSChris Mason if (wret) 1225aa5d6bedSChris Mason ret = wret; 1226be0e5c09SChris Mason 1227be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1228be0e5c09SChris Mason if (path->slots[0] < push_items) { 1229be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1230234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1231eb60ceacSChris Mason path->nodes[0] = t; 1232be0e5c09SChris Mason path->slots[1] -= 1; 1233be0e5c09SChris Mason } else { 1234234b63a0SChris Mason btrfs_block_release(root, t); 1235be0e5c09SChris Mason path->slots[0] -= push_items; 1236be0e5c09SChris Mason } 1237eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1238*098f59c2SChris Mason if (path->nodes[1]) 1239*098f59c2SChris Mason check_node(root, path, 1); 1240aa5d6bedSChris Mason return ret; 1241be0e5c09SChris Mason } 1242be0e5c09SChris Mason 124374123bd7SChris Mason /* 124474123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 124574123bd7SChris Mason * available for the resulting leaf level of the path. 1246aa5d6bedSChris Mason * 1247aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 124874123bd7SChris Mason */ 1249e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1250d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1251d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1252be0e5c09SChris Mason { 1253e20d96d6SChris Mason struct buffer_head *l_buf; 1254234b63a0SChris Mason struct btrfs_leaf *l; 12557518a238SChris Mason u32 nritems; 1256eb60ceacSChris Mason int mid; 1257eb60ceacSChris Mason int slot; 1258234b63a0SChris Mason struct btrfs_leaf *right; 1259e20d96d6SChris Mason struct buffer_head *right_buffer; 12600783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1261be0e5c09SChris Mason int data_copy_size; 1262be0e5c09SChris Mason int rt_data_off; 1263be0e5c09SChris Mason int i; 1264d4dbff95SChris Mason int ret = 0; 1265aa5d6bedSChris Mason int wret; 1266d4dbff95SChris Mason int double_split = 0; 1267d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1268be0e5c09SChris Mason 126940689478SChris Mason /* first try to make some room by pushing left and right */ 1270e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1271eaee50e8SChris Mason if (wret < 0) 1272eaee50e8SChris Mason return wret; 1273eaee50e8SChris Mason if (wret) { 1274e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1275eaee50e8SChris Mason if (wret < 0) 1276eaee50e8SChris Mason return wret; 1277eaee50e8SChris Mason } 1278eb60ceacSChris Mason l_buf = path->nodes[0]; 1279e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1280aa5d6bedSChris Mason 1281aa5d6bedSChris Mason /* did the pushes work? */ 1282123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1283123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1284be0e5c09SChris Mason return 0; 1285aa5d6bedSChris Mason 12865c680ed6SChris Mason if (!path->nodes[1]) { 1287e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 12885c680ed6SChris Mason if (ret) 12895c680ed6SChris Mason return ret; 12905c680ed6SChris Mason } 1291eb60ceacSChris Mason slot = path->slots[0]; 12927518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1293eb60ceacSChris Mason mid = (nritems + 1)/ 2; 129431f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 1295eb60ceacSChris Mason BUG_ON(!right_buffer); 1296e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1297123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 12987eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 12997f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 13004d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 13017518a238SChris Mason btrfs_set_header_level(&right->header, 0); 13023eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 13033eb0314dSChris Mason sizeof(right->header.fsid)); 1304d4dbff95SChris Mason if (mid <= slot) { 1305d4dbff95SChris Mason if (nritems == 1 || 1306d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1307d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1308d4dbff95SChris Mason if (slot >= nritems) { 1309d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1310d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1311d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1312d4dbff95SChris Mason &disk_key, 13137eccb903SChris Mason bh_blocknr(right_buffer), 1314d4dbff95SChris Mason path->slots[1] + 1, 1); 1315d4dbff95SChris Mason if (wret) 1316d4dbff95SChris Mason ret = wret; 1317d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1318d4dbff95SChris Mason path->nodes[0] = right_buffer; 1319d4dbff95SChris Mason path->slots[0] = 0; 1320d4dbff95SChris Mason path->slots[1] += 1; 1321d4dbff95SChris Mason return ret; 1322d4dbff95SChris Mason } 1323d4dbff95SChris Mason mid = slot; 1324d4dbff95SChris Mason double_split = 1; 1325d4dbff95SChris Mason } 1326d4dbff95SChris Mason } else { 1327d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1328d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1329d4dbff95SChris Mason if (slot == 0) { 1330d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1331d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1332d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1333d4dbff95SChris Mason &disk_key, 13347eccb903SChris Mason bh_blocknr(right_buffer), 1335*098f59c2SChris Mason path->slots[1], 1); 1336d4dbff95SChris Mason if (wret) 1337d4dbff95SChris Mason ret = wret; 1338d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1339d4dbff95SChris Mason path->nodes[0] = right_buffer; 1340d4dbff95SChris Mason path->slots[0] = 0; 1341a429e513SChris Mason if (path->slots[1] == 0) { 1342a429e513SChris Mason wret = fixup_low_keys(trans, root, 1343a429e513SChris Mason path, &disk_key, 1); 1344a429e513SChris Mason if (wret) 1345a429e513SChris Mason ret = wret; 1346a429e513SChris Mason } 1347d4dbff95SChris Mason return ret; 1348d4dbff95SChris Mason } 1349d4dbff95SChris Mason mid = slot; 1350d4dbff95SChris Mason double_split = 1; 1351d4dbff95SChris Mason } 1352d4dbff95SChris Mason } 1353d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1354123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1355123abc88SChris Mason leaf_data_end(root, l); 1356d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 13570783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1358d6025579SChris Mason btrfs_memcpy(root, right, 1359d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1360123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1361123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1362123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1363123abc88SChris Mason btrfs_item_end(l->items + mid); 136474123bd7SChris Mason 13650783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1366123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 13670783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 13680783fcfcSChris Mason } 136974123bd7SChris Mason 13707518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1371aa5d6bedSChris Mason ret = 0; 1372e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 13737eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1374aa5d6bedSChris Mason if (wret) 1375aa5d6bedSChris Mason ret = wret; 1376d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1377d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1378eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1379be0e5c09SChris Mason if (mid <= slot) { 1380234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1381eb60ceacSChris Mason path->nodes[0] = right_buffer; 1382be0e5c09SChris Mason path->slots[0] -= mid; 1383be0e5c09SChris Mason path->slots[1] += 1; 1384eb60ceacSChris Mason } else 1385234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1386eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1387*098f59c2SChris Mason check_node(root, path, 1); 1388d4dbff95SChris Mason 1389d4dbff95SChris Mason if (!double_split) 1390d4dbff95SChris Mason return ret; 139131f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 1392d4dbff95SChris Mason BUG_ON(!right_buffer); 1393d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1394d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 13957eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1396d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 13974d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 1398d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 13993eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 14003eb0314dSChris Mason sizeof(right->header.fsid)); 1401d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1402d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1403d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1404d4dbff95SChris Mason &disk_key, 14057eccb903SChris Mason bh_blocknr(right_buffer), 1406d4dbff95SChris Mason path->slots[1], 1); 1407d4dbff95SChris Mason if (wret) 1408d4dbff95SChris Mason ret = wret; 1409a429e513SChris Mason if (path->slots[1] == 0) { 1410a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1411a429e513SChris Mason if (wret) 1412a429e513SChris Mason ret = wret; 1413a429e513SChris Mason } 1414d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1415d4dbff95SChris Mason path->nodes[0] = right_buffer; 1416d4dbff95SChris Mason path->slots[0] = 0; 1417d4dbff95SChris Mason check_node(root, path, 1); 1418d4dbff95SChris Mason check_leaf(root, path, 0); 1419be0e5c09SChris Mason return ret; 1420be0e5c09SChris Mason } 1421be0e5c09SChris Mason 1422b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1423b18c6685SChris Mason struct btrfs_root *root, 1424b18c6685SChris Mason struct btrfs_path *path, 1425b18c6685SChris Mason u32 new_size) 1426b18c6685SChris Mason { 1427b18c6685SChris Mason int ret = 0; 1428b18c6685SChris Mason int slot; 1429b18c6685SChris Mason int slot_orig; 1430b18c6685SChris Mason struct btrfs_leaf *leaf; 1431b18c6685SChris Mason struct buffer_head *leaf_buf; 1432b18c6685SChris Mason u32 nritems; 1433b18c6685SChris Mason unsigned int data_end; 1434b18c6685SChris Mason unsigned int old_data_start; 1435b18c6685SChris Mason unsigned int old_size; 1436b18c6685SChris Mason unsigned int size_diff; 1437b18c6685SChris Mason int i; 1438b18c6685SChris Mason 1439b18c6685SChris Mason slot_orig = path->slots[0]; 1440b18c6685SChris Mason leaf_buf = path->nodes[0]; 1441b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1442b18c6685SChris Mason 1443b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1444b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1445b18c6685SChris Mason 1446b18c6685SChris Mason slot = path->slots[0]; 1447b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1448b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1449b18c6685SChris Mason BUG_ON(old_size <= new_size); 1450b18c6685SChris Mason size_diff = old_size - new_size; 1451b18c6685SChris Mason 1452b18c6685SChris Mason BUG_ON(slot < 0); 1453b18c6685SChris Mason BUG_ON(slot >= nritems); 1454b18c6685SChris Mason 1455b18c6685SChris Mason /* 1456b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1457b18c6685SChris Mason */ 1458b18c6685SChris Mason /* first correct the data pointers */ 1459b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1460b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1461b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1462b18c6685SChris Mason ioff + size_diff); 1463b18c6685SChris Mason } 1464b18c6685SChris Mason /* shift the data */ 1465b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1466b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1467b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1468b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1469b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1470b18c6685SChris Mason 1471b18c6685SChris Mason ret = 0; 1472b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1473b18c6685SChris Mason BUG(); 1474b18c6685SChris Mason check_leaf(root, path, 0); 1475b18c6685SChris Mason return ret; 1476b18c6685SChris Mason } 1477b18c6685SChris Mason 14786567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 14796567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 14806567e837SChris Mason { 14816567e837SChris Mason int ret = 0; 14826567e837SChris Mason int slot; 14836567e837SChris Mason int slot_orig; 14846567e837SChris Mason struct btrfs_leaf *leaf; 14856567e837SChris Mason struct buffer_head *leaf_buf; 14866567e837SChris Mason u32 nritems; 14876567e837SChris Mason unsigned int data_end; 14886567e837SChris Mason unsigned int old_data; 14896567e837SChris Mason unsigned int old_size; 14906567e837SChris Mason int i; 14916567e837SChris Mason 14926567e837SChris Mason slot_orig = path->slots[0]; 14936567e837SChris Mason leaf_buf = path->nodes[0]; 14946567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 14956567e837SChris Mason 14966567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 14976567e837SChris Mason data_end = leaf_data_end(root, leaf); 14986567e837SChris Mason 14996567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 15006567e837SChris Mason BUG(); 15016567e837SChris Mason slot = path->slots[0]; 15026567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 15036567e837SChris Mason 15046567e837SChris Mason BUG_ON(slot < 0); 15056567e837SChris Mason BUG_ON(slot >= nritems); 15066567e837SChris Mason 15076567e837SChris Mason /* 15086567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 15096567e837SChris Mason */ 15106567e837SChris Mason /* first correct the data pointers */ 15116567e837SChris Mason for (i = slot; i < nritems; i++) { 15126567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 15136567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 15146567e837SChris Mason ioff - data_size); 15156567e837SChris Mason } 15166567e837SChris Mason /* shift the data */ 15176567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 15186567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 15196567e837SChris Mason data_end, old_data - data_end); 15206567e837SChris Mason data_end = old_data; 15216567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 15226567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 15236567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 15246567e837SChris Mason 15256567e837SChris Mason ret = 0; 15266567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 15276567e837SChris Mason BUG(); 15286567e837SChris Mason check_leaf(root, path, 0); 15296567e837SChris Mason return ret; 15306567e837SChris Mason } 15316567e837SChris Mason 153274123bd7SChris Mason /* 153374123bd7SChris Mason * Given a key and some data, insert an item into the tree. 153474123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 153574123bd7SChris Mason */ 1536e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1537e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1538e089f05cSChris Mason *cpu_key, u32 data_size) 1539be0e5c09SChris Mason { 1540aa5d6bedSChris Mason int ret = 0; 1541be0e5c09SChris Mason int slot; 1542eb60ceacSChris Mason int slot_orig; 1543234b63a0SChris Mason struct btrfs_leaf *leaf; 1544e20d96d6SChris Mason struct buffer_head *leaf_buf; 15457518a238SChris Mason u32 nritems; 1546be0e5c09SChris Mason unsigned int data_end; 1547e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1548e2fa7227SChris Mason 1549e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1550be0e5c09SChris Mason 155174123bd7SChris Mason /* create a root if there isn't one */ 15525c680ed6SChris Mason if (!root->node) 1553cfaa7295SChris Mason BUG(); 1554e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1555eb60ceacSChris Mason if (ret == 0) { 1556f0930a37SChris Mason return -EEXIST; 1557aa5d6bedSChris Mason } 1558ed2ff2cbSChris Mason if (ret < 0) 1559ed2ff2cbSChris Mason goto out; 1560be0e5c09SChris Mason 156162e2749eSChris Mason slot_orig = path->slots[0]; 156262e2749eSChris Mason leaf_buf = path->nodes[0]; 1563e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 156474123bd7SChris Mason 15657518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1566123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1567eb60ceacSChris Mason 1568123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1569d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1570be0e5c09SChris Mason BUG(); 1571d4dbff95SChris Mason } 157262e2749eSChris Mason slot = path->slots[0]; 1573eb60ceacSChris Mason BUG_ON(slot < 0); 1574be0e5c09SChris Mason if (slot != nritems) { 1575be0e5c09SChris Mason int i; 15760783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1577be0e5c09SChris Mason 1578be0e5c09SChris Mason /* 1579be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1580be0e5c09SChris Mason */ 1581be0e5c09SChris Mason /* first correct the data pointers */ 15820783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1583123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 15840783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 15850783fcfcSChris Mason ioff - data_size); 15860783fcfcSChris Mason } 1587be0e5c09SChris Mason 1588be0e5c09SChris Mason /* shift the items */ 1589d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1590d6025579SChris Mason leaf->items + slot, 15910783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1592be0e5c09SChris Mason 1593be0e5c09SChris Mason /* shift the data */ 1594d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1595d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1596be0e5c09SChris Mason data_end, old_data - data_end); 1597be0e5c09SChris Mason data_end = old_data; 1598be0e5c09SChris Mason } 159962e2749eSChris Mason /* setup the item for the new data */ 1600d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1601e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 16020783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 16030783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 16047518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1605d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1606aa5d6bedSChris Mason 1607aa5d6bedSChris Mason ret = 0; 16088e19f2cdSChris Mason if (slot == 0) 1609e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1610aa5d6bedSChris Mason 1611123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1612be0e5c09SChris Mason BUG(); 161362e2749eSChris Mason check_leaf(root, path, 0); 1614ed2ff2cbSChris Mason out: 161562e2749eSChris Mason return ret; 161662e2749eSChris Mason } 161762e2749eSChris Mason 161862e2749eSChris Mason /* 161962e2749eSChris Mason * Given a key and some data, insert an item into the tree. 162062e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 162162e2749eSChris Mason */ 1622e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1623e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1624e089f05cSChris Mason data_size) 162562e2749eSChris Mason { 162662e2749eSChris Mason int ret = 0; 16272c90e5d6SChris Mason struct btrfs_path *path; 162862e2749eSChris Mason u8 *ptr; 162962e2749eSChris Mason 16302c90e5d6SChris Mason path = btrfs_alloc_path(); 16312c90e5d6SChris Mason BUG_ON(!path); 16322c90e5d6SChris Mason btrfs_init_path(path); 16332c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 163462e2749eSChris Mason if (!ret) { 16352c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 16362c90e5d6SChris Mason path->slots[0], u8); 16372c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1638d6025579SChris Mason ptr, data, data_size); 16392c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 164062e2749eSChris Mason } 16412c90e5d6SChris Mason btrfs_release_path(root, path); 16422c90e5d6SChris Mason btrfs_free_path(path); 1643aa5d6bedSChris Mason return ret; 1644be0e5c09SChris Mason } 1645be0e5c09SChris Mason 164674123bd7SChris Mason /* 16475de08d7dSChris Mason * delete the pointer from a given node. 164874123bd7SChris Mason * 164974123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 165074123bd7SChris Mason * continuing all the way the root if required. The root is converted into 165174123bd7SChris Mason * a leaf if all the nodes are emptied. 165274123bd7SChris Mason */ 1653e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1654e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1655be0e5c09SChris Mason { 1656234b63a0SChris Mason struct btrfs_node *node; 1657e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 16587518a238SChris Mason u32 nritems; 1659aa5d6bedSChris Mason int ret = 0; 1660bb803951SChris Mason int wret; 1661be0e5c09SChris Mason 1662e20d96d6SChris Mason node = btrfs_buffer_node(parent); 16637518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1664be0e5c09SChris Mason if (slot != nritems -1) { 1665d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1666d6025579SChris Mason node->ptrs + slot + 1, 1667d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1668d6025579SChris Mason (nritems - slot - 1)); 1669be0e5c09SChris Mason } 16707518a238SChris Mason nritems--; 16717518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 16727518a238SChris Mason if (nritems == 0 && parent == root->node) { 1673e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1674e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1675eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1676e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1677bb803951SChris Mason } else if (slot == 0) { 1678e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1679123abc88SChris Mason level + 1); 16800f70abe2SChris Mason if (wret) 16810f70abe2SChris Mason ret = wret; 1682be0e5c09SChris Mason } 1683d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1684aa5d6bedSChris Mason return ret; 1685be0e5c09SChris Mason } 1686be0e5c09SChris Mason 168774123bd7SChris Mason /* 168874123bd7SChris Mason * delete the item at the leaf level in path. If that empties 168974123bd7SChris Mason * the leaf, remove it from the tree 169074123bd7SChris Mason */ 1691e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1692e089f05cSChris Mason struct btrfs_path *path) 1693be0e5c09SChris Mason { 1694be0e5c09SChris Mason int slot; 1695234b63a0SChris Mason struct btrfs_leaf *leaf; 1696e20d96d6SChris Mason struct buffer_head *leaf_buf; 1697be0e5c09SChris Mason int doff; 1698be0e5c09SChris Mason int dsize; 1699aa5d6bedSChris Mason int ret = 0; 1700aa5d6bedSChris Mason int wret; 17017518a238SChris Mason u32 nritems; 1702be0e5c09SChris Mason 1703eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1704e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 17054920c9acSChris Mason slot = path->slots[0]; 17060783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 17070783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 17087518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1709be0e5c09SChris Mason 17107518a238SChris Mason if (slot != nritems - 1) { 1711be0e5c09SChris Mason int i; 1712123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 1713d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1714d6025579SChris Mason data_end + dsize, 1715123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 1716be0e5c09SChris Mason doff - data_end); 17170783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 1718123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 17190783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 17200783fcfcSChris Mason } 1721d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 1722d6025579SChris Mason leaf->items + slot + 1, 17230783fcfcSChris Mason sizeof(struct btrfs_item) * 17247518a238SChris Mason (nritems - slot - 1)); 1725be0e5c09SChris Mason } 17267518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 17277518a238SChris Mason nritems--; 172874123bd7SChris Mason /* delete the leaf if we've emptied it */ 17297518a238SChris Mason if (nritems == 0) { 1730eb60ceacSChris Mason if (leaf_buf == root->node) { 17317518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 17329a8dd150SChris Mason } else { 1733e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1734d6025579SChris Mason wait_on_buffer(leaf_buf); 1735e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 1736aa5d6bedSChris Mason if (wret) 1737aa5d6bedSChris Mason ret = wret; 1738e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 17397eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 17400f70abe2SChris Mason if (wret) 17410f70abe2SChris Mason ret = wret; 17429a8dd150SChris Mason } 1743be0e5c09SChris Mason } else { 17447518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 1745aa5d6bedSChris Mason if (slot == 0) { 1746e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 1747aa5d6bedSChris Mason &leaf->items[0].key, 1); 1748aa5d6bedSChris Mason if (wret) 1749aa5d6bedSChris Mason ret = wret; 1750aa5d6bedSChris Mason } 1751aa5d6bedSChris Mason 175274123bd7SChris Mason /* delete the leaf if it is mostly empty */ 1753123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1754be0e5c09SChris Mason /* push_leaf_left fixes the path. 1755be0e5c09SChris Mason * make sure the path still points to our leaf 1756be0e5c09SChris Mason * for possible call to del_ptr below 1757be0e5c09SChris Mason */ 17584920c9acSChris Mason slot = path->slots[1]; 1759e20d96d6SChris Mason get_bh(leaf_buf); 1760e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 1761aa5d6bedSChris Mason if (wret < 0) 1762aa5d6bedSChris Mason ret = wret; 1763f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 17647518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 1765e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 1766aa5d6bedSChris Mason if (wret < 0) 1767aa5d6bedSChris Mason ret = wret; 1768aa5d6bedSChris Mason } 17697518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 17707eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 1771e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1772d6025579SChris Mason wait_on_buffer(leaf_buf); 1773e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 1774aa5d6bedSChris Mason if (wret) 1775aa5d6bedSChris Mason ret = wret; 1776234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1777e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1778e089f05cSChris Mason 1, 1); 17790f70abe2SChris Mason if (wret) 17800f70abe2SChris Mason ret = wret; 17815de08d7dSChris Mason } else { 1782d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1783234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1784be0e5c09SChris Mason } 1785d5719762SChris Mason } else { 1786d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1787be0e5c09SChris Mason } 17889a8dd150SChris Mason } 1789aa5d6bedSChris Mason return ret; 17909a8dd150SChris Mason } 17919a8dd150SChris Mason 179297571fd0SChris Mason /* 179397571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 17940f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 17950f70abe2SChris Mason * returns < 0 on io errors. 179697571fd0SChris Mason */ 1797234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 1798d97e63b6SChris Mason { 1799d97e63b6SChris Mason int slot; 1800d97e63b6SChris Mason int level = 1; 1801d97e63b6SChris Mason u64 blocknr; 1802e20d96d6SChris Mason struct buffer_head *c; 1803e20d96d6SChris Mason struct btrfs_node *c_node; 1804e20d96d6SChris Mason struct buffer_head *next = NULL; 1805d97e63b6SChris Mason 1806234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 1807d97e63b6SChris Mason if (!path->nodes[level]) 18080f70abe2SChris Mason return 1; 1809d97e63b6SChris Mason slot = path->slots[level] + 1; 1810d97e63b6SChris Mason c = path->nodes[level]; 1811e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 1812e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 1813d97e63b6SChris Mason level++; 1814d97e63b6SChris Mason continue; 1815d97e63b6SChris Mason } 1816e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 1817cfaa7295SChris Mason if (next) 1818234b63a0SChris Mason btrfs_block_release(root, next); 1819d97e63b6SChris Mason next = read_tree_block(root, blocknr); 1820d97e63b6SChris Mason break; 1821d97e63b6SChris Mason } 1822d97e63b6SChris Mason path->slots[level] = slot; 1823d97e63b6SChris Mason while(1) { 1824d97e63b6SChris Mason level--; 1825d97e63b6SChris Mason c = path->nodes[level]; 1826234b63a0SChris Mason btrfs_block_release(root, c); 1827d97e63b6SChris Mason path->nodes[level] = next; 1828d97e63b6SChris Mason path->slots[level] = 0; 1829d97e63b6SChris Mason if (!level) 1830d97e63b6SChris Mason break; 18311d4f8a0cSChris Mason next = read_tree_block(root, 1832e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 1833d97e63b6SChris Mason } 1834d97e63b6SChris Mason return 0; 1835d97e63b6SChris Mason } 1836