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; 136*8d7be552SChris Mason int slot; 137*8d7be552SChris 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]; 143*8d7be552SChris 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)); 154*8d7be552SChris Mason if (slot != 0) { 155*8d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key); 156*8d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0); 157*8d7be552SChris Mason } 158*8d7be552SChris Mason if (slot < nritems - 1) { 159*8d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key); 160*8d7be552SChris 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; 171*8d7be552SChris Mason int slot = path->slots[0]; 172*8d7be552SChris Mason struct btrfs_key cpukey; 173*8d7be552SChris 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 } 192*8d7be552SChris Mason if (slot != 0) { 193*8d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key); 194*8d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0); 195*8d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot - 1) != 196*8d7be552SChris Mason btrfs_item_end(leaf->items + slot)); 197aa5d6bedSChris Mason } 198*8d7be552SChris Mason if (slot < nritems - 1) { 199*8d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key); 200*8d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0); 201*8d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot) != 202*8d7be552SChris Mason btrfs_item_end(leaf->items + slot + 1)); 203aa5d6bedSChris Mason } 204*8d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items) + 205*8d7be552SChris 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]); 87474123bd7SChris Mason return 0; 87574123bd7SChris Mason } 87674123bd7SChris Mason 87797571fd0SChris Mason /* 87897571fd0SChris Mason * split the node at the specified level in path in two. 87997571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 88097571fd0SChris Mason * 88197571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 88297571fd0SChris Mason * left and right, if either one works, it returns right away. 883aa5d6bedSChris Mason * 884aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 88597571fd0SChris Mason */ 886e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 887e089f05cSChris Mason *root, struct btrfs_path *path, int level) 888be0e5c09SChris Mason { 889e20d96d6SChris Mason struct buffer_head *t; 890234b63a0SChris Mason struct btrfs_node *c; 891e20d96d6SChris Mason struct buffer_head *split_buffer; 892234b63a0SChris Mason struct btrfs_node *split; 893be0e5c09SChris Mason int mid; 8945c680ed6SChris Mason int ret; 895aa5d6bedSChris Mason int wret; 8967518a238SChris Mason u32 c_nritems; 897be0e5c09SChris Mason 8985c680ed6SChris Mason t = path->nodes[level]; 899e20d96d6SChris Mason c = btrfs_buffer_node(t); 9005c680ed6SChris Mason if (t == root->node) { 9015c680ed6SChris Mason /* trying to split the root, lets make a new one */ 902e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 9035c680ed6SChris Mason if (ret) 9045c680ed6SChris Mason return ret; 905e66f709bSChris Mason } else { 906e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 907e66f709bSChris Mason t = path->nodes[level]; 908e66f709bSChris Mason c = btrfs_buffer_node(t); 909e66f709bSChris Mason if (!ret && 910e66f709bSChris Mason btrfs_header_nritems(&c->header) < 911e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 912e66f709bSChris Mason return 0; 9135c680ed6SChris Mason } 914e66f709bSChris Mason 9157518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 91631f3c99bSChris Mason split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr); 917e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 9187518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 9199a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 9207eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 9217f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 9224d775673SChris Mason btrfs_set_header_owner(&split->header, root->root_key.objectid); 9233eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 9243eb0314dSChris Mason sizeof(split->header.fsid)); 9257518a238SChris Mason mid = (c_nritems + 1) / 2; 926d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 927123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 9287518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 9297518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 930aa5d6bedSChris Mason ret = 0; 931aa5d6bedSChris Mason 932d6025579SChris Mason btrfs_mark_buffer_dirty(t); 933d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 934e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 9357eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 936123abc88SChris Mason level + 1); 937aa5d6bedSChris Mason if (wret) 938aa5d6bedSChris Mason ret = wret; 939aa5d6bedSChris Mason 9405de08d7dSChris Mason if (path->slots[level] >= mid) { 9415c680ed6SChris Mason path->slots[level] -= mid; 942234b63a0SChris Mason btrfs_block_release(root, t); 9435c680ed6SChris Mason path->nodes[level] = split_buffer; 9445c680ed6SChris Mason path->slots[level + 1] += 1; 945eb60ceacSChris Mason } else { 946234b63a0SChris Mason btrfs_block_release(root, split_buffer); 947be0e5c09SChris Mason } 948aa5d6bedSChris Mason return ret; 949be0e5c09SChris Mason } 950be0e5c09SChris Mason 95174123bd7SChris Mason /* 95274123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 95374123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 95474123bd7SChris Mason * space used both by the item structs and the item data 95574123bd7SChris Mason */ 956234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 957be0e5c09SChris Mason { 958be0e5c09SChris Mason int data_len; 959d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 960d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 961be0e5c09SChris Mason 962be0e5c09SChris Mason if (!nr) 963be0e5c09SChris Mason return 0; 9640783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 9650783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 9660783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 967d4dbff95SChris Mason WARN_ON(data_len < 0); 968be0e5c09SChris Mason return data_len; 969be0e5c09SChris Mason } 970be0e5c09SChris Mason 97174123bd7SChris Mason /* 972d4dbff95SChris Mason * The space between the end of the leaf items and 973d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 974d4dbff95SChris Mason * the leaf has left for both items and data 975d4dbff95SChris Mason */ 976d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 977d4dbff95SChris Mason { 978d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 979d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 980d4dbff95SChris Mason } 981d4dbff95SChris Mason 982d4dbff95SChris Mason /* 98300ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 98400ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 985aa5d6bedSChris Mason * 986aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 987aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 98800ec4c51SChris Mason */ 989e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 990e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 99100ec4c51SChris Mason { 992e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 993e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 994234b63a0SChris Mason struct btrfs_leaf *right; 995e20d96d6SChris Mason struct buffer_head *right_buf; 996e20d96d6SChris Mason struct buffer_head *upper; 997e20d96d6SChris Mason struct btrfs_node *upper_node; 99800ec4c51SChris Mason int slot; 99900ec4c51SChris Mason int i; 100000ec4c51SChris Mason int free_space; 100100ec4c51SChris Mason int push_space = 0; 100200ec4c51SChris Mason int push_items = 0; 10030783fcfcSChris Mason struct btrfs_item *item; 10047518a238SChris Mason u32 left_nritems; 10057518a238SChris Mason u32 right_nritems; 100600ec4c51SChris Mason 100700ec4c51SChris Mason slot = path->slots[1]; 100800ec4c51SChris Mason if (!path->nodes[1]) { 100900ec4c51SChris Mason return 1; 101000ec4c51SChris Mason } 101100ec4c51SChris Mason upper = path->nodes[1]; 1012e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1013e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 101400ec4c51SChris Mason return 1; 101500ec4c51SChris Mason } 1016e20d96d6SChris Mason right_buf = read_tree_block(root, 1017e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 1018e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1019123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10200783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1021234b63a0SChris Mason btrfs_block_release(root, right_buf); 102200ec4c51SChris Mason return 1; 102300ec4c51SChris Mason } 102402217ed2SChris Mason /* cow and double check */ 1025e089f05cSChris Mason btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); 1026e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1027123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10280783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1029234b63a0SChris Mason btrfs_block_release(root, right_buf); 103002217ed2SChris Mason return 1; 103102217ed2SChris Mason } 103202217ed2SChris Mason 10337518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1034a429e513SChris Mason if (left_nritems == 0) { 1035a429e513SChris Mason btrfs_block_release(root, right_buf); 1036a429e513SChris Mason return 1; 1037a429e513SChris Mason } 1038a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 103900ec4c51SChris Mason item = left->items + i; 104000ec4c51SChris Mason if (path->slots[0] == i) 104100ec4c51SChris Mason push_space += data_size + sizeof(*item); 10420783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 10430783fcfcSChris Mason free_space) 104400ec4c51SChris Mason break; 104500ec4c51SChris Mason push_items++; 10460783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 104700ec4c51SChris Mason } 104800ec4c51SChris Mason if (push_items == 0) { 1049234b63a0SChris Mason btrfs_block_release(root, right_buf); 105000ec4c51SChris Mason return 1; 105100ec4c51SChris Mason } 1052a429e513SChris Mason if (push_items == left_nritems) 1053a429e513SChris Mason WARN_ON(1); 10547518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 105500ec4c51SChris Mason /* push left to right */ 10560783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1057123abc88SChris Mason push_space -= leaf_data_end(root, left); 105800ec4c51SChris Mason /* make room in the right data area */ 1059d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1060d6025579SChris Mason leaf_data_end(root, right) - push_space, 1061d6025579SChris Mason btrfs_leaf_data(right) + 1062d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1063d6025579SChris Mason leaf_data_end(root, right)); 106400ec4c51SChris Mason /* copy from the left data area */ 1065d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1066d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1067d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1068d6025579SChris Mason push_space); 1069d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 10700783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 107100ec4c51SChris Mason /* copy the items from left to right */ 1072d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1073d6025579SChris Mason left_nritems - push_items, 10740783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 107500ec4c51SChris Mason 107600ec4c51SChris Mason /* update the item pointers */ 10777518a238SChris Mason right_nritems += push_items; 10787518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1079123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 10807518a238SChris Mason for (i = 0; i < right_nritems; i++) { 10810783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 10820783fcfcSChris Mason btrfs_item_size(right->items + i)); 10830783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 108400ec4c51SChris Mason } 10857518a238SChris Mason left_nritems -= push_items; 10867518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 108700ec4c51SChris Mason 1088d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1089d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1090a429e513SChris Mason 1091d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1092e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1093d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 109402217ed2SChris Mason 109500ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 10967518a238SChris Mason if (path->slots[0] >= left_nritems) { 10977518a238SChris Mason path->slots[0] -= left_nritems; 1098234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 109900ec4c51SChris Mason path->nodes[0] = right_buf; 110000ec4c51SChris Mason path->slots[1] += 1; 110100ec4c51SChris Mason } else { 1102234b63a0SChris Mason btrfs_block_release(root, right_buf); 110300ec4c51SChris Mason } 110400ec4c51SChris Mason return 0; 110500ec4c51SChris Mason } 110600ec4c51SChris Mason /* 110774123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 110874123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 110974123bd7SChris Mason */ 1110e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1111e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1112be0e5c09SChris Mason { 1113e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1114e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1115e20d96d6SChris Mason struct buffer_head *t; 1116234b63a0SChris Mason struct btrfs_leaf *left; 1117be0e5c09SChris Mason int slot; 1118be0e5c09SChris Mason int i; 1119be0e5c09SChris Mason int free_space; 1120be0e5c09SChris Mason int push_space = 0; 1121be0e5c09SChris Mason int push_items = 0; 11220783fcfcSChris Mason struct btrfs_item *item; 11237518a238SChris Mason u32 old_left_nritems; 1124aa5d6bedSChris Mason int ret = 0; 1125aa5d6bedSChris Mason int wret; 1126be0e5c09SChris Mason 1127be0e5c09SChris Mason slot = path->slots[1]; 1128be0e5c09SChris Mason if (slot == 0) { 1129be0e5c09SChris Mason return 1; 1130be0e5c09SChris Mason } 1131be0e5c09SChris Mason if (!path->nodes[1]) { 1132be0e5c09SChris Mason return 1; 1133be0e5c09SChris Mason } 1134e20d96d6SChris Mason t = read_tree_block(root, 1135e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1136e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1137123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11380783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1139234b63a0SChris Mason btrfs_block_release(root, t); 1140be0e5c09SChris Mason return 1; 1141be0e5c09SChris Mason } 114202217ed2SChris Mason 114302217ed2SChris Mason /* cow and double check */ 1144e089f05cSChris Mason btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 1145e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1146123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11470783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1148234b63a0SChris Mason btrfs_block_release(root, t); 114902217ed2SChris Mason return 1; 115002217ed2SChris Mason } 115102217ed2SChris Mason 1152a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1153a429e513SChris Mason btrfs_block_release(root, t); 1154a429e513SChris Mason return 1; 1155a429e513SChris Mason } 1156a429e513SChris Mason 1157a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1158be0e5c09SChris Mason item = right->items + i; 1159be0e5c09SChris Mason if (path->slots[0] == i) 1160be0e5c09SChris Mason push_space += data_size + sizeof(*item); 11610783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 11620783fcfcSChris Mason free_space) 1163be0e5c09SChris Mason break; 1164be0e5c09SChris Mason push_items++; 11650783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1166be0e5c09SChris Mason } 1167be0e5c09SChris Mason if (push_items == 0) { 1168234b63a0SChris Mason btrfs_block_release(root, t); 1169be0e5c09SChris Mason return 1; 1170be0e5c09SChris Mason } 1171a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1172a429e513SChris Mason WARN_ON(1); 1173be0e5c09SChris Mason /* push data from right to left */ 1174d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1175d6025579SChris Mason btrfs_header_nritems(&left->header), 11760783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1177123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 11780783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1179d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1180d6025579SChris Mason leaf_data_end(root, left) - push_space, 1181123abc88SChris Mason btrfs_leaf_data(right) + 1182123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1183be0e5c09SChris Mason push_space); 11847518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1185eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1186eb60ceacSChris Mason 1187be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1188123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1189123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1190123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 11910783fcfcSChris Mason btrfs_item_offset(left->items + 11920783fcfcSChris Mason old_left_nritems - 1))); 1193be0e5c09SChris Mason } 11947518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1195be0e5c09SChris Mason 1196be0e5c09SChris Mason /* fixup right node */ 11970783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1198123abc88SChris Mason leaf_data_end(root, right); 1199d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1200d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1201d6025579SChris Mason btrfs_leaf_data(right) + 1202123abc88SChris Mason leaf_data_end(root, right), push_space); 1203d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 12047518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 12050783fcfcSChris Mason sizeof(struct btrfs_item)); 12067518a238SChris Mason btrfs_set_header_nritems(&right->header, 12077518a238SChris Mason btrfs_header_nritems(&right->header) - 12087518a238SChris Mason push_items); 1209123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1210eb60ceacSChris Mason 12117518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 12120783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 12130783fcfcSChris Mason btrfs_item_size(right->items + i)); 12140783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1215be0e5c09SChris Mason } 1216eb60ceacSChris Mason 1217d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1218d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1219e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1220aa5d6bedSChris Mason if (wret) 1221aa5d6bedSChris Mason ret = wret; 1222be0e5c09SChris Mason 1223be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1224be0e5c09SChris Mason if (path->slots[0] < push_items) { 1225be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1226234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1227eb60ceacSChris Mason path->nodes[0] = t; 1228be0e5c09SChris Mason path->slots[1] -= 1; 1229be0e5c09SChris Mason } else { 1230234b63a0SChris Mason btrfs_block_release(root, t); 1231be0e5c09SChris Mason path->slots[0] -= push_items; 1232be0e5c09SChris Mason } 1233eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1234aa5d6bedSChris Mason return ret; 1235be0e5c09SChris Mason } 1236be0e5c09SChris Mason 123774123bd7SChris Mason /* 123874123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 123974123bd7SChris Mason * available for the resulting leaf level of the path. 1240aa5d6bedSChris Mason * 1241aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 124274123bd7SChris Mason */ 1243e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1244d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1245d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1246be0e5c09SChris Mason { 1247e20d96d6SChris Mason struct buffer_head *l_buf; 1248234b63a0SChris Mason struct btrfs_leaf *l; 12497518a238SChris Mason u32 nritems; 1250eb60ceacSChris Mason int mid; 1251eb60ceacSChris Mason int slot; 1252234b63a0SChris Mason struct btrfs_leaf *right; 1253e20d96d6SChris Mason struct buffer_head *right_buffer; 12540783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1255be0e5c09SChris Mason int data_copy_size; 1256be0e5c09SChris Mason int rt_data_off; 1257be0e5c09SChris Mason int i; 1258d4dbff95SChris Mason int ret = 0; 1259aa5d6bedSChris Mason int wret; 1260d4dbff95SChris Mason int double_split = 0; 1261d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1262be0e5c09SChris Mason 126340689478SChris Mason /* first try to make some room by pushing left and right */ 1264e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1265eaee50e8SChris Mason if (wret < 0) 1266eaee50e8SChris Mason return wret; 1267eaee50e8SChris Mason if (wret) { 1268e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1269eaee50e8SChris Mason if (wret < 0) 1270eaee50e8SChris Mason return wret; 1271eaee50e8SChris Mason } 1272eb60ceacSChris Mason l_buf = path->nodes[0]; 1273e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1274aa5d6bedSChris Mason 1275aa5d6bedSChris Mason /* did the pushes work? */ 1276123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1277123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1278be0e5c09SChris Mason return 0; 1279aa5d6bedSChris Mason 12805c680ed6SChris Mason if (!path->nodes[1]) { 1281e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 12825c680ed6SChris Mason if (ret) 12835c680ed6SChris Mason return ret; 12845c680ed6SChris Mason } 1285eb60ceacSChris Mason slot = path->slots[0]; 12867518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1287eb60ceacSChris Mason mid = (nritems + 1)/ 2; 128831f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 1289eb60ceacSChris Mason BUG_ON(!right_buffer); 1290e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1291123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 12927eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 12937f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 12944d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 12957518a238SChris Mason btrfs_set_header_level(&right->header, 0); 12963eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 12973eb0314dSChris Mason sizeof(right->header.fsid)); 1298d4dbff95SChris Mason if (mid <= slot) { 1299d4dbff95SChris Mason if (nritems == 1 || 1300d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1301d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1302d4dbff95SChris Mason if (slot >= nritems) { 1303d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1304d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1305d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1306d4dbff95SChris Mason &disk_key, 13077eccb903SChris Mason bh_blocknr(right_buffer), 1308d4dbff95SChris Mason path->slots[1] + 1, 1); 1309d4dbff95SChris Mason if (wret) 1310d4dbff95SChris Mason ret = wret; 1311d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1312d4dbff95SChris Mason path->nodes[0] = right_buffer; 1313d4dbff95SChris Mason path->slots[0] = 0; 1314d4dbff95SChris Mason path->slots[1] += 1; 1315d4dbff95SChris Mason return ret; 1316d4dbff95SChris Mason } 1317d4dbff95SChris Mason mid = slot; 1318d4dbff95SChris Mason double_split = 1; 1319d4dbff95SChris Mason } 1320d4dbff95SChris Mason } else { 1321d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1322d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1323d4dbff95SChris Mason if (slot == 0) { 1324d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1325d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1326d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1327d4dbff95SChris Mason &disk_key, 13287eccb903SChris Mason bh_blocknr(right_buffer), 1329d4dbff95SChris Mason path->slots[1] - 1, 1); 1330d4dbff95SChris Mason if (wret) 1331d4dbff95SChris Mason ret = wret; 1332d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1333d4dbff95SChris Mason path->nodes[0] = right_buffer; 1334d4dbff95SChris Mason path->slots[0] = 0; 1335d4dbff95SChris Mason path->slots[1] -= 1; 1336a429e513SChris Mason if (path->slots[1] == 0) { 1337a429e513SChris Mason wret = fixup_low_keys(trans, root, 1338a429e513SChris Mason path, &disk_key, 1); 1339a429e513SChris Mason if (wret) 1340a429e513SChris Mason ret = wret; 1341a429e513SChris Mason } 1342d4dbff95SChris Mason return ret; 1343d4dbff95SChris Mason } 1344d4dbff95SChris Mason mid = slot; 1345d4dbff95SChris Mason double_split = 1; 1346d4dbff95SChris Mason } 1347d4dbff95SChris Mason } 1348d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1349123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1350123abc88SChris Mason leaf_data_end(root, l); 1351d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 13520783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1353d6025579SChris Mason btrfs_memcpy(root, right, 1354d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1355123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1356123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1357123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1358123abc88SChris Mason btrfs_item_end(l->items + mid); 135974123bd7SChris Mason 13600783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1361123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 13620783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 13630783fcfcSChris Mason } 136474123bd7SChris Mason 13657518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1366aa5d6bedSChris Mason ret = 0; 1367e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 13687eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1369aa5d6bedSChris Mason if (wret) 1370aa5d6bedSChris Mason ret = wret; 1371d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1372d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1373eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1374be0e5c09SChris Mason if (mid <= slot) { 1375234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1376eb60ceacSChris Mason path->nodes[0] = right_buffer; 1377be0e5c09SChris Mason path->slots[0] -= mid; 1378be0e5c09SChris Mason path->slots[1] += 1; 1379eb60ceacSChris Mason } else 1380234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1381eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1382d4dbff95SChris Mason 1383d4dbff95SChris Mason if (!double_split) 1384d4dbff95SChris Mason return ret; 138531f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 1386d4dbff95SChris Mason BUG_ON(!right_buffer); 1387d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1388d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 13897eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1390d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 13914d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 1392d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 13933eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 13943eb0314dSChris Mason sizeof(right->header.fsid)); 1395d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1396d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1397d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1398d4dbff95SChris Mason &disk_key, 13997eccb903SChris Mason bh_blocknr(right_buffer), 1400d4dbff95SChris Mason path->slots[1], 1); 1401d4dbff95SChris Mason if (wret) 1402d4dbff95SChris Mason ret = wret; 1403a429e513SChris Mason if (path->slots[1] == 0) { 1404a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1405a429e513SChris Mason if (wret) 1406a429e513SChris Mason ret = wret; 1407a429e513SChris Mason } 1408d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1409d4dbff95SChris Mason path->nodes[0] = right_buffer; 1410d4dbff95SChris Mason path->slots[0] = 0; 1411d4dbff95SChris Mason check_node(root, path, 1); 1412d4dbff95SChris Mason check_leaf(root, path, 0); 1413be0e5c09SChris Mason return ret; 1414be0e5c09SChris Mason } 1415be0e5c09SChris Mason 1416b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1417b18c6685SChris Mason struct btrfs_root *root, 1418b18c6685SChris Mason struct btrfs_path *path, 1419b18c6685SChris Mason u32 new_size) 1420b18c6685SChris Mason { 1421b18c6685SChris Mason int ret = 0; 1422b18c6685SChris Mason int slot; 1423b18c6685SChris Mason int slot_orig; 1424b18c6685SChris Mason struct btrfs_leaf *leaf; 1425b18c6685SChris Mason struct buffer_head *leaf_buf; 1426b18c6685SChris Mason u32 nritems; 1427b18c6685SChris Mason unsigned int data_end; 1428b18c6685SChris Mason unsigned int old_data_start; 1429b18c6685SChris Mason unsigned int old_size; 1430b18c6685SChris Mason unsigned int size_diff; 1431b18c6685SChris Mason int i; 1432b18c6685SChris Mason 1433b18c6685SChris Mason slot_orig = path->slots[0]; 1434b18c6685SChris Mason leaf_buf = path->nodes[0]; 1435b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1436b18c6685SChris Mason 1437b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1438b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1439b18c6685SChris Mason 1440b18c6685SChris Mason slot = path->slots[0]; 1441b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1442b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1443b18c6685SChris Mason BUG_ON(old_size <= new_size); 1444b18c6685SChris Mason size_diff = old_size - new_size; 1445b18c6685SChris Mason 1446b18c6685SChris Mason BUG_ON(slot < 0); 1447b18c6685SChris Mason BUG_ON(slot >= nritems); 1448b18c6685SChris Mason 1449b18c6685SChris Mason /* 1450b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1451b18c6685SChris Mason */ 1452b18c6685SChris Mason /* first correct the data pointers */ 1453b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1454b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1455b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1456b18c6685SChris Mason ioff + size_diff); 1457b18c6685SChris Mason } 1458b18c6685SChris Mason /* shift the data */ 1459b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1460b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1461b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1462b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1463b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1464b18c6685SChris Mason 1465b18c6685SChris Mason ret = 0; 1466b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1467b18c6685SChris Mason BUG(); 1468b18c6685SChris Mason check_leaf(root, path, 0); 1469b18c6685SChris Mason return ret; 1470b18c6685SChris Mason } 1471b18c6685SChris Mason 14726567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 14736567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 14746567e837SChris Mason { 14756567e837SChris Mason int ret = 0; 14766567e837SChris Mason int slot; 14776567e837SChris Mason int slot_orig; 14786567e837SChris Mason struct btrfs_leaf *leaf; 14796567e837SChris Mason struct buffer_head *leaf_buf; 14806567e837SChris Mason u32 nritems; 14816567e837SChris Mason unsigned int data_end; 14826567e837SChris Mason unsigned int old_data; 14836567e837SChris Mason unsigned int old_size; 14846567e837SChris Mason int i; 14856567e837SChris Mason 14866567e837SChris Mason slot_orig = path->slots[0]; 14876567e837SChris Mason leaf_buf = path->nodes[0]; 14886567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 14896567e837SChris Mason 14906567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 14916567e837SChris Mason data_end = leaf_data_end(root, leaf); 14926567e837SChris Mason 14936567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 14946567e837SChris Mason BUG(); 14956567e837SChris Mason slot = path->slots[0]; 14966567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 14976567e837SChris Mason 14986567e837SChris Mason BUG_ON(slot < 0); 14996567e837SChris Mason BUG_ON(slot >= nritems); 15006567e837SChris Mason 15016567e837SChris Mason /* 15026567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 15036567e837SChris Mason */ 15046567e837SChris Mason /* first correct the data pointers */ 15056567e837SChris Mason for (i = slot; i < nritems; i++) { 15066567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 15076567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 15086567e837SChris Mason ioff - data_size); 15096567e837SChris Mason } 15106567e837SChris Mason /* shift the data */ 15116567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 15126567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 15136567e837SChris Mason data_end, old_data - data_end); 15146567e837SChris Mason data_end = old_data; 15156567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 15166567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 15176567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 15186567e837SChris Mason 15196567e837SChris Mason ret = 0; 15206567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 15216567e837SChris Mason BUG(); 15226567e837SChris Mason check_leaf(root, path, 0); 15236567e837SChris Mason return ret; 15246567e837SChris Mason } 15256567e837SChris Mason 152674123bd7SChris Mason /* 152774123bd7SChris Mason * Given a key and some data, insert an item into the tree. 152874123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 152974123bd7SChris Mason */ 1530e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1531e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1532e089f05cSChris Mason *cpu_key, u32 data_size) 1533be0e5c09SChris Mason { 1534aa5d6bedSChris Mason int ret = 0; 1535be0e5c09SChris Mason int slot; 1536eb60ceacSChris Mason int slot_orig; 1537234b63a0SChris Mason struct btrfs_leaf *leaf; 1538e20d96d6SChris Mason struct buffer_head *leaf_buf; 15397518a238SChris Mason u32 nritems; 1540be0e5c09SChris Mason unsigned int data_end; 1541e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1542e2fa7227SChris Mason 1543e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1544be0e5c09SChris Mason 154574123bd7SChris Mason /* create a root if there isn't one */ 15465c680ed6SChris Mason if (!root->node) 1547cfaa7295SChris Mason BUG(); 1548e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1549eb60ceacSChris Mason if (ret == 0) { 1550f0930a37SChris Mason return -EEXIST; 1551aa5d6bedSChris Mason } 1552ed2ff2cbSChris Mason if (ret < 0) 1553ed2ff2cbSChris Mason goto out; 1554be0e5c09SChris Mason 155562e2749eSChris Mason slot_orig = path->slots[0]; 155662e2749eSChris Mason leaf_buf = path->nodes[0]; 1557e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 155874123bd7SChris Mason 15597518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1560123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1561eb60ceacSChris Mason 1562123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1563d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1564be0e5c09SChris Mason BUG(); 1565d4dbff95SChris Mason } 156662e2749eSChris Mason slot = path->slots[0]; 1567eb60ceacSChris Mason BUG_ON(slot < 0); 1568be0e5c09SChris Mason if (slot != nritems) { 1569be0e5c09SChris Mason int i; 15700783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1571be0e5c09SChris Mason 1572be0e5c09SChris Mason /* 1573be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1574be0e5c09SChris Mason */ 1575be0e5c09SChris Mason /* first correct the data pointers */ 15760783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1577123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 15780783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 15790783fcfcSChris Mason ioff - data_size); 15800783fcfcSChris Mason } 1581be0e5c09SChris Mason 1582be0e5c09SChris Mason /* shift the items */ 1583d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1584d6025579SChris Mason leaf->items + slot, 15850783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1586be0e5c09SChris Mason 1587be0e5c09SChris Mason /* shift the data */ 1588d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1589d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1590be0e5c09SChris Mason data_end, old_data - data_end); 1591be0e5c09SChris Mason data_end = old_data; 1592be0e5c09SChris Mason } 159362e2749eSChris Mason /* setup the item for the new data */ 1594d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1595e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 15960783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 15970783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 15987518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1599d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1600aa5d6bedSChris Mason 1601aa5d6bedSChris Mason ret = 0; 16028e19f2cdSChris Mason if (slot == 0) 1603e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1604aa5d6bedSChris Mason 1605123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1606be0e5c09SChris Mason BUG(); 160762e2749eSChris Mason check_leaf(root, path, 0); 1608ed2ff2cbSChris Mason out: 160962e2749eSChris Mason return ret; 161062e2749eSChris Mason } 161162e2749eSChris Mason 161262e2749eSChris Mason /* 161362e2749eSChris Mason * Given a key and some data, insert an item into the tree. 161462e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 161562e2749eSChris Mason */ 1616e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1617e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1618e089f05cSChris Mason data_size) 161962e2749eSChris Mason { 162062e2749eSChris Mason int ret = 0; 16212c90e5d6SChris Mason struct btrfs_path *path; 162262e2749eSChris Mason u8 *ptr; 162362e2749eSChris Mason 16242c90e5d6SChris Mason path = btrfs_alloc_path(); 16252c90e5d6SChris Mason BUG_ON(!path); 16262c90e5d6SChris Mason btrfs_init_path(path); 16272c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 162862e2749eSChris Mason if (!ret) { 16292c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 16302c90e5d6SChris Mason path->slots[0], u8); 16312c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1632d6025579SChris Mason ptr, data, data_size); 16332c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 163462e2749eSChris Mason } 16352c90e5d6SChris Mason btrfs_release_path(root, path); 16362c90e5d6SChris Mason btrfs_free_path(path); 1637aa5d6bedSChris Mason return ret; 1638be0e5c09SChris Mason } 1639be0e5c09SChris Mason 164074123bd7SChris Mason /* 16415de08d7dSChris Mason * delete the pointer from a given node. 164274123bd7SChris Mason * 164374123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 164474123bd7SChris Mason * continuing all the way the root if required. The root is converted into 164574123bd7SChris Mason * a leaf if all the nodes are emptied. 164674123bd7SChris Mason */ 1647e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1648e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1649be0e5c09SChris Mason { 1650234b63a0SChris Mason struct btrfs_node *node; 1651e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 16527518a238SChris Mason u32 nritems; 1653aa5d6bedSChris Mason int ret = 0; 1654bb803951SChris Mason int wret; 1655be0e5c09SChris Mason 1656e20d96d6SChris Mason node = btrfs_buffer_node(parent); 16577518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1658be0e5c09SChris Mason if (slot != nritems -1) { 1659d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1660d6025579SChris Mason node->ptrs + slot + 1, 1661d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1662d6025579SChris Mason (nritems - slot - 1)); 1663be0e5c09SChris Mason } 16647518a238SChris Mason nritems--; 16657518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 16667518a238SChris Mason if (nritems == 0 && parent == root->node) { 1667e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1668e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1669eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1670e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1671bb803951SChris Mason } else if (slot == 0) { 1672e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1673123abc88SChris Mason level + 1); 16740f70abe2SChris Mason if (wret) 16750f70abe2SChris Mason ret = wret; 1676be0e5c09SChris Mason } 1677d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1678aa5d6bedSChris Mason return ret; 1679be0e5c09SChris Mason } 1680be0e5c09SChris Mason 168174123bd7SChris Mason /* 168274123bd7SChris Mason * delete the item at the leaf level in path. If that empties 168374123bd7SChris Mason * the leaf, remove it from the tree 168474123bd7SChris Mason */ 1685e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1686e089f05cSChris Mason struct btrfs_path *path) 1687be0e5c09SChris Mason { 1688be0e5c09SChris Mason int slot; 1689234b63a0SChris Mason struct btrfs_leaf *leaf; 1690e20d96d6SChris Mason struct buffer_head *leaf_buf; 1691be0e5c09SChris Mason int doff; 1692be0e5c09SChris Mason int dsize; 1693aa5d6bedSChris Mason int ret = 0; 1694aa5d6bedSChris Mason int wret; 16957518a238SChris Mason u32 nritems; 1696be0e5c09SChris Mason 1697eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1698e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 16994920c9acSChris Mason slot = path->slots[0]; 17000783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 17010783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 17027518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1703be0e5c09SChris Mason 17047518a238SChris Mason if (slot != nritems - 1) { 1705be0e5c09SChris Mason int i; 1706123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 1707d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1708d6025579SChris Mason data_end + dsize, 1709123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 1710be0e5c09SChris Mason doff - data_end); 17110783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 1712123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 17130783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 17140783fcfcSChris Mason } 1715d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 1716d6025579SChris Mason leaf->items + slot + 1, 17170783fcfcSChris Mason sizeof(struct btrfs_item) * 17187518a238SChris Mason (nritems - slot - 1)); 1719be0e5c09SChris Mason } 17207518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 17217518a238SChris Mason nritems--; 172274123bd7SChris Mason /* delete the leaf if we've emptied it */ 17237518a238SChris Mason if (nritems == 0) { 1724eb60ceacSChris Mason if (leaf_buf == root->node) { 17257518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 17269a8dd150SChris Mason } else { 1727e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1728d6025579SChris Mason wait_on_buffer(leaf_buf); 1729e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 1730aa5d6bedSChris Mason if (wret) 1731aa5d6bedSChris Mason ret = wret; 1732e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 17337eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 17340f70abe2SChris Mason if (wret) 17350f70abe2SChris Mason ret = wret; 17369a8dd150SChris Mason } 1737be0e5c09SChris Mason } else { 17387518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 1739aa5d6bedSChris Mason if (slot == 0) { 1740e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 1741aa5d6bedSChris Mason &leaf->items[0].key, 1); 1742aa5d6bedSChris Mason if (wret) 1743aa5d6bedSChris Mason ret = wret; 1744aa5d6bedSChris Mason } 1745aa5d6bedSChris Mason 174674123bd7SChris Mason /* delete the leaf if it is mostly empty */ 1747123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1748be0e5c09SChris Mason /* push_leaf_left fixes the path. 1749be0e5c09SChris Mason * make sure the path still points to our leaf 1750be0e5c09SChris Mason * for possible call to del_ptr below 1751be0e5c09SChris Mason */ 17524920c9acSChris Mason slot = path->slots[1]; 1753e20d96d6SChris Mason get_bh(leaf_buf); 1754e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 1755aa5d6bedSChris Mason if (wret < 0) 1756aa5d6bedSChris Mason ret = wret; 1757f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 17587518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 1759e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 1760aa5d6bedSChris Mason if (wret < 0) 1761aa5d6bedSChris Mason ret = wret; 1762aa5d6bedSChris Mason } 17637518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 17647eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 1765e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1766d6025579SChris Mason wait_on_buffer(leaf_buf); 1767e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 1768aa5d6bedSChris Mason if (wret) 1769aa5d6bedSChris Mason ret = wret; 1770234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1771e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1772e089f05cSChris Mason 1, 1); 17730f70abe2SChris Mason if (wret) 17740f70abe2SChris Mason ret = wret; 17755de08d7dSChris Mason } else { 1776d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1777234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1778be0e5c09SChris Mason } 1779d5719762SChris Mason } else { 1780d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1781be0e5c09SChris Mason } 17829a8dd150SChris Mason } 1783aa5d6bedSChris Mason return ret; 17849a8dd150SChris Mason } 17859a8dd150SChris Mason 178697571fd0SChris Mason /* 178797571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 17880f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 17890f70abe2SChris Mason * returns < 0 on io errors. 179097571fd0SChris Mason */ 1791234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 1792d97e63b6SChris Mason { 1793d97e63b6SChris Mason int slot; 1794d97e63b6SChris Mason int level = 1; 1795d97e63b6SChris Mason u64 blocknr; 1796e20d96d6SChris Mason struct buffer_head *c; 1797e20d96d6SChris Mason struct btrfs_node *c_node; 1798e20d96d6SChris Mason struct buffer_head *next = NULL; 1799d97e63b6SChris Mason 1800234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 1801d97e63b6SChris Mason if (!path->nodes[level]) 18020f70abe2SChris Mason return 1; 1803d97e63b6SChris Mason slot = path->slots[level] + 1; 1804d97e63b6SChris Mason c = path->nodes[level]; 1805e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 1806e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 1807d97e63b6SChris Mason level++; 1808d97e63b6SChris Mason continue; 1809d97e63b6SChris Mason } 1810e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 1811cfaa7295SChris Mason if (next) 1812234b63a0SChris Mason btrfs_block_release(root, next); 1813d97e63b6SChris Mason next = read_tree_block(root, blocknr); 1814d97e63b6SChris Mason break; 1815d97e63b6SChris Mason } 1816d97e63b6SChris Mason path->slots[level] = slot; 1817d97e63b6SChris Mason while(1) { 1818d97e63b6SChris Mason level--; 1819d97e63b6SChris Mason c = path->nodes[level]; 1820234b63a0SChris Mason btrfs_block_release(root, c); 1821d97e63b6SChris Mason path->nodes[level] = next; 1822d97e63b6SChris Mason path->slots[level] = 0; 1823d97e63b6SChris Mason if (!level) 1824d97e63b6SChris Mason break; 18251d4f8a0cSChris Mason next = read_tree_block(root, 1826e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 1827d97e63b6SChris Mason } 1828d97e63b6SChris Mason return 0; 1829d97e63b6SChris Mason } 1830