12e635a27SChris Mason #include <linux/module.h> 2eb60ceacSChris Mason #include "ctree.h" 3eb60ceacSChris Mason #include "disk-io.h" 47f5c1516SChris Mason #include "transaction.h" 59a8dd150SChris Mason 6e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 7e089f05cSChris Mason *root, struct btrfs_path *path, int level); 8e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 9d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 10d4dbff95SChris Mason struct btrfs_path *path, int data_size); 11e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 12e20d96d6SChris Mason *root, struct buffer_head *dst, struct buffer_head 13e089f05cSChris Mason *src); 14e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 15e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 16e20d96d6SChris Mason struct buffer_head *src_buf); 17e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 18e089f05cSChris Mason struct btrfs_path *path, int level, int slot); 19d97e63b6SChris Mason 20df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p) 21df24a2b9SChris Mason { 22df24a2b9SChris Mason memset(p, 0, sizeof(*p)); 23df24a2b9SChris Mason } 24df24a2b9SChris Mason 252c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void) 262c90e5d6SChris Mason { 27df24a2b9SChris Mason struct btrfs_path *path; 28df24a2b9SChris Mason path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); 29df24a2b9SChris Mason if (path) 30df24a2b9SChris Mason btrfs_init_path(path); 31df24a2b9SChris Mason return path; 322c90e5d6SChris Mason } 332c90e5d6SChris Mason 342c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p) 352c90e5d6SChris Mason { 36df24a2b9SChris Mason btrfs_release_path(NULL, p); 372c90e5d6SChris Mason kmem_cache_free(btrfs_path_cachep, p); 382c90e5d6SChris Mason } 392c90e5d6SChris Mason 40234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) 41eb60ceacSChris Mason { 42eb60ceacSChris Mason int i; 43234b63a0SChris Mason for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 44eb60ceacSChris Mason if (!p->nodes[i]) 45eb60ceacSChris Mason break; 46234b63a0SChris Mason btrfs_block_release(root, p->nodes[i]); 47eb60ceacSChris Mason } 48aa5d6bedSChris Mason memset(p, 0, sizeof(*p)); 49eb60ceacSChris Mason } 50eb60ceacSChris Mason 51e089f05cSChris Mason static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 52e20d96d6SChris Mason *root, struct buffer_head *buf, struct buffer_head 53e20d96d6SChris Mason *parent, int parent_slot, struct buffer_head 54e089f05cSChris Mason **cow_ret) 5502217ed2SChris Mason { 56e20d96d6SChris Mason struct buffer_head *cow; 57e20d96d6SChris Mason struct btrfs_node *cow_node; 5802217ed2SChris Mason 597f5c1516SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) == 607f5c1516SChris Mason trans->transid) { 6102217ed2SChris Mason *cow_ret = buf; 6202217ed2SChris Mason return 0; 6302217ed2SChris Mason } 64e089f05cSChris Mason cow = btrfs_alloc_free_block(trans, root); 65e20d96d6SChris Mason cow_node = btrfs_buffer_node(cow); 662c90e5d6SChris Mason if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) 672c90e5d6SChris Mason WARN_ON(1); 68e20d96d6SChris Mason memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 697eccb903SChris Mason btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); 707f5c1516SChris Mason btrfs_set_header_generation(&cow_node->header, trans->transid); 71e089f05cSChris Mason btrfs_inc_ref(trans, root, buf); 7202217ed2SChris Mason if (buf == root->node) { 7302217ed2SChris Mason root->node = cow; 74e20d96d6SChris Mason get_bh(cow); 752c90e5d6SChris Mason if (buf != root->commit_root) { 767eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 772c90e5d6SChris Mason } 78234b63a0SChris Mason btrfs_block_release(root, buf); 7902217ed2SChris Mason } else { 80e20d96d6SChris Mason btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 817eccb903SChris Mason bh_blocknr(cow)); 82d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 837eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 8402217ed2SChris Mason } 85234b63a0SChris Mason btrfs_block_release(root, buf); 86df24a2b9SChris Mason mark_buffer_dirty(cow); 872c90e5d6SChris Mason *cow_ret = cow; 8802217ed2SChris Mason return 0; 8902217ed2SChris Mason } 9002217ed2SChris Mason 9174123bd7SChris Mason /* 9274123bd7SChris Mason * The leaf data grows from end-to-front in the node. 9374123bd7SChris Mason * this returns the address of the start of the last item, 9474123bd7SChris Mason * which is the stop of the leaf data stack 9574123bd7SChris Mason */ 96123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 97123abc88SChris Mason struct btrfs_leaf *leaf) 98be0e5c09SChris Mason { 997518a238SChris Mason u32 nr = btrfs_header_nritems(&leaf->header); 100be0e5c09SChris Mason if (nr == 0) 101123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 1020783fcfcSChris Mason return btrfs_item_offset(leaf->items + nr - 1); 103be0e5c09SChris Mason } 104be0e5c09SChris Mason 10574123bd7SChris Mason /* 10674123bd7SChris Mason * compare two keys in a memcmp fashion 10774123bd7SChris Mason */ 1089aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 109be0e5c09SChris Mason { 110e2fa7227SChris Mason struct btrfs_key k1; 111e2fa7227SChris Mason 112e2fa7227SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 113e2fa7227SChris Mason 114e2fa7227SChris Mason if (k1.objectid > k2->objectid) 115be0e5c09SChris Mason return 1; 116e2fa7227SChris Mason if (k1.objectid < k2->objectid) 117be0e5c09SChris Mason return -1; 118f254e52cSChris Mason if (k1.flags > k2->flags) 119f254e52cSChris Mason return 1; 120f254e52cSChris Mason if (k1.flags < k2->flags) 121f254e52cSChris Mason return -1; 12270b2befdSChris Mason if (k1.offset > k2->offset) 12370b2befdSChris Mason return 1; 12470b2befdSChris Mason if (k1.offset < k2->offset) 12570b2befdSChris Mason return -1; 126be0e5c09SChris Mason return 0; 127be0e5c09SChris Mason } 12874123bd7SChris Mason 129123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 130123abc88SChris Mason int level) 131aa5d6bedSChris Mason { 132aa5d6bedSChris Mason int i; 133234b63a0SChris Mason struct btrfs_node *parent = NULL; 134e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 135aa5d6bedSChris Mason int parent_slot; 1367518a238SChris Mason u32 nritems = btrfs_header_nritems(&node->header); 137aa5d6bedSChris Mason 138aa5d6bedSChris Mason if (path->nodes[level + 1]) 139e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 140aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 1417518a238SChris Mason BUG_ON(nritems == 0); 1427518a238SChris Mason if (parent) { 143e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 144123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 145123abc88SChris Mason BUG_ON(memcmp(parent_key, &node->ptrs[0].key, 146e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1471d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1487518a238SChris Mason btrfs_header_blocknr(&node->header)); 149aa5d6bedSChris Mason } 150123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 1517518a238SChris Mason for (i = 0; nritems > 1 && i < nritems - 2; i++) { 152e2fa7227SChris Mason struct btrfs_key cpukey; 153123abc88SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[i + 1].key); 154123abc88SChris Mason BUG_ON(comp_keys(&node->ptrs[i].key, &cpukey) >= 0); 155aa5d6bedSChris Mason } 156aa5d6bedSChris Mason return 0; 157aa5d6bedSChris Mason } 158aa5d6bedSChris Mason 159123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 160123abc88SChris Mason int level) 161aa5d6bedSChris Mason { 162aa5d6bedSChris Mason int i; 163e20d96d6SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); 164234b63a0SChris Mason struct btrfs_node *parent = NULL; 165aa5d6bedSChris Mason int parent_slot; 1667518a238SChris Mason u32 nritems = btrfs_header_nritems(&leaf->header); 167aa5d6bedSChris Mason 168aa5d6bedSChris Mason if (path->nodes[level + 1]) 169e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 170aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 171123abc88SChris Mason BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 1727518a238SChris Mason 1737518a238SChris Mason if (nritems == 0) 1747518a238SChris Mason return 0; 1757518a238SChris Mason 1767518a238SChris Mason if (parent) { 177e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 178123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 179aa5d6bedSChris Mason BUG_ON(memcmp(parent_key, &leaf->items[0].key, 180e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1811d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1827518a238SChris Mason btrfs_header_blocknr(&leaf->header)); 183aa5d6bedSChris Mason } 1847518a238SChris Mason for (i = 0; nritems > 1 && i < nritems - 2; i++) { 185e2fa7227SChris Mason struct btrfs_key cpukey; 186e2fa7227SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key); 187aa5d6bedSChris Mason BUG_ON(comp_keys(&leaf->items[i].key, 188e2fa7227SChris Mason &cpukey) >= 0); 1890783fcfcSChris Mason BUG_ON(btrfs_item_offset(leaf->items + i) != 1900783fcfcSChris Mason btrfs_item_end(leaf->items + i + 1)); 191aa5d6bedSChris Mason if (i == 0) { 1920783fcfcSChris Mason BUG_ON(btrfs_item_offset(leaf->items + i) + 1930783fcfcSChris Mason btrfs_item_size(leaf->items + i) != 194123abc88SChris Mason BTRFS_LEAF_DATA_SIZE(root)); 195aa5d6bedSChris Mason } 196aa5d6bedSChris Mason } 197aa5d6bedSChris Mason return 0; 198aa5d6bedSChris Mason } 199aa5d6bedSChris Mason 200123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 201123abc88SChris Mason int level) 202aa5d6bedSChris Mason { 2033eb0314dSChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 2043eb0314dSChris Mason if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, 2053eb0314dSChris Mason sizeof(node->header.fsid))) 2063eb0314dSChris Mason BUG(); 207aa5d6bedSChris Mason if (level == 0) 208123abc88SChris Mason return check_leaf(root, path, level); 209123abc88SChris Mason return check_node(root, path, level); 210aa5d6bedSChris Mason } 211aa5d6bedSChris Mason 21274123bd7SChris Mason /* 21374123bd7SChris Mason * search for key in the array p. items p are item_size apart 21474123bd7SChris Mason * and there are 'max' items in p 21574123bd7SChris Mason * the slot in the array is returned via slot, and it points to 21674123bd7SChris Mason * the place where you would insert key if it is not found in 21774123bd7SChris Mason * the array. 21874123bd7SChris Mason * 21974123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 22074123bd7SChris Mason */ 2219aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, 222be0e5c09SChris Mason int max, int *slot) 223be0e5c09SChris Mason { 224be0e5c09SChris Mason int low = 0; 225be0e5c09SChris Mason int high = max; 226be0e5c09SChris Mason int mid; 227be0e5c09SChris Mason int ret; 228e2fa7227SChris Mason struct btrfs_disk_key *tmp; 229be0e5c09SChris Mason 230be0e5c09SChris Mason while(low < high) { 231be0e5c09SChris Mason mid = (low + high) / 2; 232e2fa7227SChris Mason tmp = (struct btrfs_disk_key *)(p + mid * item_size); 233be0e5c09SChris Mason ret = comp_keys(tmp, key); 234be0e5c09SChris Mason 235be0e5c09SChris Mason if (ret < 0) 236be0e5c09SChris Mason low = mid + 1; 237be0e5c09SChris Mason else if (ret > 0) 238be0e5c09SChris Mason high = mid; 239be0e5c09SChris Mason else { 240be0e5c09SChris Mason *slot = mid; 241be0e5c09SChris Mason return 0; 242be0e5c09SChris Mason } 243be0e5c09SChris Mason } 244be0e5c09SChris Mason *slot = low; 245be0e5c09SChris Mason return 1; 246be0e5c09SChris Mason } 247be0e5c09SChris Mason 24897571fd0SChris Mason /* 24997571fd0SChris Mason * simple bin_search frontend that does the right thing for 25097571fd0SChris Mason * leaves vs nodes 25197571fd0SChris Mason */ 2529aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) 253be0e5c09SChris Mason { 2547518a238SChris Mason if (btrfs_is_leaf(c)) { 255234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 2560783fcfcSChris Mason return generic_bin_search((void *)l->items, 2570783fcfcSChris Mason sizeof(struct btrfs_item), 2587518a238SChris Mason key, btrfs_header_nritems(&c->header), 2597518a238SChris Mason slot); 260be0e5c09SChris Mason } else { 261123abc88SChris Mason return generic_bin_search((void *)c->ptrs, 262123abc88SChris Mason sizeof(struct btrfs_key_ptr), 2637518a238SChris Mason key, btrfs_header_nritems(&c->header), 2647518a238SChris Mason slot); 265be0e5c09SChris Mason } 266be0e5c09SChris Mason return -1; 267be0e5c09SChris Mason } 268be0e5c09SChris Mason 269e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root, 270e20d96d6SChris Mason struct buffer_head *parent_buf, 271bb803951SChris Mason int slot) 272bb803951SChris Mason { 273e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(parent_buf); 274bb803951SChris Mason if (slot < 0) 275bb803951SChris Mason return NULL; 2767518a238SChris Mason if (slot >= btrfs_header_nritems(&node->header)) 277bb803951SChris Mason return NULL; 2781d4f8a0cSChris Mason return read_tree_block(root, btrfs_node_blockptr(node, slot)); 279bb803951SChris Mason } 280bb803951SChris Mason 281e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 282e089f05cSChris Mason *root, struct btrfs_path *path, int level) 283bb803951SChris Mason { 284e20d96d6SChris Mason struct buffer_head *right_buf; 285e20d96d6SChris Mason struct buffer_head *mid_buf; 286e20d96d6SChris Mason struct buffer_head *left_buf; 287e20d96d6SChris Mason struct buffer_head *parent_buf = NULL; 288234b63a0SChris Mason struct btrfs_node *right = NULL; 289234b63a0SChris Mason struct btrfs_node *mid; 290234b63a0SChris Mason struct btrfs_node *left = NULL; 291234b63a0SChris Mason struct btrfs_node *parent = NULL; 292bb803951SChris Mason int ret = 0; 293bb803951SChris Mason int wret; 294bb803951SChris Mason int pslot; 295bb803951SChris Mason int orig_slot = path->slots[level]; 29679f95c82SChris Mason u64 orig_ptr; 297bb803951SChris Mason 298bb803951SChris Mason if (level == 0) 299bb803951SChris Mason return 0; 300bb803951SChris Mason 301bb803951SChris Mason mid_buf = path->nodes[level]; 302e20d96d6SChris Mason mid = btrfs_buffer_node(mid_buf); 3031d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 30479f95c82SChris Mason 305234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 306bb803951SChris Mason parent_buf = path->nodes[level + 1]; 307bb803951SChris Mason pslot = path->slots[level + 1]; 308bb803951SChris Mason 30940689478SChris Mason /* 31040689478SChris Mason * deal with the case where there is only one pointer in the root 31140689478SChris Mason * by promoting the node below to a root 31240689478SChris Mason */ 313bb803951SChris Mason if (!parent_buf) { 314e20d96d6SChris Mason struct buffer_head *child; 3157eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 316bb803951SChris Mason 3177518a238SChris Mason if (btrfs_header_nritems(&mid->header) != 1) 318bb803951SChris Mason return 0; 319bb803951SChris Mason 320bb803951SChris Mason /* promote the child to a root */ 321bb803951SChris Mason child = read_node_slot(root, mid_buf, 0); 322bb803951SChris Mason BUG_ON(!child); 323bb803951SChris Mason root->node = child; 324bb803951SChris Mason path->nodes[level] = NULL; 325d6025579SChris Mason clean_tree_block(trans, root, mid_buf); 326d6025579SChris Mason wait_on_buffer(mid_buf); 327bb803951SChris Mason /* once for the path */ 328234b63a0SChris Mason btrfs_block_release(root, mid_buf); 329bb803951SChris Mason /* once for the root ptr */ 330234b63a0SChris Mason btrfs_block_release(root, mid_buf); 331e089f05cSChris Mason return btrfs_free_extent(trans, root, blocknr, 1, 1); 332bb803951SChris Mason } 333e20d96d6SChris Mason parent = btrfs_buffer_node(parent_buf); 334bb803951SChris Mason 335123abc88SChris Mason if (btrfs_header_nritems(&mid->header) > 336123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 337bb803951SChris Mason return 0; 338bb803951SChris Mason 339bb803951SChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 340bb803951SChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 34179f95c82SChris Mason 34279f95c82SChris Mason /* first, try to make some room in the middle buffer */ 343bb803951SChris Mason if (left_buf) { 344e089f05cSChris Mason btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, 345e089f05cSChris Mason &left_buf); 346e20d96d6SChris Mason left = btrfs_buffer_node(left_buf); 3477518a238SChris Mason orig_slot += btrfs_header_nritems(&left->header); 348e089f05cSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 34979f95c82SChris Mason if (wret < 0) 35079f95c82SChris Mason ret = wret; 351bb803951SChris Mason } 35279f95c82SChris Mason 35379f95c82SChris Mason /* 35479f95c82SChris Mason * then try to empty the right most buffer into the middle 35579f95c82SChris Mason */ 356bb803951SChris Mason if (right_buf) { 357e089f05cSChris Mason btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, 358e089f05cSChris Mason &right_buf); 359e20d96d6SChris Mason right = btrfs_buffer_node(right_buf); 360e089f05cSChris Mason wret = push_node_left(trans, root, mid_buf, right_buf); 36179f95c82SChris Mason if (wret < 0) 36279f95c82SChris Mason ret = wret; 3637518a238SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 3647eccb903SChris Mason u64 blocknr = bh_blocknr(right_buf); 365e089f05cSChris Mason clean_tree_block(trans, root, right_buf); 366d6025579SChris Mason wait_on_buffer(right_buf); 367d6025579SChris Mason btrfs_block_release(root, right_buf); 368bb803951SChris Mason right_buf = NULL; 369bb803951SChris Mason right = NULL; 370e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 371e089f05cSChris Mason 1); 372bb803951SChris Mason if (wret) 373bb803951SChris Mason ret = wret; 374e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 375bb803951SChris Mason if (wret) 376bb803951SChris Mason ret = wret; 377bb803951SChris Mason } else { 378d6025579SChris Mason btrfs_memcpy(root, parent, 379d6025579SChris Mason &parent->ptrs[pslot + 1].key, 380123abc88SChris Mason &right->ptrs[0].key, 381e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 382d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 383bb803951SChris Mason } 384bb803951SChris Mason } 3857518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 1) { 38679f95c82SChris Mason /* 38779f95c82SChris Mason * we're not allowed to leave a node with one item in the 38879f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 38979f95c82SChris Mason * could try to delete the only pointer in this node. 39079f95c82SChris Mason * So, pull some keys from the left. 39179f95c82SChris Mason * There has to be a left pointer at this point because 39279f95c82SChris Mason * otherwise we would have pulled some pointers from the 39379f95c82SChris Mason * right 39479f95c82SChris Mason */ 39579f95c82SChris Mason BUG_ON(!left_buf); 396e089f05cSChris Mason wret = balance_node_right(trans, root, mid_buf, left_buf); 39779f95c82SChris Mason if (wret < 0) 39879f95c82SChris Mason ret = wret; 39979f95c82SChris Mason BUG_ON(wret == 1); 40079f95c82SChris Mason } 4017518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 0) { 40279f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 4037eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 404e089f05cSChris Mason clean_tree_block(trans, root, mid_buf); 405d6025579SChris Mason wait_on_buffer(mid_buf); 406d6025579SChris Mason btrfs_block_release(root, mid_buf); 407bb803951SChris Mason mid_buf = NULL; 408bb803951SChris Mason mid = NULL; 409e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 410bb803951SChris Mason if (wret) 411bb803951SChris Mason ret = wret; 412e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 413bb803951SChris Mason if (wret) 414bb803951SChris Mason ret = wret; 41579f95c82SChris Mason } else { 41679f95c82SChris Mason /* update the parent key to reflect our changes */ 417d6025579SChris Mason btrfs_memcpy(root, parent, 418d6025579SChris Mason &parent->ptrs[pslot].key, &mid->ptrs[0].key, 419e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 420d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 42179f95c82SChris Mason } 422bb803951SChris Mason 42379f95c82SChris Mason /* update the path */ 424bb803951SChris Mason if (left_buf) { 4257518a238SChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 426e20d96d6SChris Mason get_bh(left_buf); 427bb803951SChris Mason path->nodes[level] = left_buf; 428bb803951SChris Mason path->slots[level + 1] -= 1; 429bb803951SChris Mason path->slots[level] = orig_slot; 430bb803951SChris Mason if (mid_buf) 431234b63a0SChris Mason btrfs_block_release(root, mid_buf); 432bb803951SChris Mason } else { 4337518a238SChris Mason orig_slot -= btrfs_header_nritems(&left->header); 434bb803951SChris Mason path->slots[level] = orig_slot; 435bb803951SChris Mason } 436bb803951SChris Mason } 43779f95c82SChris Mason /* double check we haven't messed things up */ 438123abc88SChris Mason check_block(root, path, level); 439e20d96d6SChris Mason if (orig_ptr != 440e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 4411d4f8a0cSChris Mason path->slots[level])) 44279f95c82SChris Mason BUG(); 443bb803951SChris Mason 444bb803951SChris Mason if (right_buf) 445234b63a0SChris Mason btrfs_block_release(root, right_buf); 446bb803951SChris Mason if (left_buf) 447234b63a0SChris Mason btrfs_block_release(root, left_buf); 448bb803951SChris Mason return ret; 449bb803951SChris Mason } 450bb803951SChris Mason 451e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 452e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 453e66f709bSChris Mason struct btrfs_root *root, 454e66f709bSChris Mason struct btrfs_path *path, int level) 455e66f709bSChris Mason { 456e66f709bSChris Mason struct buffer_head *right_buf; 457e66f709bSChris Mason struct buffer_head *mid_buf; 458e66f709bSChris Mason struct buffer_head *left_buf; 459e66f709bSChris Mason struct buffer_head *parent_buf = NULL; 460e66f709bSChris Mason struct btrfs_node *right = NULL; 461e66f709bSChris Mason struct btrfs_node *mid; 462e66f709bSChris Mason struct btrfs_node *left = NULL; 463e66f709bSChris Mason struct btrfs_node *parent = NULL; 464e66f709bSChris Mason int ret = 0; 465e66f709bSChris Mason int wret; 466e66f709bSChris Mason int pslot; 467e66f709bSChris Mason int orig_slot = path->slots[level]; 468e66f709bSChris Mason u64 orig_ptr; 469e66f709bSChris Mason 470e66f709bSChris Mason if (level == 0) 471e66f709bSChris Mason return 1; 472e66f709bSChris Mason 473e66f709bSChris Mason mid_buf = path->nodes[level]; 474e66f709bSChris Mason mid = btrfs_buffer_node(mid_buf); 475e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 476e66f709bSChris Mason 477e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 478e66f709bSChris Mason parent_buf = path->nodes[level + 1]; 479e66f709bSChris Mason pslot = path->slots[level + 1]; 480e66f709bSChris Mason 481e66f709bSChris Mason if (!parent_buf) 482e66f709bSChris Mason return 1; 483e66f709bSChris Mason parent = btrfs_buffer_node(parent_buf); 484e66f709bSChris Mason 485e66f709bSChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 486e66f709bSChris Mason 487e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 488e66f709bSChris Mason if (left_buf) { 489e66f709bSChris Mason u32 left_nr; 490e66f709bSChris Mason left = btrfs_buffer_node(left_buf); 491e66f709bSChris Mason left_nr = btrfs_header_nritems(&left->header); 492*33ade1f8SChris Mason if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 493*33ade1f8SChris Mason wret = 1; 494*33ade1f8SChris Mason } else { 495*33ade1f8SChris Mason btrfs_cow_block(trans, root, left_buf, parent_buf, 496*33ade1f8SChris Mason pslot - 1, &left_buf); 497*33ade1f8SChris Mason left = btrfs_buffer_node(left_buf); 498e66f709bSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 499*33ade1f8SChris Mason } 500e66f709bSChris Mason if (wret < 0) 501e66f709bSChris Mason ret = wret; 502e66f709bSChris Mason if (wret == 0) { 503e66f709bSChris Mason orig_slot += left_nr; 504e66f709bSChris Mason btrfs_memcpy(root, parent, 505e66f709bSChris Mason &parent->ptrs[pslot].key, 506e66f709bSChris Mason &mid->ptrs[0].key, 507e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 508e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 509e66f709bSChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 510e66f709bSChris Mason path->nodes[level] = left_buf; 511e66f709bSChris Mason path->slots[level + 1] -= 1; 512e66f709bSChris Mason path->slots[level] = orig_slot; 513e66f709bSChris Mason btrfs_block_release(root, mid_buf); 514e66f709bSChris Mason } else { 515e66f709bSChris Mason orig_slot -= 516e66f709bSChris Mason btrfs_header_nritems(&left->header); 517e66f709bSChris Mason path->slots[level] = orig_slot; 518e66f709bSChris Mason btrfs_block_release(root, left_buf); 519e66f709bSChris Mason } 520e66f709bSChris Mason check_node(root, path, level); 521e66f709bSChris Mason return 0; 522e66f709bSChris Mason } 523e66f709bSChris Mason btrfs_block_release(root, left_buf); 524e66f709bSChris Mason } 525e66f709bSChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 526e66f709bSChris Mason 527e66f709bSChris Mason /* 528e66f709bSChris Mason * then try to empty the right most buffer into the middle 529e66f709bSChris Mason */ 530e66f709bSChris Mason if (right_buf) { 531*33ade1f8SChris Mason u32 right_nr; 532e66f709bSChris Mason right = btrfs_buffer_node(right_buf); 533*33ade1f8SChris Mason right_nr = btrfs_header_nritems(&right->header); 534*33ade1f8SChris Mason if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 535*33ade1f8SChris Mason wret = 1; 536*33ade1f8SChris Mason } else { 537*33ade1f8SChris Mason btrfs_cow_block(trans, root, right_buf, 538*33ade1f8SChris Mason parent_buf, pslot + 1, &right_buf); 539*33ade1f8SChris Mason right = btrfs_buffer_node(right_buf); 540*33ade1f8SChris Mason wret = balance_node_right(trans, root, 541*33ade1f8SChris Mason right_buf, mid_buf); 542*33ade1f8SChris Mason } 543e66f709bSChris Mason if (wret < 0) 544e66f709bSChris Mason ret = wret; 545e66f709bSChris Mason if (wret == 0) { 546e66f709bSChris Mason btrfs_memcpy(root, parent, 547e66f709bSChris Mason &parent->ptrs[pslot + 1].key, 548e66f709bSChris Mason &right->ptrs[0].key, 549e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 550e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 551e66f709bSChris Mason if (btrfs_header_nritems(&mid->header) <= orig_slot) { 552e66f709bSChris Mason path->nodes[level] = right_buf; 553e66f709bSChris Mason path->slots[level + 1] += 1; 554e66f709bSChris Mason path->slots[level] = orig_slot - 555e66f709bSChris Mason btrfs_header_nritems(&mid->header); 556e66f709bSChris Mason btrfs_block_release(root, mid_buf); 557e66f709bSChris Mason } else { 558e66f709bSChris Mason btrfs_block_release(root, right_buf); 559e66f709bSChris Mason } 560e66f709bSChris Mason check_node(root, path, level); 561e66f709bSChris Mason return 0; 562e66f709bSChris Mason } 563e66f709bSChris Mason btrfs_block_release(root, right_buf); 564e66f709bSChris Mason } 565e66f709bSChris Mason check_node(root, path, level); 566e66f709bSChris Mason return 1; 567e66f709bSChris Mason } 568e66f709bSChris Mason 56974123bd7SChris Mason /* 57074123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 57174123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 57274123bd7SChris Mason * level of the path (level 0) 57374123bd7SChris Mason * 57474123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 575aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 576aa5d6bedSChris Mason * search a negative error number is returned. 57797571fd0SChris Mason * 57897571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 57997571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 58097571fd0SChris Mason * possible) 58174123bd7SChris Mason */ 582e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 583e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 584e089f05cSChris Mason ins_len, int cow) 585be0e5c09SChris Mason { 586e20d96d6SChris Mason struct buffer_head *b; 587e20d96d6SChris Mason struct buffer_head *cow_buf; 588234b63a0SChris Mason struct btrfs_node *c; 589be0e5c09SChris Mason int slot; 590be0e5c09SChris Mason int ret; 591be0e5c09SChris Mason int level; 5925c680ed6SChris Mason 59322b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 59422b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 595bb803951SChris Mason again: 596bb803951SChris Mason b = root->node; 597e20d96d6SChris Mason get_bh(b); 598eb60ceacSChris Mason while (b) { 599e20d96d6SChris Mason c = btrfs_buffer_node(b); 600e20d96d6SChris Mason level = btrfs_header_level(&c->header); 60102217ed2SChris Mason if (cow) { 60202217ed2SChris Mason int wret; 603e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 604e20d96d6SChris Mason p->nodes[level + 1], 605e20d96d6SChris Mason p->slots[level + 1], 606e089f05cSChris Mason &cow_buf); 60702217ed2SChris Mason b = cow_buf; 6082c90e5d6SChris Mason c = btrfs_buffer_node(b); 60902217ed2SChris Mason } 61002217ed2SChris Mason BUG_ON(!cow && ins_len); 6112c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 6122c90e5d6SChris Mason WARN_ON(1); 6132c90e5d6SChris Mason level = btrfs_header_level(&c->header); 614eb60ceacSChris Mason p->nodes[level] = b; 615123abc88SChris Mason ret = check_block(root, p, level); 616aa5d6bedSChris Mason if (ret) 617aa5d6bedSChris Mason return -1; 618be0e5c09SChris Mason ret = bin_search(c, key, &slot); 6197518a238SChris Mason if (!btrfs_is_leaf(c)) { 620be0e5c09SChris Mason if (ret && slot > 0) 621be0e5c09SChris Mason slot -= 1; 622be0e5c09SChris Mason p->slots[level] = slot; 623d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 624d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 625e089f05cSChris Mason int sret = split_node(trans, root, p, level); 6265c680ed6SChris Mason BUG_ON(sret > 0); 6275c680ed6SChris Mason if (sret) 6285c680ed6SChris Mason return sret; 6295c680ed6SChris Mason b = p->nodes[level]; 630e20d96d6SChris Mason c = btrfs_buffer_node(b); 6315c680ed6SChris Mason slot = p->slots[level]; 632bb803951SChris Mason } else if (ins_len < 0) { 633e089f05cSChris Mason int sret = balance_level(trans, root, p, 634e089f05cSChris Mason level); 635bb803951SChris Mason if (sret) 636bb803951SChris Mason return sret; 637bb803951SChris Mason b = p->nodes[level]; 638bb803951SChris Mason if (!b) 639bb803951SChris Mason goto again; 640e20d96d6SChris Mason c = btrfs_buffer_node(b); 641bb803951SChris Mason slot = p->slots[level]; 6427518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 6435c680ed6SChris Mason } 6441d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 645be0e5c09SChris Mason } else { 646234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 647be0e5c09SChris Mason p->slots[level] = slot; 648123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 6490783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 650d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 651d4dbff95SChris Mason p, ins_len); 6525c680ed6SChris Mason BUG_ON(sret > 0); 6535c680ed6SChris Mason if (sret) 6545c680ed6SChris Mason return sret; 6555c680ed6SChris Mason } 656be0e5c09SChris Mason return ret; 657be0e5c09SChris Mason } 658be0e5c09SChris Mason } 659aa5d6bedSChris Mason return 1; 660be0e5c09SChris Mason } 661be0e5c09SChris Mason 66274123bd7SChris Mason /* 66374123bd7SChris Mason * adjust the pointers going up the tree, starting at level 66474123bd7SChris Mason * making sure the right key of each node is points to 'key'. 66574123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 66674123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 66774123bd7SChris Mason * higher levels 668aa5d6bedSChris Mason * 669aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 670aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 67174123bd7SChris Mason */ 672e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 673e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 674e089f05cSChris Mason *key, int level) 675be0e5c09SChris Mason { 676be0e5c09SChris Mason int i; 677aa5d6bedSChris Mason int ret = 0; 678234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 679234b63a0SChris Mason struct btrfs_node *t; 680be0e5c09SChris Mason int tslot = path->slots[i]; 681eb60ceacSChris Mason if (!path->nodes[i]) 682be0e5c09SChris Mason break; 683e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 684d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 685d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 686be0e5c09SChris Mason if (tslot != 0) 687be0e5c09SChris Mason break; 688be0e5c09SChris Mason } 689aa5d6bedSChris Mason return ret; 690be0e5c09SChris Mason } 691be0e5c09SChris Mason 69274123bd7SChris Mason /* 69374123bd7SChris Mason * try to push data from one node into the next node left in the 69479f95c82SChris Mason * tree. 695aa5d6bedSChris Mason * 696aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 697aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 69874123bd7SChris Mason */ 699e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 700e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 701e20d96d6SChris Mason buffer_head *src_buf) 702be0e5c09SChris Mason { 703e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 704e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 705be0e5c09SChris Mason int push_items = 0; 706bb803951SChris Mason int src_nritems; 707bb803951SChris Mason int dst_nritems; 708aa5d6bedSChris Mason int ret = 0; 709be0e5c09SChris Mason 7107518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7117518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 712123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 713eb60ceacSChris Mason if (push_items <= 0) { 714be0e5c09SChris Mason return 1; 715eb60ceacSChris Mason } 716be0e5c09SChris Mason 717be0e5c09SChris Mason if (src_nritems < push_items) 718be0e5c09SChris Mason push_items = src_nritems; 71979f95c82SChris Mason 720d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 721123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 722bb803951SChris Mason if (push_items < src_nritems) { 723d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 724e2fa7227SChris Mason (src_nritems - push_items) * 725123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 726bb803951SChris Mason } 7277518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 7287518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 729d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 730d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 731bb803951SChris Mason return ret; 732be0e5c09SChris Mason } 733be0e5c09SChris Mason 73497571fd0SChris Mason /* 73579f95c82SChris Mason * try to push data from one node into the next node right in the 73679f95c82SChris Mason * tree. 73779f95c82SChris Mason * 73879f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 73979f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 74079f95c82SChris Mason * 74179f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 74279f95c82SChris Mason */ 743e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 744e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 745e20d96d6SChris Mason struct buffer_head *src_buf) 74679f95c82SChris Mason { 747e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 748e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 74979f95c82SChris Mason int push_items = 0; 75079f95c82SChris Mason int max_push; 75179f95c82SChris Mason int src_nritems; 75279f95c82SChris Mason int dst_nritems; 75379f95c82SChris Mason int ret = 0; 75479f95c82SChris Mason 7557518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7567518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 757123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 75879f95c82SChris Mason if (push_items <= 0) { 75979f95c82SChris Mason return 1; 76079f95c82SChris Mason } 76179f95c82SChris Mason 76279f95c82SChris Mason max_push = src_nritems / 2 + 1; 76379f95c82SChris Mason /* don't try to empty the node */ 76479f95c82SChris Mason if (max_push > src_nritems) 76579f95c82SChris Mason return 1; 76679f95c82SChris Mason if (max_push < push_items) 76779f95c82SChris Mason push_items = max_push; 76879f95c82SChris Mason 769d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 770123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 771d6025579SChris Mason 772d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 773d6025579SChris Mason src->ptrs + src_nritems - push_items, 774123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 77579f95c82SChris Mason 7767518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 7777518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 77879f95c82SChris Mason 779d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 780d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 78179f95c82SChris Mason return ret; 78279f95c82SChris Mason } 78379f95c82SChris Mason 78479f95c82SChris Mason /* 78597571fd0SChris Mason * helper function to insert a new root level in the tree. 78697571fd0SChris Mason * A new node is allocated, and a single item is inserted to 78797571fd0SChris Mason * point to the existing root 788aa5d6bedSChris Mason * 789aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 79097571fd0SChris Mason */ 791e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 792e089f05cSChris Mason *root, struct btrfs_path *path, int level) 79374123bd7SChris Mason { 794e20d96d6SChris Mason struct buffer_head *t; 795234b63a0SChris Mason struct btrfs_node *lower; 796234b63a0SChris Mason struct btrfs_node *c; 797e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 7985c680ed6SChris Mason 7995c680ed6SChris Mason BUG_ON(path->nodes[level]); 8005c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 8015c680ed6SChris Mason 802e089f05cSChris Mason t = btrfs_alloc_free_block(trans, root); 803e20d96d6SChris Mason c = btrfs_buffer_node(t); 804123abc88SChris Mason memset(c, 0, root->blocksize); 8057518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 8067518a238SChris Mason btrfs_set_header_level(&c->header, level); 8077eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 8087f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 809e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 8103eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 8113eb0314dSChris Mason sizeof(c->header.fsid)); 8127518a238SChris Mason if (btrfs_is_leaf(lower)) 813234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 81474123bd7SChris Mason else 815123abc88SChris Mason lower_key = &lower->ptrs[0].key; 816d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 817d6025579SChris Mason sizeof(struct btrfs_disk_key)); 8187eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 819d5719762SChris Mason 820d6025579SChris Mason btrfs_mark_buffer_dirty(t); 821d5719762SChris Mason 822cfaa7295SChris Mason /* the super has an extra ref to root->node */ 823234b63a0SChris Mason btrfs_block_release(root, root->node); 82474123bd7SChris Mason root->node = t; 825e20d96d6SChris Mason get_bh(t); 82674123bd7SChris Mason path->nodes[level] = t; 82774123bd7SChris Mason path->slots[level] = 0; 82874123bd7SChris Mason return 0; 82974123bd7SChris Mason } 8305c680ed6SChris Mason 8315c680ed6SChris Mason /* 8325c680ed6SChris Mason * worker function to insert a single pointer in a node. 8335c680ed6SChris Mason * the node should have enough room for the pointer already 83497571fd0SChris Mason * 8355c680ed6SChris Mason * slot and level indicate where you want the key to go, and 8365c680ed6SChris Mason * blocknr is the block the key points to. 837aa5d6bedSChris Mason * 838aa5d6bedSChris Mason * returns zero on success and < 0 on any error 8395c680ed6SChris Mason */ 840e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 841e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 842e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 8435c680ed6SChris Mason { 844234b63a0SChris Mason struct btrfs_node *lower; 8455c680ed6SChris Mason int nritems; 8465c680ed6SChris Mason 8475c680ed6SChris Mason BUG_ON(!path->nodes[level]); 848e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 8497518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 85074123bd7SChris Mason if (slot > nritems) 85174123bd7SChris Mason BUG(); 852123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 85374123bd7SChris Mason BUG(); 85474123bd7SChris Mason if (slot != nritems) { 855d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 856d6025579SChris Mason lower->ptrs + slot, 857123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 85874123bd7SChris Mason } 859d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 860d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 8611d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 8627518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 863d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 86474123bd7SChris Mason return 0; 86574123bd7SChris Mason } 86674123bd7SChris Mason 86797571fd0SChris Mason /* 86897571fd0SChris Mason * split the node at the specified level in path in two. 86997571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 87097571fd0SChris Mason * 87197571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 87297571fd0SChris Mason * left and right, if either one works, it returns right away. 873aa5d6bedSChris Mason * 874aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 87597571fd0SChris Mason */ 876e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 877e089f05cSChris Mason *root, struct btrfs_path *path, int level) 878be0e5c09SChris Mason { 879e20d96d6SChris Mason struct buffer_head *t; 880234b63a0SChris Mason struct btrfs_node *c; 881e20d96d6SChris Mason struct buffer_head *split_buffer; 882234b63a0SChris Mason struct btrfs_node *split; 883be0e5c09SChris Mason int mid; 8845c680ed6SChris Mason int ret; 885aa5d6bedSChris Mason int wret; 8867518a238SChris Mason u32 c_nritems; 887be0e5c09SChris Mason 8885c680ed6SChris Mason t = path->nodes[level]; 889e20d96d6SChris Mason c = btrfs_buffer_node(t); 8905c680ed6SChris Mason if (t == root->node) { 8915c680ed6SChris Mason /* trying to split the root, lets make a new one */ 892e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 8935c680ed6SChris Mason if (ret) 8945c680ed6SChris Mason return ret; 895e66f709bSChris Mason } else { 896e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 897e66f709bSChris Mason t = path->nodes[level]; 898e66f709bSChris Mason c = btrfs_buffer_node(t); 899e66f709bSChris Mason if (!ret && 900e66f709bSChris Mason btrfs_header_nritems(&c->header) < 901e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 902e66f709bSChris Mason return 0; 9035c680ed6SChris Mason } 904e66f709bSChris Mason 9057518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 906e089f05cSChris Mason split_buffer = btrfs_alloc_free_block(trans, root); 907e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 9087518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 9099a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 9107eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 9117f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 9123eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 9133eb0314dSChris Mason sizeof(split->header.fsid)); 9147518a238SChris Mason mid = (c_nritems + 1) / 2; 915d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 916123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 9177518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 9187518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 919aa5d6bedSChris Mason ret = 0; 920aa5d6bedSChris Mason 921d6025579SChris Mason btrfs_mark_buffer_dirty(t); 922d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 923e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 9247eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 925123abc88SChris Mason level + 1); 926aa5d6bedSChris Mason if (wret) 927aa5d6bedSChris Mason ret = wret; 928aa5d6bedSChris Mason 9295de08d7dSChris Mason if (path->slots[level] >= mid) { 9305c680ed6SChris Mason path->slots[level] -= mid; 931234b63a0SChris Mason btrfs_block_release(root, t); 9325c680ed6SChris Mason path->nodes[level] = split_buffer; 9335c680ed6SChris Mason path->slots[level + 1] += 1; 934eb60ceacSChris Mason } else { 935234b63a0SChris Mason btrfs_block_release(root, split_buffer); 936be0e5c09SChris Mason } 937aa5d6bedSChris Mason return ret; 938be0e5c09SChris Mason } 939be0e5c09SChris Mason 94074123bd7SChris Mason /* 94174123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 94274123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 94374123bd7SChris Mason * space used both by the item structs and the item data 94474123bd7SChris Mason */ 945234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 946be0e5c09SChris Mason { 947be0e5c09SChris Mason int data_len; 948d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 949d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 950be0e5c09SChris Mason 951be0e5c09SChris Mason if (!nr) 952be0e5c09SChris Mason return 0; 9530783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 9540783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 9550783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 956d4dbff95SChris Mason WARN_ON(data_len < 0); 957be0e5c09SChris Mason return data_len; 958be0e5c09SChris Mason } 959be0e5c09SChris Mason 96074123bd7SChris Mason /* 961d4dbff95SChris Mason * The space between the end of the leaf items and 962d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 963d4dbff95SChris Mason * the leaf has left for both items and data 964d4dbff95SChris Mason */ 965d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 966d4dbff95SChris Mason { 967d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 968d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 969d4dbff95SChris Mason } 970d4dbff95SChris Mason 971d4dbff95SChris Mason /* 97200ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 97300ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 974aa5d6bedSChris Mason * 975aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 976aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 97700ec4c51SChris Mason */ 978e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 979e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 98000ec4c51SChris Mason { 981e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 982e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 983234b63a0SChris Mason struct btrfs_leaf *right; 984e20d96d6SChris Mason struct buffer_head *right_buf; 985e20d96d6SChris Mason struct buffer_head *upper; 986e20d96d6SChris Mason struct btrfs_node *upper_node; 98700ec4c51SChris Mason int slot; 98800ec4c51SChris Mason int i; 98900ec4c51SChris Mason int free_space; 99000ec4c51SChris Mason int push_space = 0; 99100ec4c51SChris Mason int push_items = 0; 9920783fcfcSChris Mason struct btrfs_item *item; 9937518a238SChris Mason u32 left_nritems; 9947518a238SChris Mason u32 right_nritems; 99500ec4c51SChris Mason 99600ec4c51SChris Mason slot = path->slots[1]; 99700ec4c51SChris Mason if (!path->nodes[1]) { 99800ec4c51SChris Mason return 1; 99900ec4c51SChris Mason } 100000ec4c51SChris Mason upper = path->nodes[1]; 1001e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1002e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 100300ec4c51SChris Mason return 1; 100400ec4c51SChris Mason } 1005e20d96d6SChris Mason right_buf = read_tree_block(root, 1006e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 1007e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1008123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10090783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1010234b63a0SChris Mason btrfs_block_release(root, right_buf); 101100ec4c51SChris Mason return 1; 101200ec4c51SChris Mason } 101302217ed2SChris Mason /* cow and double check */ 1014e089f05cSChris Mason btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); 1015e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1016123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10170783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1018234b63a0SChris Mason btrfs_block_release(root, right_buf); 101902217ed2SChris Mason return 1; 102002217ed2SChris Mason } 102102217ed2SChris Mason 10227518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1023a429e513SChris Mason if (left_nritems == 0) { 1024a429e513SChris Mason btrfs_block_release(root, right_buf); 1025a429e513SChris Mason return 1; 1026a429e513SChris Mason } 1027a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 102800ec4c51SChris Mason item = left->items + i; 102900ec4c51SChris Mason if (path->slots[0] == i) 103000ec4c51SChris Mason push_space += data_size + sizeof(*item); 10310783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 10320783fcfcSChris Mason free_space) 103300ec4c51SChris Mason break; 103400ec4c51SChris Mason push_items++; 10350783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 103600ec4c51SChris Mason } 103700ec4c51SChris Mason if (push_items == 0) { 1038234b63a0SChris Mason btrfs_block_release(root, right_buf); 103900ec4c51SChris Mason return 1; 104000ec4c51SChris Mason } 1041a429e513SChris Mason if (push_items == left_nritems) 1042a429e513SChris Mason WARN_ON(1); 10437518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 104400ec4c51SChris Mason /* push left to right */ 10450783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1046123abc88SChris Mason push_space -= leaf_data_end(root, left); 104700ec4c51SChris Mason /* make room in the right data area */ 1048d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1049d6025579SChris Mason leaf_data_end(root, right) - push_space, 1050d6025579SChris Mason btrfs_leaf_data(right) + 1051d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1052d6025579SChris Mason leaf_data_end(root, right)); 105300ec4c51SChris Mason /* copy from the left data area */ 1054d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1055d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1056d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1057d6025579SChris Mason push_space); 1058d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 10590783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 106000ec4c51SChris Mason /* copy the items from left to right */ 1061d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1062d6025579SChris Mason left_nritems - push_items, 10630783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 106400ec4c51SChris Mason 106500ec4c51SChris Mason /* update the item pointers */ 10667518a238SChris Mason right_nritems += push_items; 10677518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1068123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 10697518a238SChris Mason for (i = 0; i < right_nritems; i++) { 10700783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 10710783fcfcSChris Mason btrfs_item_size(right->items + i)); 10720783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 107300ec4c51SChris Mason } 10747518a238SChris Mason left_nritems -= push_items; 10757518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 107600ec4c51SChris Mason 1077d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1078d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1079a429e513SChris Mason 1080d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1081e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1082d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 108302217ed2SChris Mason 108400ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 10857518a238SChris Mason if (path->slots[0] >= left_nritems) { 10867518a238SChris Mason path->slots[0] -= left_nritems; 1087234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 108800ec4c51SChris Mason path->nodes[0] = right_buf; 108900ec4c51SChris Mason path->slots[1] += 1; 109000ec4c51SChris Mason } else { 1091234b63a0SChris Mason btrfs_block_release(root, right_buf); 109200ec4c51SChris Mason } 109300ec4c51SChris Mason return 0; 109400ec4c51SChris Mason } 109500ec4c51SChris Mason /* 109674123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 109774123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 109874123bd7SChris Mason */ 1099e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1100e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1101be0e5c09SChris Mason { 1102e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1103e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1104e20d96d6SChris Mason struct buffer_head *t; 1105234b63a0SChris Mason struct btrfs_leaf *left; 1106be0e5c09SChris Mason int slot; 1107be0e5c09SChris Mason int i; 1108be0e5c09SChris Mason int free_space; 1109be0e5c09SChris Mason int push_space = 0; 1110be0e5c09SChris Mason int push_items = 0; 11110783fcfcSChris Mason struct btrfs_item *item; 11127518a238SChris Mason u32 old_left_nritems; 1113aa5d6bedSChris Mason int ret = 0; 1114aa5d6bedSChris Mason int wret; 1115be0e5c09SChris Mason 1116be0e5c09SChris Mason slot = path->slots[1]; 1117be0e5c09SChris Mason if (slot == 0) { 1118be0e5c09SChris Mason return 1; 1119be0e5c09SChris Mason } 1120be0e5c09SChris Mason if (!path->nodes[1]) { 1121be0e5c09SChris Mason return 1; 1122be0e5c09SChris Mason } 1123e20d96d6SChris Mason t = read_tree_block(root, 1124e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1125e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1126123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11270783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1128234b63a0SChris Mason btrfs_block_release(root, t); 1129be0e5c09SChris Mason return 1; 1130be0e5c09SChris Mason } 113102217ed2SChris Mason 113202217ed2SChris Mason /* cow and double check */ 1133e089f05cSChris Mason btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 1134e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1135123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 11360783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1137234b63a0SChris Mason btrfs_block_release(root, t); 113802217ed2SChris Mason return 1; 113902217ed2SChris Mason } 114002217ed2SChris Mason 1141a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1142a429e513SChris Mason btrfs_block_release(root, t); 1143a429e513SChris Mason return 1; 1144a429e513SChris Mason } 1145a429e513SChris Mason 1146a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1147be0e5c09SChris Mason item = right->items + i; 1148be0e5c09SChris Mason if (path->slots[0] == i) 1149be0e5c09SChris Mason push_space += data_size + sizeof(*item); 11500783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 11510783fcfcSChris Mason free_space) 1152be0e5c09SChris Mason break; 1153be0e5c09SChris Mason push_items++; 11540783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1155be0e5c09SChris Mason } 1156be0e5c09SChris Mason if (push_items == 0) { 1157234b63a0SChris Mason btrfs_block_release(root, t); 1158be0e5c09SChris Mason return 1; 1159be0e5c09SChris Mason } 1160a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1161a429e513SChris Mason WARN_ON(1); 1162be0e5c09SChris Mason /* push data from right to left */ 1163d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1164d6025579SChris Mason btrfs_header_nritems(&left->header), 11650783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1166123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 11670783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1168d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1169d6025579SChris Mason leaf_data_end(root, left) - push_space, 1170123abc88SChris Mason btrfs_leaf_data(right) + 1171123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1172be0e5c09SChris Mason push_space); 11737518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1174eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1175eb60ceacSChris Mason 1176be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1177123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1178123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1179123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 11800783fcfcSChris Mason btrfs_item_offset(left->items + 11810783fcfcSChris Mason old_left_nritems - 1))); 1182be0e5c09SChris Mason } 11837518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1184be0e5c09SChris Mason 1185be0e5c09SChris Mason /* fixup right node */ 11860783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1187123abc88SChris Mason leaf_data_end(root, right); 1188d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1189d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1190d6025579SChris Mason btrfs_leaf_data(right) + 1191123abc88SChris Mason leaf_data_end(root, right), push_space); 1192d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 11937518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 11940783fcfcSChris Mason sizeof(struct btrfs_item)); 11957518a238SChris Mason btrfs_set_header_nritems(&right->header, 11967518a238SChris Mason btrfs_header_nritems(&right->header) - 11977518a238SChris Mason push_items); 1198123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1199eb60ceacSChris Mason 12007518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 12010783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 12020783fcfcSChris Mason btrfs_item_size(right->items + i)); 12030783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1204be0e5c09SChris Mason } 1205eb60ceacSChris Mason 1206d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1207d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1208e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1209aa5d6bedSChris Mason if (wret) 1210aa5d6bedSChris Mason ret = wret; 1211be0e5c09SChris Mason 1212be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1213be0e5c09SChris Mason if (path->slots[0] < push_items) { 1214be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1215234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1216eb60ceacSChris Mason path->nodes[0] = t; 1217be0e5c09SChris Mason path->slots[1] -= 1; 1218be0e5c09SChris Mason } else { 1219234b63a0SChris Mason btrfs_block_release(root, t); 1220be0e5c09SChris Mason path->slots[0] -= push_items; 1221be0e5c09SChris Mason } 1222eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1223aa5d6bedSChris Mason return ret; 1224be0e5c09SChris Mason } 1225be0e5c09SChris Mason 122674123bd7SChris Mason /* 122774123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 122874123bd7SChris Mason * available for the resulting leaf level of the path. 1229aa5d6bedSChris Mason * 1230aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 123174123bd7SChris Mason */ 1232e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1233d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1234d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1235be0e5c09SChris Mason { 1236e20d96d6SChris Mason struct buffer_head *l_buf; 1237234b63a0SChris Mason struct btrfs_leaf *l; 12387518a238SChris Mason u32 nritems; 1239eb60ceacSChris Mason int mid; 1240eb60ceacSChris Mason int slot; 1241234b63a0SChris Mason struct btrfs_leaf *right; 1242e20d96d6SChris Mason struct buffer_head *right_buffer; 12430783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1244be0e5c09SChris Mason int data_copy_size; 1245be0e5c09SChris Mason int rt_data_off; 1246be0e5c09SChris Mason int i; 1247d4dbff95SChris Mason int ret = 0; 1248aa5d6bedSChris Mason int wret; 1249d4dbff95SChris Mason int double_split = 0; 1250d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1251be0e5c09SChris Mason 125240689478SChris Mason /* first try to make some room by pushing left and right */ 1253e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1254eaee50e8SChris Mason if (wret < 0) 1255eaee50e8SChris Mason return wret; 1256eaee50e8SChris Mason if (wret) { 1257e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1258eaee50e8SChris Mason if (wret < 0) 1259eaee50e8SChris Mason return wret; 1260eaee50e8SChris Mason } 1261eb60ceacSChris Mason l_buf = path->nodes[0]; 1262e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1263aa5d6bedSChris Mason 1264aa5d6bedSChris Mason /* did the pushes work? */ 1265123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1266123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1267be0e5c09SChris Mason return 0; 1268aa5d6bedSChris Mason 12695c680ed6SChris Mason if (!path->nodes[1]) { 1270e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 12715c680ed6SChris Mason if (ret) 12725c680ed6SChris Mason return ret; 12735c680ed6SChris Mason } 1274eb60ceacSChris Mason slot = path->slots[0]; 12757518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1276eb60ceacSChris Mason mid = (nritems + 1)/ 2; 1277e089f05cSChris Mason right_buffer = btrfs_alloc_free_block(trans, root); 1278eb60ceacSChris Mason BUG_ON(!right_buffer); 1279e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1280123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 12817eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 12827f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 12837518a238SChris Mason btrfs_set_header_level(&right->header, 0); 12843eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 12853eb0314dSChris Mason sizeof(right->header.fsid)); 1286d4dbff95SChris Mason if (mid <= slot) { 1287d4dbff95SChris Mason if (nritems == 1 || 1288d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1289d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1290d4dbff95SChris Mason if (slot >= nritems) { 1291d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1292d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1293d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1294d4dbff95SChris Mason &disk_key, 12957eccb903SChris Mason bh_blocknr(right_buffer), 1296d4dbff95SChris Mason path->slots[1] + 1, 1); 1297d4dbff95SChris Mason if (wret) 1298d4dbff95SChris Mason ret = wret; 1299d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1300d4dbff95SChris Mason path->nodes[0] = right_buffer; 1301d4dbff95SChris Mason path->slots[0] = 0; 1302d4dbff95SChris Mason path->slots[1] += 1; 1303d4dbff95SChris Mason return ret; 1304d4dbff95SChris Mason } 1305d4dbff95SChris Mason mid = slot; 1306d4dbff95SChris Mason double_split = 1; 1307d4dbff95SChris Mason } 1308d4dbff95SChris Mason } else { 1309d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1310d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1311d4dbff95SChris Mason if (slot == 0) { 1312d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1313d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1314d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1315d4dbff95SChris Mason &disk_key, 13167eccb903SChris Mason bh_blocknr(right_buffer), 1317d4dbff95SChris Mason path->slots[1] - 1, 1); 1318d4dbff95SChris Mason if (wret) 1319d4dbff95SChris Mason ret = wret; 1320d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1321d4dbff95SChris Mason path->nodes[0] = right_buffer; 1322d4dbff95SChris Mason path->slots[0] = 0; 1323d4dbff95SChris Mason path->slots[1] -= 1; 1324a429e513SChris Mason if (path->slots[1] == 0) { 1325a429e513SChris Mason wret = fixup_low_keys(trans, root, 1326a429e513SChris Mason path, &disk_key, 1); 1327a429e513SChris Mason if (wret) 1328a429e513SChris Mason ret = wret; 1329a429e513SChris Mason } 1330d4dbff95SChris Mason return ret; 1331d4dbff95SChris Mason } 1332d4dbff95SChris Mason mid = slot; 1333d4dbff95SChris Mason double_split = 1; 1334d4dbff95SChris Mason } 1335d4dbff95SChris Mason } 1336d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1337123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1338123abc88SChris Mason leaf_data_end(root, l); 1339d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 13400783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1341d6025579SChris Mason btrfs_memcpy(root, right, 1342d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1343123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1344123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1345123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1346123abc88SChris Mason btrfs_item_end(l->items + mid); 134774123bd7SChris Mason 13480783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1349123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 13500783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 13510783fcfcSChris Mason } 135274123bd7SChris Mason 13537518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1354aa5d6bedSChris Mason ret = 0; 1355e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 13567eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1357aa5d6bedSChris Mason if (wret) 1358aa5d6bedSChris Mason ret = wret; 1359d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1360d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1361eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1362be0e5c09SChris Mason if (mid <= slot) { 1363234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1364eb60ceacSChris Mason path->nodes[0] = right_buffer; 1365be0e5c09SChris Mason path->slots[0] -= mid; 1366be0e5c09SChris Mason path->slots[1] += 1; 1367eb60ceacSChris Mason } else 1368234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1369eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1370d4dbff95SChris Mason 1371d4dbff95SChris Mason if (!double_split) 1372d4dbff95SChris Mason return ret; 1373d4dbff95SChris Mason right_buffer = btrfs_alloc_free_block(trans, root); 1374d4dbff95SChris Mason BUG_ON(!right_buffer); 1375d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1376d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 13777eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1378d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 1379d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 13803eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 13813eb0314dSChris Mason sizeof(right->header.fsid)); 1382d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1383d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1384d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1385d4dbff95SChris Mason &disk_key, 13867eccb903SChris Mason bh_blocknr(right_buffer), 1387d4dbff95SChris Mason path->slots[1], 1); 1388d4dbff95SChris Mason if (wret) 1389d4dbff95SChris Mason ret = wret; 1390a429e513SChris Mason if (path->slots[1] == 0) { 1391a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1392a429e513SChris Mason if (wret) 1393a429e513SChris Mason ret = wret; 1394a429e513SChris Mason } 1395d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1396d4dbff95SChris Mason path->nodes[0] = right_buffer; 1397d4dbff95SChris Mason path->slots[0] = 0; 1398d4dbff95SChris Mason check_node(root, path, 1); 1399d4dbff95SChris Mason check_leaf(root, path, 0); 1400be0e5c09SChris Mason return ret; 1401be0e5c09SChris Mason } 1402be0e5c09SChris Mason 1403b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1404b18c6685SChris Mason struct btrfs_root *root, 1405b18c6685SChris Mason struct btrfs_path *path, 1406b18c6685SChris Mason u32 new_size) 1407b18c6685SChris Mason { 1408b18c6685SChris Mason int ret = 0; 1409b18c6685SChris Mason int slot; 1410b18c6685SChris Mason int slot_orig; 1411b18c6685SChris Mason struct btrfs_leaf *leaf; 1412b18c6685SChris Mason struct buffer_head *leaf_buf; 1413b18c6685SChris Mason u32 nritems; 1414b18c6685SChris Mason unsigned int data_end; 1415b18c6685SChris Mason unsigned int old_data_start; 1416b18c6685SChris Mason unsigned int old_size; 1417b18c6685SChris Mason unsigned int size_diff; 1418b18c6685SChris Mason int i; 1419b18c6685SChris Mason 1420b18c6685SChris Mason slot_orig = path->slots[0]; 1421b18c6685SChris Mason leaf_buf = path->nodes[0]; 1422b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1423b18c6685SChris Mason 1424b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1425b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1426b18c6685SChris Mason 1427b18c6685SChris Mason slot = path->slots[0]; 1428b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1429b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1430b18c6685SChris Mason BUG_ON(old_size <= new_size); 1431b18c6685SChris Mason size_diff = old_size - new_size; 1432b18c6685SChris Mason 1433b18c6685SChris Mason BUG_ON(slot < 0); 1434b18c6685SChris Mason BUG_ON(slot >= nritems); 1435b18c6685SChris Mason 1436b18c6685SChris Mason /* 1437b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1438b18c6685SChris Mason */ 1439b18c6685SChris Mason /* first correct the data pointers */ 1440b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1441b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1442b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1443b18c6685SChris Mason ioff + size_diff); 1444b18c6685SChris Mason } 1445b18c6685SChris Mason /* shift the data */ 1446b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1447b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1448b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1449b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1450b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1451b18c6685SChris Mason 1452b18c6685SChris Mason ret = 0; 1453b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1454b18c6685SChris Mason BUG(); 1455b18c6685SChris Mason check_leaf(root, path, 0); 1456b18c6685SChris Mason return ret; 1457b18c6685SChris Mason } 1458b18c6685SChris Mason 14596567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 14606567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 14616567e837SChris Mason { 14626567e837SChris Mason int ret = 0; 14636567e837SChris Mason int slot; 14646567e837SChris Mason int slot_orig; 14656567e837SChris Mason struct btrfs_leaf *leaf; 14666567e837SChris Mason struct buffer_head *leaf_buf; 14676567e837SChris Mason u32 nritems; 14686567e837SChris Mason unsigned int data_end; 14696567e837SChris Mason unsigned int old_data; 14706567e837SChris Mason unsigned int old_size; 14716567e837SChris Mason int i; 14726567e837SChris Mason 14736567e837SChris Mason slot_orig = path->slots[0]; 14746567e837SChris Mason leaf_buf = path->nodes[0]; 14756567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 14766567e837SChris Mason 14776567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 14786567e837SChris Mason data_end = leaf_data_end(root, leaf); 14796567e837SChris Mason 14806567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 14816567e837SChris Mason BUG(); 14826567e837SChris Mason slot = path->slots[0]; 14836567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 14846567e837SChris Mason 14856567e837SChris Mason BUG_ON(slot < 0); 14866567e837SChris Mason BUG_ON(slot >= nritems); 14876567e837SChris Mason 14886567e837SChris Mason /* 14896567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 14906567e837SChris Mason */ 14916567e837SChris Mason /* first correct the data pointers */ 14926567e837SChris Mason for (i = slot; i < nritems; i++) { 14936567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 14946567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 14956567e837SChris Mason ioff - data_size); 14966567e837SChris Mason } 14976567e837SChris Mason /* shift the data */ 14986567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 14996567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 15006567e837SChris Mason data_end, old_data - data_end); 15016567e837SChris Mason data_end = old_data; 15026567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 15036567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 15046567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 15056567e837SChris Mason 15066567e837SChris Mason ret = 0; 15076567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 15086567e837SChris Mason BUG(); 15096567e837SChris Mason check_leaf(root, path, 0); 15106567e837SChris Mason return ret; 15116567e837SChris Mason } 15126567e837SChris Mason 151374123bd7SChris Mason /* 151474123bd7SChris Mason * Given a key and some data, insert an item into the tree. 151574123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 151674123bd7SChris Mason */ 1517e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1518e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1519e089f05cSChris Mason *cpu_key, u32 data_size) 1520be0e5c09SChris Mason { 1521aa5d6bedSChris Mason int ret = 0; 1522be0e5c09SChris Mason int slot; 1523eb60ceacSChris Mason int slot_orig; 1524234b63a0SChris Mason struct btrfs_leaf *leaf; 1525e20d96d6SChris Mason struct buffer_head *leaf_buf; 15267518a238SChris Mason u32 nritems; 1527be0e5c09SChris Mason unsigned int data_end; 1528e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1529e2fa7227SChris Mason 1530e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1531be0e5c09SChris Mason 153274123bd7SChris Mason /* create a root if there isn't one */ 15335c680ed6SChris Mason if (!root->node) 1534cfaa7295SChris Mason BUG(); 1535e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1536eb60ceacSChris Mason if (ret == 0) { 1537f0930a37SChris Mason return -EEXIST; 1538aa5d6bedSChris Mason } 1539ed2ff2cbSChris Mason if (ret < 0) 1540ed2ff2cbSChris Mason goto out; 1541be0e5c09SChris Mason 154262e2749eSChris Mason slot_orig = path->slots[0]; 154362e2749eSChris Mason leaf_buf = path->nodes[0]; 1544e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 154574123bd7SChris Mason 15467518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1547123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1548eb60ceacSChris Mason 1549123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1550d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1551be0e5c09SChris Mason BUG(); 1552d4dbff95SChris Mason } 155362e2749eSChris Mason slot = path->slots[0]; 1554eb60ceacSChris Mason BUG_ON(slot < 0); 1555be0e5c09SChris Mason if (slot != nritems) { 1556be0e5c09SChris Mason int i; 15570783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1558be0e5c09SChris Mason 1559be0e5c09SChris Mason /* 1560be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1561be0e5c09SChris Mason */ 1562be0e5c09SChris Mason /* first correct the data pointers */ 15630783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1564123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 15650783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 15660783fcfcSChris Mason ioff - data_size); 15670783fcfcSChris Mason } 1568be0e5c09SChris Mason 1569be0e5c09SChris Mason /* shift the items */ 1570d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1571d6025579SChris Mason leaf->items + slot, 15720783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1573be0e5c09SChris Mason 1574be0e5c09SChris Mason /* shift the data */ 1575d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1576d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1577be0e5c09SChris Mason data_end, old_data - data_end); 1578be0e5c09SChris Mason data_end = old_data; 1579be0e5c09SChris Mason } 158062e2749eSChris Mason /* setup the item for the new data */ 1581d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1582e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 15830783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 15840783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 15857518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1586d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1587aa5d6bedSChris Mason 1588aa5d6bedSChris Mason ret = 0; 15898e19f2cdSChris Mason if (slot == 0) 1590e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1591aa5d6bedSChris Mason 1592123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1593be0e5c09SChris Mason BUG(); 159462e2749eSChris Mason check_leaf(root, path, 0); 1595ed2ff2cbSChris Mason out: 159662e2749eSChris Mason return ret; 159762e2749eSChris Mason } 159862e2749eSChris Mason 159962e2749eSChris Mason /* 160062e2749eSChris Mason * Given a key and some data, insert an item into the tree. 160162e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 160262e2749eSChris Mason */ 1603e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1604e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1605e089f05cSChris Mason data_size) 160662e2749eSChris Mason { 160762e2749eSChris Mason int ret = 0; 16082c90e5d6SChris Mason struct btrfs_path *path; 160962e2749eSChris Mason u8 *ptr; 161062e2749eSChris Mason 16112c90e5d6SChris Mason path = btrfs_alloc_path(); 16122c90e5d6SChris Mason BUG_ON(!path); 16132c90e5d6SChris Mason btrfs_init_path(path); 16142c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 161562e2749eSChris Mason if (!ret) { 16162c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 16172c90e5d6SChris Mason path->slots[0], u8); 16182c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1619d6025579SChris Mason ptr, data, data_size); 16202c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 162162e2749eSChris Mason } 16222c90e5d6SChris Mason btrfs_release_path(root, path); 16232c90e5d6SChris Mason btrfs_free_path(path); 1624aa5d6bedSChris Mason return ret; 1625be0e5c09SChris Mason } 1626be0e5c09SChris Mason 162774123bd7SChris Mason /* 16285de08d7dSChris Mason * delete the pointer from a given node. 162974123bd7SChris Mason * 163074123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 163174123bd7SChris Mason * continuing all the way the root if required. The root is converted into 163274123bd7SChris Mason * a leaf if all the nodes are emptied. 163374123bd7SChris Mason */ 1634e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1635e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1636be0e5c09SChris Mason { 1637234b63a0SChris Mason struct btrfs_node *node; 1638e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 16397518a238SChris Mason u32 nritems; 1640aa5d6bedSChris Mason int ret = 0; 1641bb803951SChris Mason int wret; 1642be0e5c09SChris Mason 1643e20d96d6SChris Mason node = btrfs_buffer_node(parent); 16447518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1645be0e5c09SChris Mason if (slot != nritems -1) { 1646d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1647d6025579SChris Mason node->ptrs + slot + 1, 1648d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1649d6025579SChris Mason (nritems - slot - 1)); 1650be0e5c09SChris Mason } 16517518a238SChris Mason nritems--; 16527518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 16537518a238SChris Mason if (nritems == 0 && parent == root->node) { 1654e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1655e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1656eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1657e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1658bb803951SChris Mason } else if (slot == 0) { 1659e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1660123abc88SChris Mason level + 1); 16610f70abe2SChris Mason if (wret) 16620f70abe2SChris Mason ret = wret; 1663be0e5c09SChris Mason } 1664d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1665aa5d6bedSChris Mason return ret; 1666be0e5c09SChris Mason } 1667be0e5c09SChris Mason 166874123bd7SChris Mason /* 166974123bd7SChris Mason * delete the item at the leaf level in path. If that empties 167074123bd7SChris Mason * the leaf, remove it from the tree 167174123bd7SChris Mason */ 1672e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1673e089f05cSChris Mason struct btrfs_path *path) 1674be0e5c09SChris Mason { 1675be0e5c09SChris Mason int slot; 1676234b63a0SChris Mason struct btrfs_leaf *leaf; 1677e20d96d6SChris Mason struct buffer_head *leaf_buf; 1678be0e5c09SChris Mason int doff; 1679be0e5c09SChris Mason int dsize; 1680aa5d6bedSChris Mason int ret = 0; 1681aa5d6bedSChris Mason int wret; 16827518a238SChris Mason u32 nritems; 1683be0e5c09SChris Mason 1684eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1685e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 16864920c9acSChris Mason slot = path->slots[0]; 16870783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 16880783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 16897518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1690be0e5c09SChris Mason 16917518a238SChris Mason if (slot != nritems - 1) { 1692be0e5c09SChris Mason int i; 1693123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 1694d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1695d6025579SChris Mason data_end + dsize, 1696123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 1697be0e5c09SChris Mason doff - data_end); 16980783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 1699123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 17000783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 17010783fcfcSChris Mason } 1702d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 1703d6025579SChris Mason leaf->items + slot + 1, 17040783fcfcSChris Mason sizeof(struct btrfs_item) * 17057518a238SChris Mason (nritems - slot - 1)); 1706be0e5c09SChris Mason } 17077518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 17087518a238SChris Mason nritems--; 170974123bd7SChris Mason /* delete the leaf if we've emptied it */ 17107518a238SChris Mason if (nritems == 0) { 1711eb60ceacSChris Mason if (leaf_buf == root->node) { 17127518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 17139a8dd150SChris Mason } else { 1714e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1715d6025579SChris Mason wait_on_buffer(leaf_buf); 1716e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 1717aa5d6bedSChris Mason if (wret) 1718aa5d6bedSChris Mason ret = wret; 1719e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 17207eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 17210f70abe2SChris Mason if (wret) 17220f70abe2SChris Mason ret = wret; 17239a8dd150SChris Mason } 1724be0e5c09SChris Mason } else { 17257518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 1726aa5d6bedSChris Mason if (slot == 0) { 1727e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 1728aa5d6bedSChris Mason &leaf->items[0].key, 1); 1729aa5d6bedSChris Mason if (wret) 1730aa5d6bedSChris Mason ret = wret; 1731aa5d6bedSChris Mason } 1732aa5d6bedSChris Mason 173374123bd7SChris Mason /* delete the leaf if it is mostly empty */ 1734123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1735be0e5c09SChris Mason /* push_leaf_left fixes the path. 1736be0e5c09SChris Mason * make sure the path still points to our leaf 1737be0e5c09SChris Mason * for possible call to del_ptr below 1738be0e5c09SChris Mason */ 17394920c9acSChris Mason slot = path->slots[1]; 1740e20d96d6SChris Mason get_bh(leaf_buf); 1741e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 1742aa5d6bedSChris Mason if (wret < 0) 1743aa5d6bedSChris Mason ret = wret; 1744f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 17457518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 1746e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 1747aa5d6bedSChris Mason if (wret < 0) 1748aa5d6bedSChris Mason ret = wret; 1749aa5d6bedSChris Mason } 17507518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 17517eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 1752e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1753d6025579SChris Mason wait_on_buffer(leaf_buf); 1754e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 1755aa5d6bedSChris Mason if (wret) 1756aa5d6bedSChris Mason ret = wret; 1757234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1758e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1759e089f05cSChris Mason 1, 1); 17600f70abe2SChris Mason if (wret) 17610f70abe2SChris Mason ret = wret; 17625de08d7dSChris Mason } else { 1763d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1764234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1765be0e5c09SChris Mason } 1766d5719762SChris Mason } else { 1767d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1768be0e5c09SChris Mason } 17699a8dd150SChris Mason } 1770aa5d6bedSChris Mason return ret; 17719a8dd150SChris Mason } 17729a8dd150SChris Mason 177397571fd0SChris Mason /* 177497571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 17750f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 17760f70abe2SChris Mason * returns < 0 on io errors. 177797571fd0SChris Mason */ 1778234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 1779d97e63b6SChris Mason { 1780d97e63b6SChris Mason int slot; 1781d97e63b6SChris Mason int level = 1; 1782d97e63b6SChris Mason u64 blocknr; 1783e20d96d6SChris Mason struct buffer_head *c; 1784e20d96d6SChris Mason struct btrfs_node *c_node; 1785e20d96d6SChris Mason struct buffer_head *next = NULL; 1786d97e63b6SChris Mason 1787234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 1788d97e63b6SChris Mason if (!path->nodes[level]) 17890f70abe2SChris Mason return 1; 1790d97e63b6SChris Mason slot = path->slots[level] + 1; 1791d97e63b6SChris Mason c = path->nodes[level]; 1792e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 1793e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 1794d97e63b6SChris Mason level++; 1795d97e63b6SChris Mason continue; 1796d97e63b6SChris Mason } 1797e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 1798cfaa7295SChris Mason if (next) 1799234b63a0SChris Mason btrfs_block_release(root, next); 1800d97e63b6SChris Mason next = read_tree_block(root, blocknr); 1801d97e63b6SChris Mason break; 1802d97e63b6SChris Mason } 1803d97e63b6SChris Mason path->slots[level] = slot; 1804d97e63b6SChris Mason while(1) { 1805d97e63b6SChris Mason level--; 1806d97e63b6SChris Mason c = path->nodes[level]; 1807234b63a0SChris Mason btrfs_block_release(root, c); 1808d97e63b6SChris Mason path->nodes[level] = next; 1809d97e63b6SChris Mason path->slots[level] = 0; 1810d97e63b6SChris Mason if (!level) 1811d97e63b6SChris Mason break; 18121d4f8a0cSChris Mason next = read_tree_block(root, 1813e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 1814d97e63b6SChris Mason } 1815d97e63b6SChris Mason return 0; 1816d97e63b6SChris Mason } 1817