16cbd5570SChris Mason /* 26cbd5570SChris Mason * Copyright (C) 2007 Oracle. All rights reserved. 36cbd5570SChris Mason * 46cbd5570SChris Mason * This program is free software; you can redistribute it and/or 56cbd5570SChris Mason * modify it under the terms of the GNU General Public 66cbd5570SChris Mason * License v2 as published by the Free Software Foundation. 76cbd5570SChris Mason * 86cbd5570SChris Mason * This program is distributed in the hope that it will be useful, 96cbd5570SChris Mason * but WITHOUT ANY WARRANTY; without even the implied warranty of 106cbd5570SChris Mason * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 116cbd5570SChris Mason * General Public License for more details. 126cbd5570SChris Mason * 136cbd5570SChris Mason * You should have received a copy of the GNU General Public 146cbd5570SChris Mason * License along with this program; if not, write to the 156cbd5570SChris Mason * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 166cbd5570SChris Mason * Boston, MA 021110-1307, USA. 176cbd5570SChris Mason */ 186cbd5570SChris Mason 192e635a27SChris Mason #include <linux/module.h> 20eb60ceacSChris Mason #include "ctree.h" 21eb60ceacSChris Mason #include "disk-io.h" 227f5c1516SChris Mason #include "transaction.h" 239a8dd150SChris Mason 24e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 25e089f05cSChris Mason *root, struct btrfs_path *path, int level); 26e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 27d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 28d4dbff95SChris Mason struct btrfs_path *path, int data_size); 29e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 30e20d96d6SChris Mason *root, struct buffer_head *dst, struct buffer_head 31e089f05cSChris Mason *src); 32e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 33e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 34e20d96d6SChris Mason struct buffer_head *src_buf); 35e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 36e089f05cSChris Mason struct btrfs_path *path, int level, int slot); 37d97e63b6SChris Mason 38df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p) 39df24a2b9SChris Mason { 40df24a2b9SChris Mason memset(p, 0, sizeof(*p)); 41df24a2b9SChris Mason } 42df24a2b9SChris Mason 432c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void) 442c90e5d6SChris Mason { 45df24a2b9SChris Mason struct btrfs_path *path; 46df24a2b9SChris Mason path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); 47df24a2b9SChris Mason if (path) 48df24a2b9SChris Mason btrfs_init_path(path); 49df24a2b9SChris Mason return path; 502c90e5d6SChris Mason } 512c90e5d6SChris Mason 522c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p) 532c90e5d6SChris Mason { 54df24a2b9SChris Mason btrfs_release_path(NULL, p); 552c90e5d6SChris Mason kmem_cache_free(btrfs_path_cachep, p); 562c90e5d6SChris Mason } 572c90e5d6SChris Mason 58234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) 59eb60ceacSChris Mason { 60eb60ceacSChris Mason int i; 61234b63a0SChris Mason for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 62eb60ceacSChris Mason if (!p->nodes[i]) 63eb60ceacSChris Mason break; 64234b63a0SChris Mason btrfs_block_release(root, p->nodes[i]); 65eb60ceacSChris Mason } 66aa5d6bedSChris Mason memset(p, 0, sizeof(*p)); 67eb60ceacSChris Mason } 68eb60ceacSChris Mason 69e089f05cSChris Mason static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 70e20d96d6SChris Mason *root, struct buffer_head *buf, struct buffer_head 71e20d96d6SChris Mason *parent, int parent_slot, struct buffer_head 72e089f05cSChris Mason **cow_ret) 7302217ed2SChris Mason { 74e20d96d6SChris Mason struct buffer_head *cow; 75e20d96d6SChris Mason struct btrfs_node *cow_node; 7654aa1f4dSChris Mason int ret; 7702217ed2SChris Mason 78*ccd467d6SChris Mason WARN_ON(!buffer_uptodate(buf)); 79*ccd467d6SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 80*ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 81*ccd467d6SChris Mason root->fs_info->running_transaction->transid); 82*ccd467d6SChris Mason WARN_ON(1); 83*ccd467d6SChris Mason } 84*ccd467d6SChris Mason if (trans->transid != root->fs_info->generation) { 85*ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 86*ccd467d6SChris Mason root->fs_info->generation); 87*ccd467d6SChris Mason WARN_ON(1); 88*ccd467d6SChris Mason } 897f5c1516SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) == 907f5c1516SChris Mason trans->transid) { 9102217ed2SChris Mason *cow_ret = buf; 9202217ed2SChris Mason return 0; 9302217ed2SChris Mason } 9431f3c99bSChris Mason cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr); 9554aa1f4dSChris Mason if (IS_ERR(cow)) 9654aa1f4dSChris Mason return PTR_ERR(cow); 97e20d96d6SChris Mason cow_node = btrfs_buffer_node(cow); 982c90e5d6SChris Mason if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) 992c90e5d6SChris Mason WARN_ON(1); 100e20d96d6SChris Mason memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 1017eccb903SChris Mason btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); 1027f5c1516SChris Mason btrfs_set_header_generation(&cow_node->header, trans->transid); 1034d775673SChris Mason btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); 10454aa1f4dSChris Mason ret = btrfs_inc_ref(trans, root, buf); 10554aa1f4dSChris Mason if (ret) 10654aa1f4dSChris Mason return ret; 10702217ed2SChris Mason if (buf == root->node) { 10802217ed2SChris Mason root->node = cow; 109e20d96d6SChris Mason get_bh(cow); 1102c90e5d6SChris Mason if (buf != root->commit_root) { 1117eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 1122c90e5d6SChris Mason } 113234b63a0SChris Mason btrfs_block_release(root, buf); 11402217ed2SChris Mason } else { 115e20d96d6SChris Mason btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 1167eccb903SChris Mason bh_blocknr(cow)); 117d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1187eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 11902217ed2SChris Mason } 120234b63a0SChris Mason btrfs_block_release(root, buf); 121*ccd467d6SChris Mason btrfs_mark_buffer_dirty(cow); 1222c90e5d6SChris Mason *cow_ret = cow; 12302217ed2SChris Mason return 0; 12402217ed2SChris Mason } 12502217ed2SChris Mason 12674123bd7SChris Mason /* 12774123bd7SChris Mason * The leaf data grows from end-to-front in the node. 12874123bd7SChris Mason * this returns the address of the start of the last item, 12974123bd7SChris Mason * which is the stop of the leaf data stack 13074123bd7SChris Mason */ 131123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 132123abc88SChris Mason struct btrfs_leaf *leaf) 133be0e5c09SChris Mason { 1347518a238SChris Mason u32 nr = btrfs_header_nritems(&leaf->header); 135be0e5c09SChris Mason if (nr == 0) 136123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 1370783fcfcSChris Mason return btrfs_item_offset(leaf->items + nr - 1); 138be0e5c09SChris Mason } 139be0e5c09SChris Mason 14074123bd7SChris Mason /* 14174123bd7SChris Mason * compare two keys in a memcmp fashion 14274123bd7SChris Mason */ 1439aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 144be0e5c09SChris Mason { 145e2fa7227SChris Mason struct btrfs_key k1; 146e2fa7227SChris Mason 147e2fa7227SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 148e2fa7227SChris Mason 149e2fa7227SChris Mason if (k1.objectid > k2->objectid) 150be0e5c09SChris Mason return 1; 151e2fa7227SChris Mason if (k1.objectid < k2->objectid) 152be0e5c09SChris Mason return -1; 153f254e52cSChris Mason if (k1.flags > k2->flags) 154f254e52cSChris Mason return 1; 155f254e52cSChris Mason if (k1.flags < k2->flags) 156f254e52cSChris Mason return -1; 15770b2befdSChris Mason if (k1.offset > k2->offset) 15870b2befdSChris Mason return 1; 15970b2befdSChris Mason if (k1.offset < k2->offset) 16070b2befdSChris Mason return -1; 161be0e5c09SChris Mason return 0; 162be0e5c09SChris Mason } 16374123bd7SChris Mason 164123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 165123abc88SChris Mason int level) 166aa5d6bedSChris Mason { 167234b63a0SChris Mason struct btrfs_node *parent = NULL; 168e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 169aa5d6bedSChris Mason int parent_slot; 1708d7be552SChris Mason int slot; 1718d7be552SChris Mason struct btrfs_key cpukey; 1727518a238SChris Mason u32 nritems = btrfs_header_nritems(&node->header); 173aa5d6bedSChris Mason 174aa5d6bedSChris Mason if (path->nodes[level + 1]) 175e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 176aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 1778d7be552SChris Mason slot = path->slots[level]; 1787518a238SChris Mason BUG_ON(nritems == 0); 1797518a238SChris Mason if (parent) { 180e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 181123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 182123abc88SChris Mason BUG_ON(memcmp(parent_key, &node->ptrs[0].key, 183e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1841d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1857518a238SChris Mason btrfs_header_blocknr(&node->header)); 186aa5d6bedSChris Mason } 187123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 1888d7be552SChris Mason if (slot != 0) { 1898d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key); 1908d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0); 1918d7be552SChris Mason } 1928d7be552SChris Mason if (slot < nritems - 1) { 1938d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key); 1948d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0); 195aa5d6bedSChris Mason } 196aa5d6bedSChris Mason return 0; 197aa5d6bedSChris Mason } 198aa5d6bedSChris Mason 199123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 200123abc88SChris Mason int level) 201aa5d6bedSChris Mason { 202e20d96d6SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); 203234b63a0SChris Mason struct btrfs_node *parent = NULL; 204aa5d6bedSChris Mason int parent_slot; 2058d7be552SChris Mason int slot = path->slots[0]; 2068d7be552SChris Mason struct btrfs_key cpukey; 2078d7be552SChris Mason 2087518a238SChris Mason u32 nritems = btrfs_header_nritems(&leaf->header); 209aa5d6bedSChris Mason 210aa5d6bedSChris Mason if (path->nodes[level + 1]) 211e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 212aa5d6bedSChris Mason parent_slot = path->slots[level + 1]; 213123abc88SChris Mason BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 2147518a238SChris Mason 2157518a238SChris Mason if (nritems == 0) 2167518a238SChris Mason return 0; 2177518a238SChris Mason 2187518a238SChris Mason if (parent) { 219e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 220123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 221aa5d6bedSChris Mason BUG_ON(memcmp(parent_key, &leaf->items[0].key, 222e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 2231d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 2247518a238SChris Mason btrfs_header_blocknr(&leaf->header)); 225aa5d6bedSChris Mason } 2268d7be552SChris Mason if (slot != 0) { 2278d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key); 2288d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0); 2298d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot - 1) != 2308d7be552SChris Mason btrfs_item_end(leaf->items + slot)); 231aa5d6bedSChris Mason } 2328d7be552SChris Mason if (slot < nritems - 1) { 2338d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key); 2348d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0); 2358d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot) != 2368d7be552SChris Mason btrfs_item_end(leaf->items + slot + 1)); 237aa5d6bedSChris Mason } 2388d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items) + 2398d7be552SChris Mason btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root)); 240aa5d6bedSChris Mason return 0; 241aa5d6bedSChris Mason } 242aa5d6bedSChris Mason 243123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 244123abc88SChris Mason int level) 245aa5d6bedSChris Mason { 2463eb0314dSChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 2473eb0314dSChris Mason if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, 2483eb0314dSChris Mason sizeof(node->header.fsid))) 2493eb0314dSChris Mason BUG(); 250aa5d6bedSChris Mason if (level == 0) 251123abc88SChris Mason return check_leaf(root, path, level); 252123abc88SChris Mason return check_node(root, path, level); 253aa5d6bedSChris Mason } 254aa5d6bedSChris Mason 25574123bd7SChris Mason /* 25674123bd7SChris Mason * search for key in the array p. items p are item_size apart 25774123bd7SChris Mason * and there are 'max' items in p 25874123bd7SChris Mason * the slot in the array is returned via slot, and it points to 25974123bd7SChris Mason * the place where you would insert key if it is not found in 26074123bd7SChris Mason * the array. 26174123bd7SChris Mason * 26274123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 26374123bd7SChris Mason */ 2649aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, 265be0e5c09SChris Mason int max, int *slot) 266be0e5c09SChris Mason { 267be0e5c09SChris Mason int low = 0; 268be0e5c09SChris Mason int high = max; 269be0e5c09SChris Mason int mid; 270be0e5c09SChris Mason int ret; 271e2fa7227SChris Mason struct btrfs_disk_key *tmp; 272be0e5c09SChris Mason 273be0e5c09SChris Mason while(low < high) { 274be0e5c09SChris Mason mid = (low + high) / 2; 275e2fa7227SChris Mason tmp = (struct btrfs_disk_key *)(p + mid * item_size); 276be0e5c09SChris Mason ret = comp_keys(tmp, key); 277be0e5c09SChris Mason 278be0e5c09SChris Mason if (ret < 0) 279be0e5c09SChris Mason low = mid + 1; 280be0e5c09SChris Mason else if (ret > 0) 281be0e5c09SChris Mason high = mid; 282be0e5c09SChris Mason else { 283be0e5c09SChris Mason *slot = mid; 284be0e5c09SChris Mason return 0; 285be0e5c09SChris Mason } 286be0e5c09SChris Mason } 287be0e5c09SChris Mason *slot = low; 288be0e5c09SChris Mason return 1; 289be0e5c09SChris Mason } 290be0e5c09SChris Mason 29197571fd0SChris Mason /* 29297571fd0SChris Mason * simple bin_search frontend that does the right thing for 29397571fd0SChris Mason * leaves vs nodes 29497571fd0SChris Mason */ 2959aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) 296be0e5c09SChris Mason { 2977518a238SChris Mason if (btrfs_is_leaf(c)) { 298234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 2990783fcfcSChris Mason return generic_bin_search((void *)l->items, 3000783fcfcSChris Mason sizeof(struct btrfs_item), 3017518a238SChris Mason key, btrfs_header_nritems(&c->header), 3027518a238SChris Mason slot); 303be0e5c09SChris Mason } else { 304123abc88SChris Mason return generic_bin_search((void *)c->ptrs, 305123abc88SChris Mason sizeof(struct btrfs_key_ptr), 3067518a238SChris Mason key, btrfs_header_nritems(&c->header), 3077518a238SChris Mason slot); 308be0e5c09SChris Mason } 309be0e5c09SChris Mason return -1; 310be0e5c09SChris Mason } 311be0e5c09SChris Mason 312e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root, 313e20d96d6SChris Mason struct buffer_head *parent_buf, 314bb803951SChris Mason int slot) 315bb803951SChris Mason { 316e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(parent_buf); 317bb803951SChris Mason if (slot < 0) 318bb803951SChris Mason return NULL; 3197518a238SChris Mason if (slot >= btrfs_header_nritems(&node->header)) 320bb803951SChris Mason return NULL; 3211d4f8a0cSChris Mason return read_tree_block(root, btrfs_node_blockptr(node, slot)); 322bb803951SChris Mason } 323bb803951SChris Mason 324e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 325e089f05cSChris Mason *root, struct btrfs_path *path, int level) 326bb803951SChris Mason { 327e20d96d6SChris Mason struct buffer_head *right_buf; 328e20d96d6SChris Mason struct buffer_head *mid_buf; 329e20d96d6SChris Mason struct buffer_head *left_buf; 330e20d96d6SChris Mason struct buffer_head *parent_buf = NULL; 331234b63a0SChris Mason struct btrfs_node *right = NULL; 332234b63a0SChris Mason struct btrfs_node *mid; 333234b63a0SChris Mason struct btrfs_node *left = NULL; 334234b63a0SChris Mason struct btrfs_node *parent = NULL; 335bb803951SChris Mason int ret = 0; 336bb803951SChris Mason int wret; 337bb803951SChris Mason int pslot; 338bb803951SChris Mason int orig_slot = path->slots[level]; 33954aa1f4dSChris Mason int err_on_enospc = 0; 34079f95c82SChris Mason u64 orig_ptr; 341bb803951SChris Mason 342bb803951SChris Mason if (level == 0) 343bb803951SChris Mason return 0; 344bb803951SChris Mason 345bb803951SChris Mason mid_buf = path->nodes[level]; 346e20d96d6SChris Mason mid = btrfs_buffer_node(mid_buf); 3471d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 34879f95c82SChris Mason 349234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 350bb803951SChris Mason parent_buf = path->nodes[level + 1]; 351bb803951SChris Mason pslot = path->slots[level + 1]; 352bb803951SChris Mason 35340689478SChris Mason /* 35440689478SChris Mason * deal with the case where there is only one pointer in the root 35540689478SChris Mason * by promoting the node below to a root 35640689478SChris Mason */ 357bb803951SChris Mason if (!parent_buf) { 358e20d96d6SChris Mason struct buffer_head *child; 3597eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 360bb803951SChris Mason 3617518a238SChris Mason if (btrfs_header_nritems(&mid->header) != 1) 362bb803951SChris Mason return 0; 363bb803951SChris Mason 364bb803951SChris Mason /* promote the child to a root */ 365bb803951SChris Mason child = read_node_slot(root, mid_buf, 0); 366bb803951SChris Mason BUG_ON(!child); 367bb803951SChris Mason root->node = child; 368bb803951SChris Mason path->nodes[level] = NULL; 369d6025579SChris Mason clean_tree_block(trans, root, mid_buf); 370d6025579SChris Mason wait_on_buffer(mid_buf); 371bb803951SChris Mason /* once for the path */ 372234b63a0SChris Mason btrfs_block_release(root, mid_buf); 373bb803951SChris Mason /* once for the root ptr */ 374234b63a0SChris Mason btrfs_block_release(root, mid_buf); 375e089f05cSChris Mason return btrfs_free_extent(trans, root, blocknr, 1, 1); 376bb803951SChris Mason } 377e20d96d6SChris Mason parent = btrfs_buffer_node(parent_buf); 378bb803951SChris Mason 379123abc88SChris Mason if (btrfs_header_nritems(&mid->header) > 380123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 381bb803951SChris Mason return 0; 382bb803951SChris Mason 38354aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 38454aa1f4dSChris Mason err_on_enospc = 1; 38554aa1f4dSChris Mason 386bb803951SChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 387bb803951SChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 38879f95c82SChris Mason 38979f95c82SChris Mason /* first, try to make some room in the middle buffer */ 390bb803951SChris Mason if (left_buf) { 39154aa1f4dSChris Mason wret = btrfs_cow_block(trans, root, left_buf, 39254aa1f4dSChris Mason parent_buf, pslot - 1, &left_buf); 39354aa1f4dSChris Mason if (wret) { 39454aa1f4dSChris Mason ret = wret; 39554aa1f4dSChris Mason goto enospc; 39654aa1f4dSChris Mason } 397e20d96d6SChris Mason left = btrfs_buffer_node(left_buf); 3987518a238SChris Mason orig_slot += btrfs_header_nritems(&left->header); 399e089f05cSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 40079f95c82SChris Mason if (wret < 0) 40179f95c82SChris Mason ret = wret; 40254aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 40354aa1f4dSChris Mason err_on_enospc = 1; 404bb803951SChris Mason } 40579f95c82SChris Mason 40679f95c82SChris Mason /* 40779f95c82SChris Mason * then try to empty the right most buffer into the middle 40879f95c82SChris Mason */ 409bb803951SChris Mason if (right_buf) { 41054aa1f4dSChris Mason wret = btrfs_cow_block(trans, root, right_buf, 41154aa1f4dSChris Mason parent_buf, pslot + 1, &right_buf); 41254aa1f4dSChris Mason if (wret) { 41354aa1f4dSChris Mason ret = wret; 41454aa1f4dSChris Mason goto enospc; 41554aa1f4dSChris Mason } 41654aa1f4dSChris Mason 417e20d96d6SChris Mason right = btrfs_buffer_node(right_buf); 418e089f05cSChris Mason wret = push_node_left(trans, root, mid_buf, right_buf); 41954aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 42079f95c82SChris Mason ret = wret; 4217518a238SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 4227eccb903SChris Mason u64 blocknr = bh_blocknr(right_buf); 423e089f05cSChris Mason clean_tree_block(trans, root, right_buf); 424d6025579SChris Mason wait_on_buffer(right_buf); 425d6025579SChris Mason btrfs_block_release(root, right_buf); 426bb803951SChris Mason right_buf = NULL; 427bb803951SChris Mason right = NULL; 428e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 429e089f05cSChris Mason 1); 430bb803951SChris Mason if (wret) 431bb803951SChris Mason ret = wret; 432e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 433bb803951SChris Mason if (wret) 434bb803951SChris Mason ret = wret; 435bb803951SChris Mason } else { 436d6025579SChris Mason btrfs_memcpy(root, parent, 437d6025579SChris Mason &parent->ptrs[pslot + 1].key, 438123abc88SChris Mason &right->ptrs[0].key, 439e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 440d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 441bb803951SChris Mason } 442bb803951SChris Mason } 4437518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 1) { 44479f95c82SChris Mason /* 44579f95c82SChris Mason * we're not allowed to leave a node with one item in the 44679f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 44779f95c82SChris Mason * could try to delete the only pointer in this node. 44879f95c82SChris Mason * So, pull some keys from the left. 44979f95c82SChris Mason * There has to be a left pointer at this point because 45079f95c82SChris Mason * otherwise we would have pulled some pointers from the 45179f95c82SChris Mason * right 45279f95c82SChris Mason */ 45379f95c82SChris Mason BUG_ON(!left_buf); 454e089f05cSChris Mason wret = balance_node_right(trans, root, mid_buf, left_buf); 45554aa1f4dSChris Mason if (wret < 0) { 45679f95c82SChris Mason ret = wret; 45754aa1f4dSChris Mason goto enospc; 45854aa1f4dSChris Mason } 45979f95c82SChris Mason BUG_ON(wret == 1); 46079f95c82SChris Mason } 4617518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 0) { 46279f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 4637eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 464e089f05cSChris Mason clean_tree_block(trans, root, mid_buf); 465d6025579SChris Mason wait_on_buffer(mid_buf); 466d6025579SChris Mason btrfs_block_release(root, mid_buf); 467bb803951SChris Mason mid_buf = NULL; 468bb803951SChris Mason mid = NULL; 469e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 470bb803951SChris Mason if (wret) 471bb803951SChris Mason ret = wret; 472e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 473bb803951SChris Mason if (wret) 474bb803951SChris Mason ret = wret; 47579f95c82SChris Mason } else { 47679f95c82SChris Mason /* update the parent key to reflect our changes */ 477d6025579SChris Mason btrfs_memcpy(root, parent, 478d6025579SChris Mason &parent->ptrs[pslot].key, &mid->ptrs[0].key, 479e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 480d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 48179f95c82SChris Mason } 482bb803951SChris Mason 48379f95c82SChris Mason /* update the path */ 484bb803951SChris Mason if (left_buf) { 4857518a238SChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 486e20d96d6SChris Mason get_bh(left_buf); 487bb803951SChris Mason path->nodes[level] = left_buf; 488bb803951SChris Mason path->slots[level + 1] -= 1; 489bb803951SChris Mason path->slots[level] = orig_slot; 490bb803951SChris Mason if (mid_buf) 491234b63a0SChris Mason btrfs_block_release(root, mid_buf); 492bb803951SChris Mason } else { 4937518a238SChris Mason orig_slot -= btrfs_header_nritems(&left->header); 494bb803951SChris Mason path->slots[level] = orig_slot; 495bb803951SChris Mason } 496bb803951SChris Mason } 49779f95c82SChris Mason /* double check we haven't messed things up */ 498123abc88SChris Mason check_block(root, path, level); 499e20d96d6SChris Mason if (orig_ptr != 500e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 5011d4f8a0cSChris Mason path->slots[level])) 50279f95c82SChris Mason BUG(); 50354aa1f4dSChris Mason enospc: 504bb803951SChris Mason if (right_buf) 505234b63a0SChris Mason btrfs_block_release(root, right_buf); 506bb803951SChris Mason if (left_buf) 507234b63a0SChris Mason btrfs_block_release(root, left_buf); 508bb803951SChris Mason return ret; 509bb803951SChris Mason } 510bb803951SChris Mason 511e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 512e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 513e66f709bSChris Mason struct btrfs_root *root, 514e66f709bSChris Mason struct btrfs_path *path, int level) 515e66f709bSChris Mason { 516e66f709bSChris Mason struct buffer_head *right_buf; 517e66f709bSChris Mason struct buffer_head *mid_buf; 518e66f709bSChris Mason struct buffer_head *left_buf; 519e66f709bSChris Mason struct buffer_head *parent_buf = NULL; 520e66f709bSChris Mason struct btrfs_node *right = NULL; 521e66f709bSChris Mason struct btrfs_node *mid; 522e66f709bSChris Mason struct btrfs_node *left = NULL; 523e66f709bSChris Mason struct btrfs_node *parent = NULL; 524e66f709bSChris Mason int ret = 0; 525e66f709bSChris Mason int wret; 526e66f709bSChris Mason int pslot; 527e66f709bSChris Mason int orig_slot = path->slots[level]; 528e66f709bSChris Mason u64 orig_ptr; 529e66f709bSChris Mason 530e66f709bSChris Mason if (level == 0) 531e66f709bSChris Mason return 1; 532e66f709bSChris Mason 533e66f709bSChris Mason mid_buf = path->nodes[level]; 534e66f709bSChris Mason mid = btrfs_buffer_node(mid_buf); 535e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 536e66f709bSChris Mason 537e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 538e66f709bSChris Mason parent_buf = path->nodes[level + 1]; 539e66f709bSChris Mason pslot = path->slots[level + 1]; 540e66f709bSChris Mason 541e66f709bSChris Mason if (!parent_buf) 542e66f709bSChris Mason return 1; 543e66f709bSChris Mason parent = btrfs_buffer_node(parent_buf); 544e66f709bSChris Mason 545e66f709bSChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 546e66f709bSChris Mason 547e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 548e66f709bSChris Mason if (left_buf) { 549e66f709bSChris Mason u32 left_nr; 550e66f709bSChris Mason left = btrfs_buffer_node(left_buf); 551e66f709bSChris Mason left_nr = btrfs_header_nritems(&left->header); 55233ade1f8SChris Mason if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 55333ade1f8SChris Mason wret = 1; 55433ade1f8SChris Mason } else { 55554aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, left_buf, parent_buf, 55633ade1f8SChris Mason pslot - 1, &left_buf); 55754aa1f4dSChris Mason if (ret) 55854aa1f4dSChris Mason wret = 1; 55954aa1f4dSChris Mason else { 56033ade1f8SChris Mason left = btrfs_buffer_node(left_buf); 56154aa1f4dSChris Mason wret = push_node_left(trans, root, 56254aa1f4dSChris Mason left_buf, mid_buf); 56354aa1f4dSChris Mason } 56433ade1f8SChris Mason } 565e66f709bSChris Mason if (wret < 0) 566e66f709bSChris Mason ret = wret; 567e66f709bSChris Mason if (wret == 0) { 568e66f709bSChris Mason orig_slot += left_nr; 569e66f709bSChris Mason btrfs_memcpy(root, parent, 570e66f709bSChris Mason &parent->ptrs[pslot].key, 571e66f709bSChris Mason &mid->ptrs[0].key, 572e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 573e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 574e66f709bSChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 575e66f709bSChris Mason path->nodes[level] = left_buf; 576e66f709bSChris Mason path->slots[level + 1] -= 1; 577e66f709bSChris Mason path->slots[level] = orig_slot; 578e66f709bSChris Mason btrfs_block_release(root, mid_buf); 579e66f709bSChris Mason } else { 580e66f709bSChris Mason orig_slot -= 581e66f709bSChris Mason btrfs_header_nritems(&left->header); 582e66f709bSChris Mason path->slots[level] = orig_slot; 583e66f709bSChris Mason btrfs_block_release(root, left_buf); 584e66f709bSChris Mason } 585e66f709bSChris Mason check_node(root, path, level); 586e66f709bSChris Mason return 0; 587e66f709bSChris Mason } 588e66f709bSChris Mason btrfs_block_release(root, left_buf); 589e66f709bSChris Mason } 590e66f709bSChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 591e66f709bSChris Mason 592e66f709bSChris Mason /* 593e66f709bSChris Mason * then try to empty the right most buffer into the middle 594e66f709bSChris Mason */ 595e66f709bSChris Mason if (right_buf) { 59633ade1f8SChris Mason u32 right_nr; 597e66f709bSChris Mason right = btrfs_buffer_node(right_buf); 59833ade1f8SChris Mason right_nr = btrfs_header_nritems(&right->header); 59933ade1f8SChris Mason if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 60033ade1f8SChris Mason wret = 1; 60133ade1f8SChris Mason } else { 60254aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, 60354aa1f4dSChris Mason parent_buf, pslot + 1, 60454aa1f4dSChris Mason &right_buf); 60554aa1f4dSChris Mason if (ret) 60654aa1f4dSChris Mason wret = 1; 60754aa1f4dSChris Mason else { 60833ade1f8SChris Mason right = btrfs_buffer_node(right_buf); 60933ade1f8SChris Mason wret = balance_node_right(trans, root, 61033ade1f8SChris Mason right_buf, mid_buf); 61133ade1f8SChris Mason } 61254aa1f4dSChris Mason } 613e66f709bSChris Mason if (wret < 0) 614e66f709bSChris Mason ret = wret; 615e66f709bSChris Mason if (wret == 0) { 616e66f709bSChris Mason btrfs_memcpy(root, parent, 617e66f709bSChris Mason &parent->ptrs[pslot + 1].key, 618e66f709bSChris Mason &right->ptrs[0].key, 619e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 620e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 621e66f709bSChris Mason if (btrfs_header_nritems(&mid->header) <= orig_slot) { 622e66f709bSChris Mason path->nodes[level] = right_buf; 623e66f709bSChris Mason path->slots[level + 1] += 1; 624e66f709bSChris Mason path->slots[level] = orig_slot - 625e66f709bSChris Mason btrfs_header_nritems(&mid->header); 626e66f709bSChris Mason btrfs_block_release(root, mid_buf); 627e66f709bSChris Mason } else { 628e66f709bSChris Mason btrfs_block_release(root, right_buf); 629e66f709bSChris Mason } 630e66f709bSChris Mason check_node(root, path, level); 631e66f709bSChris Mason return 0; 632e66f709bSChris Mason } 633e66f709bSChris Mason btrfs_block_release(root, right_buf); 634e66f709bSChris Mason } 635e66f709bSChris Mason check_node(root, path, level); 636e66f709bSChris Mason return 1; 637e66f709bSChris Mason } 638e66f709bSChris Mason 63974123bd7SChris Mason /* 64074123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 64174123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 64274123bd7SChris Mason * level of the path (level 0) 64374123bd7SChris Mason * 64474123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 645aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 646aa5d6bedSChris Mason * search a negative error number is returned. 64797571fd0SChris Mason * 64897571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 64997571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 65097571fd0SChris Mason * possible) 65174123bd7SChris Mason */ 652e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 653e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 654e089f05cSChris Mason ins_len, int cow) 655be0e5c09SChris Mason { 656e20d96d6SChris Mason struct buffer_head *b; 657e20d96d6SChris Mason struct buffer_head *cow_buf; 658234b63a0SChris Mason struct btrfs_node *c; 659be0e5c09SChris Mason int slot; 660be0e5c09SChris Mason int ret; 661be0e5c09SChris Mason int level; 6625c680ed6SChris Mason 66322b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 66422b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 665bb803951SChris Mason again: 666bb803951SChris Mason b = root->node; 667e20d96d6SChris Mason get_bh(b); 668eb60ceacSChris Mason while (b) { 669e20d96d6SChris Mason c = btrfs_buffer_node(b); 670e20d96d6SChris Mason level = btrfs_header_level(&c->header); 67102217ed2SChris Mason if (cow) { 67202217ed2SChris Mason int wret; 673e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 674e20d96d6SChris Mason p->nodes[level + 1], 675e20d96d6SChris Mason p->slots[level + 1], 676e089f05cSChris Mason &cow_buf); 67754aa1f4dSChris Mason if (wret) { 67854aa1f4dSChris Mason btrfs_block_release(root, cow_buf); 67954aa1f4dSChris Mason return wret; 68054aa1f4dSChris Mason } 68102217ed2SChris Mason b = cow_buf; 6822c90e5d6SChris Mason c = btrfs_buffer_node(b); 68302217ed2SChris Mason } 68402217ed2SChris Mason BUG_ON(!cow && ins_len); 6852c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 6862c90e5d6SChris Mason WARN_ON(1); 6872c90e5d6SChris Mason level = btrfs_header_level(&c->header); 688eb60ceacSChris Mason p->nodes[level] = b; 689123abc88SChris Mason ret = check_block(root, p, level); 690aa5d6bedSChris Mason if (ret) 691aa5d6bedSChris Mason return -1; 692be0e5c09SChris Mason ret = bin_search(c, key, &slot); 6937518a238SChris Mason if (!btrfs_is_leaf(c)) { 694be0e5c09SChris Mason if (ret && slot > 0) 695be0e5c09SChris Mason slot -= 1; 696be0e5c09SChris Mason p->slots[level] = slot; 697d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 698d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 699e089f05cSChris Mason int sret = split_node(trans, root, p, level); 7005c680ed6SChris Mason BUG_ON(sret > 0); 7015c680ed6SChris Mason if (sret) 7025c680ed6SChris Mason return sret; 7035c680ed6SChris Mason b = p->nodes[level]; 704e20d96d6SChris Mason c = btrfs_buffer_node(b); 7055c680ed6SChris Mason slot = p->slots[level]; 706bb803951SChris Mason } else if (ins_len < 0) { 707e089f05cSChris Mason int sret = balance_level(trans, root, p, 708e089f05cSChris Mason level); 709bb803951SChris Mason if (sret) 710bb803951SChris Mason return sret; 711bb803951SChris Mason b = p->nodes[level]; 712bb803951SChris Mason if (!b) 713bb803951SChris Mason goto again; 714e20d96d6SChris Mason c = btrfs_buffer_node(b); 715bb803951SChris Mason slot = p->slots[level]; 7167518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 7175c680ed6SChris Mason } 7181d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 719be0e5c09SChris Mason } else { 720234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 721be0e5c09SChris Mason p->slots[level] = slot; 722123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 7230783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 724d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 725d4dbff95SChris Mason p, ins_len); 7265c680ed6SChris Mason BUG_ON(sret > 0); 7275c680ed6SChris Mason if (sret) 7285c680ed6SChris Mason return sret; 7295c680ed6SChris Mason } 730be0e5c09SChris Mason return ret; 731be0e5c09SChris Mason } 732be0e5c09SChris Mason } 733aa5d6bedSChris Mason return 1; 734be0e5c09SChris Mason } 735be0e5c09SChris Mason 73674123bd7SChris Mason /* 73774123bd7SChris Mason * adjust the pointers going up the tree, starting at level 73874123bd7SChris Mason * making sure the right key of each node is points to 'key'. 73974123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 74074123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 74174123bd7SChris Mason * higher levels 742aa5d6bedSChris Mason * 743aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 744aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 74574123bd7SChris Mason */ 746e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 747e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 748e089f05cSChris Mason *key, int level) 749be0e5c09SChris Mason { 750be0e5c09SChris Mason int i; 751aa5d6bedSChris Mason int ret = 0; 752234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 753234b63a0SChris Mason struct btrfs_node *t; 754be0e5c09SChris Mason int tslot = path->slots[i]; 755eb60ceacSChris Mason if (!path->nodes[i]) 756be0e5c09SChris Mason break; 757e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 758d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 759d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 760be0e5c09SChris Mason if (tslot != 0) 761be0e5c09SChris Mason break; 762be0e5c09SChris Mason } 763aa5d6bedSChris Mason return ret; 764be0e5c09SChris Mason } 765be0e5c09SChris Mason 76674123bd7SChris Mason /* 76774123bd7SChris Mason * try to push data from one node into the next node left in the 76879f95c82SChris Mason * tree. 769aa5d6bedSChris Mason * 770aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 771aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 77274123bd7SChris Mason */ 773e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 774e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 775e20d96d6SChris Mason buffer_head *src_buf) 776be0e5c09SChris Mason { 777e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 778e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 779be0e5c09SChris Mason int push_items = 0; 780bb803951SChris Mason int src_nritems; 781bb803951SChris Mason int dst_nritems; 782aa5d6bedSChris Mason int ret = 0; 783be0e5c09SChris Mason 7847518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7857518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 786123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 78754aa1f4dSChris Mason 788eb60ceacSChris Mason if (push_items <= 0) { 789be0e5c09SChris Mason return 1; 790eb60ceacSChris Mason } 791be0e5c09SChris Mason 792be0e5c09SChris Mason if (src_nritems < push_items) 793be0e5c09SChris Mason push_items = src_nritems; 79479f95c82SChris Mason 795d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 796123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 797bb803951SChris Mason if (push_items < src_nritems) { 798d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 799e2fa7227SChris Mason (src_nritems - push_items) * 800123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 801bb803951SChris Mason } 8027518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 8037518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 804d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 805d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 806bb803951SChris Mason return ret; 807be0e5c09SChris Mason } 808be0e5c09SChris Mason 80997571fd0SChris Mason /* 81079f95c82SChris Mason * try to push data from one node into the next node right in the 81179f95c82SChris Mason * tree. 81279f95c82SChris Mason * 81379f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 81479f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 81579f95c82SChris Mason * 81679f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 81779f95c82SChris Mason */ 818e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 819e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 820e20d96d6SChris Mason struct buffer_head *src_buf) 82179f95c82SChris Mason { 822e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 823e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 82479f95c82SChris Mason int push_items = 0; 82579f95c82SChris Mason int max_push; 82679f95c82SChris Mason int src_nritems; 82779f95c82SChris Mason int dst_nritems; 82879f95c82SChris Mason int ret = 0; 82979f95c82SChris Mason 8307518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 8317518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 832123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 83379f95c82SChris Mason if (push_items <= 0) { 83479f95c82SChris Mason return 1; 83579f95c82SChris Mason } 83679f95c82SChris Mason 83779f95c82SChris Mason max_push = src_nritems / 2 + 1; 83879f95c82SChris Mason /* don't try to empty the node */ 83979f95c82SChris Mason if (max_push > src_nritems) 84079f95c82SChris Mason return 1; 84179f95c82SChris Mason if (max_push < push_items) 84279f95c82SChris Mason push_items = max_push; 84379f95c82SChris Mason 844d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 845123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 846d6025579SChris Mason 847d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 848d6025579SChris Mason src->ptrs + src_nritems - push_items, 849123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 85079f95c82SChris Mason 8517518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 8527518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 85379f95c82SChris Mason 854d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 855d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 85679f95c82SChris Mason return ret; 85779f95c82SChris Mason } 85879f95c82SChris Mason 85979f95c82SChris Mason /* 86097571fd0SChris Mason * helper function to insert a new root level in the tree. 86197571fd0SChris Mason * A new node is allocated, and a single item is inserted to 86297571fd0SChris Mason * point to the existing root 863aa5d6bedSChris Mason * 864aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 86597571fd0SChris Mason */ 866e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 867e089f05cSChris Mason *root, struct btrfs_path *path, int level) 86874123bd7SChris Mason { 869e20d96d6SChris Mason struct buffer_head *t; 870234b63a0SChris Mason struct btrfs_node *lower; 871234b63a0SChris Mason struct btrfs_node *c; 872e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 8735c680ed6SChris Mason 8745c680ed6SChris Mason BUG_ON(path->nodes[level]); 8755c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 8765c680ed6SChris Mason 87731f3c99bSChris Mason t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr); 87854aa1f4dSChris Mason if (IS_ERR(t)) 87954aa1f4dSChris Mason return PTR_ERR(t); 880e20d96d6SChris Mason c = btrfs_buffer_node(t); 881123abc88SChris Mason memset(c, 0, root->blocksize); 8827518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 8837518a238SChris Mason btrfs_set_header_level(&c->header, level); 8847eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 8857f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 8864d775673SChris Mason btrfs_set_header_owner(&c->header, root->root_key.objectid); 887e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 8883eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 8893eb0314dSChris Mason sizeof(c->header.fsid)); 8907518a238SChris Mason if (btrfs_is_leaf(lower)) 891234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 89274123bd7SChris Mason else 893123abc88SChris Mason lower_key = &lower->ptrs[0].key; 894d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 895d6025579SChris Mason sizeof(struct btrfs_disk_key)); 8967eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 897d5719762SChris Mason 898d6025579SChris Mason btrfs_mark_buffer_dirty(t); 899d5719762SChris Mason 900cfaa7295SChris Mason /* the super has an extra ref to root->node */ 901234b63a0SChris Mason btrfs_block_release(root, root->node); 90274123bd7SChris Mason root->node = t; 903e20d96d6SChris Mason get_bh(t); 90474123bd7SChris Mason path->nodes[level] = t; 90574123bd7SChris Mason path->slots[level] = 0; 90674123bd7SChris Mason return 0; 90774123bd7SChris Mason } 9085c680ed6SChris Mason 9095c680ed6SChris Mason /* 9105c680ed6SChris Mason * worker function to insert a single pointer in a node. 9115c680ed6SChris Mason * the node should have enough room for the pointer already 91297571fd0SChris Mason * 9135c680ed6SChris Mason * slot and level indicate where you want the key to go, and 9145c680ed6SChris Mason * blocknr is the block the key points to. 915aa5d6bedSChris Mason * 916aa5d6bedSChris Mason * returns zero on success and < 0 on any error 9175c680ed6SChris Mason */ 918e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 919e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 920e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 9215c680ed6SChris Mason { 922234b63a0SChris Mason struct btrfs_node *lower; 9235c680ed6SChris Mason int nritems; 9245c680ed6SChris Mason 9255c680ed6SChris Mason BUG_ON(!path->nodes[level]); 926e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 9277518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 92874123bd7SChris Mason if (slot > nritems) 92974123bd7SChris Mason BUG(); 930123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 93174123bd7SChris Mason BUG(); 93274123bd7SChris Mason if (slot != nritems) { 933d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 934d6025579SChris Mason lower->ptrs + slot, 935123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 93674123bd7SChris Mason } 937d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 938d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 9391d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 9407518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 941d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 942098f59c2SChris Mason check_node(root, path, level); 94374123bd7SChris Mason return 0; 94474123bd7SChris Mason } 94574123bd7SChris Mason 94697571fd0SChris Mason /* 94797571fd0SChris Mason * split the node at the specified level in path in two. 94897571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 94997571fd0SChris Mason * 95097571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 95197571fd0SChris Mason * left and right, if either one works, it returns right away. 952aa5d6bedSChris Mason * 953aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 95497571fd0SChris Mason */ 955e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 956e089f05cSChris Mason *root, struct btrfs_path *path, int level) 957be0e5c09SChris Mason { 958e20d96d6SChris Mason struct buffer_head *t; 959234b63a0SChris Mason struct btrfs_node *c; 960e20d96d6SChris Mason struct buffer_head *split_buffer; 961234b63a0SChris Mason struct btrfs_node *split; 962be0e5c09SChris Mason int mid; 9635c680ed6SChris Mason int ret; 964aa5d6bedSChris Mason int wret; 9657518a238SChris Mason u32 c_nritems; 966be0e5c09SChris Mason 9675c680ed6SChris Mason t = path->nodes[level]; 968e20d96d6SChris Mason c = btrfs_buffer_node(t); 9695c680ed6SChris Mason if (t == root->node) { 9705c680ed6SChris Mason /* trying to split the root, lets make a new one */ 971e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 9725c680ed6SChris Mason if (ret) 9735c680ed6SChris Mason return ret; 974e66f709bSChris Mason } else { 975e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 976e66f709bSChris Mason t = path->nodes[level]; 977e66f709bSChris Mason c = btrfs_buffer_node(t); 978e66f709bSChris Mason if (!ret && 979e66f709bSChris Mason btrfs_header_nritems(&c->header) < 980e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 981e66f709bSChris Mason return 0; 98254aa1f4dSChris Mason if (ret < 0) 98354aa1f4dSChris Mason return ret; 9845c680ed6SChris Mason } 985e66f709bSChris Mason 9867518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 98731f3c99bSChris Mason split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr); 98854aa1f4dSChris Mason if (IS_ERR(split_buffer)) 98954aa1f4dSChris Mason return PTR_ERR(split_buffer); 99054aa1f4dSChris Mason 991e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 9927518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 9939a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 9947eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 9957f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 9964d775673SChris Mason btrfs_set_header_owner(&split->header, root->root_key.objectid); 9973eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 9983eb0314dSChris Mason sizeof(split->header.fsid)); 9997518a238SChris Mason mid = (c_nritems + 1) / 2; 1000d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 1001123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 10027518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 10037518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 1004aa5d6bedSChris Mason ret = 0; 1005aa5d6bedSChris Mason 1006d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1007d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 1008e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 10097eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 1010123abc88SChris Mason level + 1); 1011aa5d6bedSChris Mason if (wret) 1012aa5d6bedSChris Mason ret = wret; 1013aa5d6bedSChris Mason 10145de08d7dSChris Mason if (path->slots[level] >= mid) { 10155c680ed6SChris Mason path->slots[level] -= mid; 1016234b63a0SChris Mason btrfs_block_release(root, t); 10175c680ed6SChris Mason path->nodes[level] = split_buffer; 10185c680ed6SChris Mason path->slots[level + 1] += 1; 1019eb60ceacSChris Mason } else { 1020234b63a0SChris Mason btrfs_block_release(root, split_buffer); 1021be0e5c09SChris Mason } 1022aa5d6bedSChris Mason return ret; 1023be0e5c09SChris Mason } 1024be0e5c09SChris Mason 102574123bd7SChris Mason /* 102674123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 102774123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 102874123bd7SChris Mason * space used both by the item structs and the item data 102974123bd7SChris Mason */ 1030234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 1031be0e5c09SChris Mason { 1032be0e5c09SChris Mason int data_len; 1033d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 1034d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 1035be0e5c09SChris Mason 1036be0e5c09SChris Mason if (!nr) 1037be0e5c09SChris Mason return 0; 10380783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 10390783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 10400783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 1041d4dbff95SChris Mason WARN_ON(data_len < 0); 1042be0e5c09SChris Mason return data_len; 1043be0e5c09SChris Mason } 1044be0e5c09SChris Mason 104574123bd7SChris Mason /* 1046d4dbff95SChris Mason * The space between the end of the leaf items and 1047d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 1048d4dbff95SChris Mason * the leaf has left for both items and data 1049d4dbff95SChris Mason */ 1050d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 1051d4dbff95SChris Mason { 1052d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 1053d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 1054d4dbff95SChris Mason } 1055d4dbff95SChris Mason 1056d4dbff95SChris Mason /* 105700ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 105800ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 1059aa5d6bedSChris Mason * 1060aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 1061aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 106200ec4c51SChris Mason */ 1063e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 1064e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 106500ec4c51SChris Mason { 1066e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 1067e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 1068234b63a0SChris Mason struct btrfs_leaf *right; 1069e20d96d6SChris Mason struct buffer_head *right_buf; 1070e20d96d6SChris Mason struct buffer_head *upper; 1071e20d96d6SChris Mason struct btrfs_node *upper_node; 107200ec4c51SChris Mason int slot; 107300ec4c51SChris Mason int i; 107400ec4c51SChris Mason int free_space; 107500ec4c51SChris Mason int push_space = 0; 107600ec4c51SChris Mason int push_items = 0; 10770783fcfcSChris Mason struct btrfs_item *item; 10787518a238SChris Mason u32 left_nritems; 10797518a238SChris Mason u32 right_nritems; 108054aa1f4dSChris Mason int ret; 108100ec4c51SChris Mason 108200ec4c51SChris Mason slot = path->slots[1]; 108300ec4c51SChris Mason if (!path->nodes[1]) { 108400ec4c51SChris Mason return 1; 108500ec4c51SChris Mason } 108600ec4c51SChris Mason upper = path->nodes[1]; 1087e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1088e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 108900ec4c51SChris Mason return 1; 109000ec4c51SChris Mason } 1091e20d96d6SChris Mason right_buf = read_tree_block(root, 1092e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 1093e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1094123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10950783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1096234b63a0SChris Mason btrfs_block_release(root, right_buf); 109700ec4c51SChris Mason return 1; 109800ec4c51SChris Mason } 109902217ed2SChris Mason /* cow and double check */ 110054aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, upper, 110154aa1f4dSChris Mason slot + 1, &right_buf); 110254aa1f4dSChris Mason if (ret) { 110354aa1f4dSChris Mason btrfs_block_release(root, right_buf); 110454aa1f4dSChris Mason return 1; 110554aa1f4dSChris Mason } 1106e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1107123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 11080783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1109234b63a0SChris Mason btrfs_block_release(root, right_buf); 111002217ed2SChris Mason return 1; 111102217ed2SChris Mason } 111202217ed2SChris Mason 11137518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1114a429e513SChris Mason if (left_nritems == 0) { 1115a429e513SChris Mason btrfs_block_release(root, right_buf); 1116a429e513SChris Mason return 1; 1117a429e513SChris Mason } 1118a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 111900ec4c51SChris Mason item = left->items + i; 112000ec4c51SChris Mason if (path->slots[0] == i) 112100ec4c51SChris Mason push_space += data_size + sizeof(*item); 11220783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 11230783fcfcSChris Mason free_space) 112400ec4c51SChris Mason break; 112500ec4c51SChris Mason push_items++; 11260783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 112700ec4c51SChris Mason } 112800ec4c51SChris Mason if (push_items == 0) { 1129234b63a0SChris Mason btrfs_block_release(root, right_buf); 113000ec4c51SChris Mason return 1; 113100ec4c51SChris Mason } 1132a429e513SChris Mason if (push_items == left_nritems) 1133a429e513SChris Mason WARN_ON(1); 11347518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 113500ec4c51SChris Mason /* push left to right */ 11360783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1137123abc88SChris Mason push_space -= leaf_data_end(root, left); 113800ec4c51SChris Mason /* make room in the right data area */ 1139d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1140d6025579SChris Mason leaf_data_end(root, right) - push_space, 1141d6025579SChris Mason btrfs_leaf_data(right) + 1142d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1143d6025579SChris Mason leaf_data_end(root, right)); 114400ec4c51SChris Mason /* copy from the left data area */ 1145d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1146d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1147d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1148d6025579SChris Mason push_space); 1149d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 11500783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 115100ec4c51SChris Mason /* copy the items from left to right */ 1152d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1153d6025579SChris Mason left_nritems - push_items, 11540783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 115500ec4c51SChris Mason 115600ec4c51SChris Mason /* update the item pointers */ 11577518a238SChris Mason right_nritems += push_items; 11587518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1159123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 11607518a238SChris Mason for (i = 0; i < right_nritems; i++) { 11610783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 11620783fcfcSChris Mason btrfs_item_size(right->items + i)); 11630783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 116400ec4c51SChris Mason } 11657518a238SChris Mason left_nritems -= push_items; 11667518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 116700ec4c51SChris Mason 1168d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1169d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1170a429e513SChris Mason 1171d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1172e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1173d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 117402217ed2SChris Mason 117500ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 11767518a238SChris Mason if (path->slots[0] >= left_nritems) { 11777518a238SChris Mason path->slots[0] -= left_nritems; 1178234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 117900ec4c51SChris Mason path->nodes[0] = right_buf; 118000ec4c51SChris Mason path->slots[1] += 1; 118100ec4c51SChris Mason } else { 1182234b63a0SChris Mason btrfs_block_release(root, right_buf); 118300ec4c51SChris Mason } 1184098f59c2SChris Mason if (path->nodes[1]) 1185098f59c2SChris Mason check_node(root, path, 1); 118600ec4c51SChris Mason return 0; 118700ec4c51SChris Mason } 118800ec4c51SChris Mason /* 118974123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 119074123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 119174123bd7SChris Mason */ 1192e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1193e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1194be0e5c09SChris Mason { 1195e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1196e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1197e20d96d6SChris Mason struct buffer_head *t; 1198234b63a0SChris Mason struct btrfs_leaf *left; 1199be0e5c09SChris Mason int slot; 1200be0e5c09SChris Mason int i; 1201be0e5c09SChris Mason int free_space; 1202be0e5c09SChris Mason int push_space = 0; 1203be0e5c09SChris Mason int push_items = 0; 12040783fcfcSChris Mason struct btrfs_item *item; 12057518a238SChris Mason u32 old_left_nritems; 1206aa5d6bedSChris Mason int ret = 0; 1207aa5d6bedSChris Mason int wret; 1208be0e5c09SChris Mason 1209be0e5c09SChris Mason slot = path->slots[1]; 1210be0e5c09SChris Mason if (slot == 0) { 1211be0e5c09SChris Mason return 1; 1212be0e5c09SChris Mason } 1213be0e5c09SChris Mason if (!path->nodes[1]) { 1214be0e5c09SChris Mason return 1; 1215be0e5c09SChris Mason } 1216e20d96d6SChris Mason t = read_tree_block(root, 1217e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1218e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1219123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 12200783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1221234b63a0SChris Mason btrfs_block_release(root, t); 1222be0e5c09SChris Mason return 1; 1223be0e5c09SChris Mason } 122402217ed2SChris Mason 122502217ed2SChris Mason /* cow and double check */ 122654aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 122754aa1f4dSChris Mason if (ret) { 122854aa1f4dSChris Mason /* we hit -ENOSPC, but it isn't fatal here */ 122954aa1f4dSChris Mason return 1; 123054aa1f4dSChris Mason } 1231e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1232123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 12330783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1234234b63a0SChris Mason btrfs_block_release(root, t); 123502217ed2SChris Mason return 1; 123602217ed2SChris Mason } 123702217ed2SChris Mason 1238a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1239a429e513SChris Mason btrfs_block_release(root, t); 1240a429e513SChris Mason return 1; 1241a429e513SChris Mason } 1242a429e513SChris Mason 1243a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1244be0e5c09SChris Mason item = right->items + i; 1245be0e5c09SChris Mason if (path->slots[0] == i) 1246be0e5c09SChris Mason push_space += data_size + sizeof(*item); 12470783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 12480783fcfcSChris Mason free_space) 1249be0e5c09SChris Mason break; 1250be0e5c09SChris Mason push_items++; 12510783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1252be0e5c09SChris Mason } 1253be0e5c09SChris Mason if (push_items == 0) { 1254234b63a0SChris Mason btrfs_block_release(root, t); 1255be0e5c09SChris Mason return 1; 1256be0e5c09SChris Mason } 1257a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1258a429e513SChris Mason WARN_ON(1); 1259be0e5c09SChris Mason /* push data from right to left */ 1260d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1261d6025579SChris Mason btrfs_header_nritems(&left->header), 12620783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1263123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 12640783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1265d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1266d6025579SChris Mason leaf_data_end(root, left) - push_space, 1267123abc88SChris Mason btrfs_leaf_data(right) + 1268123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1269be0e5c09SChris Mason push_space); 12707518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1271eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1272eb60ceacSChris Mason 1273be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1274123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1275123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1276123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 12770783fcfcSChris Mason btrfs_item_offset(left->items + 12780783fcfcSChris Mason old_left_nritems - 1))); 1279be0e5c09SChris Mason } 12807518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1281be0e5c09SChris Mason 1282be0e5c09SChris Mason /* fixup right node */ 12830783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1284123abc88SChris Mason leaf_data_end(root, right); 1285d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1286d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1287d6025579SChris Mason btrfs_leaf_data(right) + 1288123abc88SChris Mason leaf_data_end(root, right), push_space); 1289d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 12907518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 12910783fcfcSChris Mason sizeof(struct btrfs_item)); 12927518a238SChris Mason btrfs_set_header_nritems(&right->header, 12937518a238SChris Mason btrfs_header_nritems(&right->header) - 12947518a238SChris Mason push_items); 1295123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1296eb60ceacSChris Mason 12977518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 12980783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 12990783fcfcSChris Mason btrfs_item_size(right->items + i)); 13000783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1301be0e5c09SChris Mason } 1302eb60ceacSChris Mason 1303d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1304d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1305098f59c2SChris Mason 1306e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1307aa5d6bedSChris Mason if (wret) 1308aa5d6bedSChris Mason ret = wret; 1309be0e5c09SChris Mason 1310be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1311be0e5c09SChris Mason if (path->slots[0] < push_items) { 1312be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1313234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1314eb60ceacSChris Mason path->nodes[0] = t; 1315be0e5c09SChris Mason path->slots[1] -= 1; 1316be0e5c09SChris Mason } else { 1317234b63a0SChris Mason btrfs_block_release(root, t); 1318be0e5c09SChris Mason path->slots[0] -= push_items; 1319be0e5c09SChris Mason } 1320eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1321098f59c2SChris Mason if (path->nodes[1]) 1322098f59c2SChris Mason check_node(root, path, 1); 1323aa5d6bedSChris Mason return ret; 1324be0e5c09SChris Mason } 1325be0e5c09SChris Mason 132674123bd7SChris Mason /* 132774123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 132874123bd7SChris Mason * available for the resulting leaf level of the path. 1329aa5d6bedSChris Mason * 1330aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 133174123bd7SChris Mason */ 1332e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1333d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1334d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1335be0e5c09SChris Mason { 1336e20d96d6SChris Mason struct buffer_head *l_buf; 1337234b63a0SChris Mason struct btrfs_leaf *l; 13387518a238SChris Mason u32 nritems; 1339eb60ceacSChris Mason int mid; 1340eb60ceacSChris Mason int slot; 1341234b63a0SChris Mason struct btrfs_leaf *right; 1342e20d96d6SChris Mason struct buffer_head *right_buffer; 13430783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1344be0e5c09SChris Mason int data_copy_size; 1345be0e5c09SChris Mason int rt_data_off; 1346be0e5c09SChris Mason int i; 1347d4dbff95SChris Mason int ret = 0; 1348aa5d6bedSChris Mason int wret; 1349d4dbff95SChris Mason int double_split = 0; 1350d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1351be0e5c09SChris Mason 135240689478SChris Mason /* first try to make some room by pushing left and right */ 1353e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1354eaee50e8SChris Mason if (wret < 0) 1355eaee50e8SChris Mason return wret; 1356eaee50e8SChris Mason if (wret) { 1357e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1358eaee50e8SChris Mason if (wret < 0) 1359eaee50e8SChris Mason return wret; 1360eaee50e8SChris Mason } 1361eb60ceacSChris Mason l_buf = path->nodes[0]; 1362e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1363aa5d6bedSChris Mason 1364aa5d6bedSChris Mason /* did the pushes work? */ 1365123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1366123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1367be0e5c09SChris Mason return 0; 1368aa5d6bedSChris Mason 13695c680ed6SChris Mason if (!path->nodes[1]) { 1370e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 13715c680ed6SChris Mason if (ret) 13725c680ed6SChris Mason return ret; 13735c680ed6SChris Mason } 1374eb60ceacSChris Mason slot = path->slots[0]; 13757518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1376eb60ceacSChris Mason mid = (nritems + 1)/ 2; 137754aa1f4dSChris Mason 137831f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 137954aa1f4dSChris Mason if (IS_ERR(right_buffer)) 138054aa1f4dSChris Mason return PTR_ERR(right_buffer); 138154aa1f4dSChris Mason 1382e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1383123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 13847eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 13857f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 13864d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 13877518a238SChris Mason btrfs_set_header_level(&right->header, 0); 13883eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 13893eb0314dSChris Mason sizeof(right->header.fsid)); 1390d4dbff95SChris Mason if (mid <= slot) { 1391d4dbff95SChris Mason if (nritems == 1 || 1392d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1393d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1394d4dbff95SChris Mason if (slot >= nritems) { 1395d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1396d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1397d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1398d4dbff95SChris Mason &disk_key, 13997eccb903SChris Mason bh_blocknr(right_buffer), 1400d4dbff95SChris Mason path->slots[1] + 1, 1); 1401d4dbff95SChris Mason if (wret) 1402d4dbff95SChris Mason ret = wret; 1403d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1404d4dbff95SChris Mason path->nodes[0] = right_buffer; 1405d4dbff95SChris Mason path->slots[0] = 0; 1406d4dbff95SChris Mason path->slots[1] += 1; 1407d4dbff95SChris Mason return ret; 1408d4dbff95SChris Mason } 1409d4dbff95SChris Mason mid = slot; 1410d4dbff95SChris Mason double_split = 1; 1411d4dbff95SChris Mason } 1412d4dbff95SChris Mason } else { 1413d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1414d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1415d4dbff95SChris Mason if (slot == 0) { 1416d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1417d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1418d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1419d4dbff95SChris Mason &disk_key, 14207eccb903SChris Mason bh_blocknr(right_buffer), 1421098f59c2SChris Mason path->slots[1], 1); 1422d4dbff95SChris Mason if (wret) 1423d4dbff95SChris Mason ret = wret; 1424d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1425d4dbff95SChris Mason path->nodes[0] = right_buffer; 1426d4dbff95SChris Mason path->slots[0] = 0; 1427a429e513SChris Mason if (path->slots[1] == 0) { 1428a429e513SChris Mason wret = fixup_low_keys(trans, root, 1429a429e513SChris Mason path, &disk_key, 1); 1430a429e513SChris Mason if (wret) 1431a429e513SChris Mason ret = wret; 1432a429e513SChris Mason } 1433d4dbff95SChris Mason return ret; 1434d4dbff95SChris Mason } 1435d4dbff95SChris Mason mid = slot; 1436d4dbff95SChris Mason double_split = 1; 1437d4dbff95SChris Mason } 1438d4dbff95SChris Mason } 1439d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1440123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1441123abc88SChris Mason leaf_data_end(root, l); 1442d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 14430783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1444d6025579SChris Mason btrfs_memcpy(root, right, 1445d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1446123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1447123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1448123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1449123abc88SChris Mason btrfs_item_end(l->items + mid); 145074123bd7SChris Mason 14510783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1452123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 14530783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 14540783fcfcSChris Mason } 145574123bd7SChris Mason 14567518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1457aa5d6bedSChris Mason ret = 0; 1458e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 14597eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1460aa5d6bedSChris Mason if (wret) 1461aa5d6bedSChris Mason ret = wret; 1462d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1463d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1464eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1465be0e5c09SChris Mason if (mid <= slot) { 1466234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1467eb60ceacSChris Mason path->nodes[0] = right_buffer; 1468be0e5c09SChris Mason path->slots[0] -= mid; 1469be0e5c09SChris Mason path->slots[1] += 1; 1470eb60ceacSChris Mason } else 1471234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1472eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1473098f59c2SChris Mason check_node(root, path, 1); 1474d4dbff95SChris Mason 1475d4dbff95SChris Mason if (!double_split) 1476d4dbff95SChris Mason return ret; 147731f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 147854aa1f4dSChris Mason if (IS_ERR(right_buffer)) 147954aa1f4dSChris Mason return PTR_ERR(right_buffer); 148054aa1f4dSChris Mason 1481d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1482d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 14837eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1484d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 14854d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 1486d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 14873eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 14883eb0314dSChris Mason sizeof(right->header.fsid)); 1489d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1490d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1491d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1492d4dbff95SChris Mason &disk_key, 14937eccb903SChris Mason bh_blocknr(right_buffer), 1494d4dbff95SChris Mason path->slots[1], 1); 1495d4dbff95SChris Mason if (wret) 1496d4dbff95SChris Mason ret = wret; 1497a429e513SChris Mason if (path->slots[1] == 0) { 1498a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1499a429e513SChris Mason if (wret) 1500a429e513SChris Mason ret = wret; 1501a429e513SChris Mason } 1502d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1503d4dbff95SChris Mason path->nodes[0] = right_buffer; 1504d4dbff95SChris Mason path->slots[0] = 0; 1505d4dbff95SChris Mason check_node(root, path, 1); 1506d4dbff95SChris Mason check_leaf(root, path, 0); 1507be0e5c09SChris Mason return ret; 1508be0e5c09SChris Mason } 1509be0e5c09SChris Mason 1510b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1511b18c6685SChris Mason struct btrfs_root *root, 1512b18c6685SChris Mason struct btrfs_path *path, 1513b18c6685SChris Mason u32 new_size) 1514b18c6685SChris Mason { 1515b18c6685SChris Mason int ret = 0; 1516b18c6685SChris Mason int slot; 1517b18c6685SChris Mason int slot_orig; 1518b18c6685SChris Mason struct btrfs_leaf *leaf; 1519b18c6685SChris Mason struct buffer_head *leaf_buf; 1520b18c6685SChris Mason u32 nritems; 1521b18c6685SChris Mason unsigned int data_end; 1522b18c6685SChris Mason unsigned int old_data_start; 1523b18c6685SChris Mason unsigned int old_size; 1524b18c6685SChris Mason unsigned int size_diff; 1525b18c6685SChris Mason int i; 1526b18c6685SChris Mason 1527b18c6685SChris Mason slot_orig = path->slots[0]; 1528b18c6685SChris Mason leaf_buf = path->nodes[0]; 1529b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1530b18c6685SChris Mason 1531b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1532b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1533b18c6685SChris Mason 1534b18c6685SChris Mason slot = path->slots[0]; 1535b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1536b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1537b18c6685SChris Mason BUG_ON(old_size <= new_size); 1538b18c6685SChris Mason size_diff = old_size - new_size; 1539b18c6685SChris Mason 1540b18c6685SChris Mason BUG_ON(slot < 0); 1541b18c6685SChris Mason BUG_ON(slot >= nritems); 1542b18c6685SChris Mason 1543b18c6685SChris Mason /* 1544b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1545b18c6685SChris Mason */ 1546b18c6685SChris Mason /* first correct the data pointers */ 1547b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1548b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1549b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1550b18c6685SChris Mason ioff + size_diff); 1551b18c6685SChris Mason } 1552b18c6685SChris Mason /* shift the data */ 1553b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1554b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1555b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1556b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1557b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1558b18c6685SChris Mason 1559b18c6685SChris Mason ret = 0; 1560b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1561b18c6685SChris Mason BUG(); 1562b18c6685SChris Mason check_leaf(root, path, 0); 1563b18c6685SChris Mason return ret; 1564b18c6685SChris Mason } 1565b18c6685SChris Mason 15666567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 15676567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 15686567e837SChris Mason { 15696567e837SChris Mason int ret = 0; 15706567e837SChris Mason int slot; 15716567e837SChris Mason int slot_orig; 15726567e837SChris Mason struct btrfs_leaf *leaf; 15736567e837SChris Mason struct buffer_head *leaf_buf; 15746567e837SChris Mason u32 nritems; 15756567e837SChris Mason unsigned int data_end; 15766567e837SChris Mason unsigned int old_data; 15776567e837SChris Mason unsigned int old_size; 15786567e837SChris Mason int i; 15796567e837SChris Mason 15806567e837SChris Mason slot_orig = path->slots[0]; 15816567e837SChris Mason leaf_buf = path->nodes[0]; 15826567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 15836567e837SChris Mason 15846567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 15856567e837SChris Mason data_end = leaf_data_end(root, leaf); 15866567e837SChris Mason 15876567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 15886567e837SChris Mason BUG(); 15896567e837SChris Mason slot = path->slots[0]; 15906567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 15916567e837SChris Mason 15926567e837SChris Mason BUG_ON(slot < 0); 15936567e837SChris Mason BUG_ON(slot >= nritems); 15946567e837SChris Mason 15956567e837SChris Mason /* 15966567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 15976567e837SChris Mason */ 15986567e837SChris Mason /* first correct the data pointers */ 15996567e837SChris Mason for (i = slot; i < nritems; i++) { 16006567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 16016567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 16026567e837SChris Mason ioff - data_size); 16036567e837SChris Mason } 16046567e837SChris Mason /* shift the data */ 16056567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 16066567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 16076567e837SChris Mason data_end, old_data - data_end); 16086567e837SChris Mason data_end = old_data; 16096567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 16106567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 16116567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 16126567e837SChris Mason 16136567e837SChris Mason ret = 0; 16146567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 16156567e837SChris Mason BUG(); 16166567e837SChris Mason check_leaf(root, path, 0); 16176567e837SChris Mason return ret; 16186567e837SChris Mason } 16196567e837SChris Mason 162074123bd7SChris Mason /* 162174123bd7SChris Mason * Given a key and some data, insert an item into the tree. 162274123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 162374123bd7SChris Mason */ 1624e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1625e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1626e089f05cSChris Mason *cpu_key, u32 data_size) 1627be0e5c09SChris Mason { 1628aa5d6bedSChris Mason int ret = 0; 1629be0e5c09SChris Mason int slot; 1630eb60ceacSChris Mason int slot_orig; 1631234b63a0SChris Mason struct btrfs_leaf *leaf; 1632e20d96d6SChris Mason struct buffer_head *leaf_buf; 16337518a238SChris Mason u32 nritems; 1634be0e5c09SChris Mason unsigned int data_end; 1635e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1636e2fa7227SChris Mason 1637e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1638be0e5c09SChris Mason 163974123bd7SChris Mason /* create a root if there isn't one */ 16405c680ed6SChris Mason if (!root->node) 1641cfaa7295SChris Mason BUG(); 1642e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1643eb60ceacSChris Mason if (ret == 0) { 1644f0930a37SChris Mason return -EEXIST; 1645aa5d6bedSChris Mason } 1646ed2ff2cbSChris Mason if (ret < 0) 1647ed2ff2cbSChris Mason goto out; 1648be0e5c09SChris Mason 164962e2749eSChris Mason slot_orig = path->slots[0]; 165062e2749eSChris Mason leaf_buf = path->nodes[0]; 1651e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 165274123bd7SChris Mason 16537518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1654123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1655eb60ceacSChris Mason 1656123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1657d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1658be0e5c09SChris Mason BUG(); 1659d4dbff95SChris Mason } 166062e2749eSChris Mason slot = path->slots[0]; 1661eb60ceacSChris Mason BUG_ON(slot < 0); 1662be0e5c09SChris Mason if (slot != nritems) { 1663be0e5c09SChris Mason int i; 16640783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1665be0e5c09SChris Mason 1666be0e5c09SChris Mason /* 1667be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1668be0e5c09SChris Mason */ 1669be0e5c09SChris Mason /* first correct the data pointers */ 16700783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1671123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 16720783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 16730783fcfcSChris Mason ioff - data_size); 16740783fcfcSChris Mason } 1675be0e5c09SChris Mason 1676be0e5c09SChris Mason /* shift the items */ 1677d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1678d6025579SChris Mason leaf->items + slot, 16790783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1680be0e5c09SChris Mason 1681be0e5c09SChris Mason /* shift the data */ 1682d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1683d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1684be0e5c09SChris Mason data_end, old_data - data_end); 1685be0e5c09SChris Mason data_end = old_data; 1686be0e5c09SChris Mason } 168762e2749eSChris Mason /* setup the item for the new data */ 1688d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1689e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 16900783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 16910783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 16927518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1693d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1694aa5d6bedSChris Mason 1695aa5d6bedSChris Mason ret = 0; 16968e19f2cdSChris Mason if (slot == 0) 1697e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1698aa5d6bedSChris Mason 1699123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1700be0e5c09SChris Mason BUG(); 170162e2749eSChris Mason check_leaf(root, path, 0); 1702ed2ff2cbSChris Mason out: 170362e2749eSChris Mason return ret; 170462e2749eSChris Mason } 170562e2749eSChris Mason 170662e2749eSChris Mason /* 170762e2749eSChris Mason * Given a key and some data, insert an item into the tree. 170862e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 170962e2749eSChris Mason */ 1710e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1711e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1712e089f05cSChris Mason data_size) 171362e2749eSChris Mason { 171462e2749eSChris Mason int ret = 0; 17152c90e5d6SChris Mason struct btrfs_path *path; 171662e2749eSChris Mason u8 *ptr; 171762e2749eSChris Mason 17182c90e5d6SChris Mason path = btrfs_alloc_path(); 17192c90e5d6SChris Mason BUG_ON(!path); 17202c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 172162e2749eSChris Mason if (!ret) { 17222c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 17232c90e5d6SChris Mason path->slots[0], u8); 17242c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1725d6025579SChris Mason ptr, data, data_size); 17262c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 172762e2749eSChris Mason } 17282c90e5d6SChris Mason btrfs_free_path(path); 1729aa5d6bedSChris Mason return ret; 1730be0e5c09SChris Mason } 1731be0e5c09SChris Mason 173274123bd7SChris Mason /* 17335de08d7dSChris Mason * delete the pointer from a given node. 173474123bd7SChris Mason * 173574123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 173674123bd7SChris Mason * continuing all the way the root if required. The root is converted into 173774123bd7SChris Mason * a leaf if all the nodes are emptied. 173874123bd7SChris Mason */ 1739e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1740e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1741be0e5c09SChris Mason { 1742234b63a0SChris Mason struct btrfs_node *node; 1743e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 17447518a238SChris Mason u32 nritems; 1745aa5d6bedSChris Mason int ret = 0; 1746bb803951SChris Mason int wret; 1747be0e5c09SChris Mason 1748e20d96d6SChris Mason node = btrfs_buffer_node(parent); 17497518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1750be0e5c09SChris Mason if (slot != nritems -1) { 1751d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1752d6025579SChris Mason node->ptrs + slot + 1, 1753d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1754d6025579SChris Mason (nritems - slot - 1)); 1755be0e5c09SChris Mason } 17567518a238SChris Mason nritems--; 17577518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 17587518a238SChris Mason if (nritems == 0 && parent == root->node) { 1759e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1760e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1761eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1762e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1763bb803951SChris Mason } else if (slot == 0) { 1764e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1765123abc88SChris Mason level + 1); 17660f70abe2SChris Mason if (wret) 17670f70abe2SChris Mason ret = wret; 1768be0e5c09SChris Mason } 1769d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1770aa5d6bedSChris Mason return ret; 1771be0e5c09SChris Mason } 1772be0e5c09SChris Mason 177374123bd7SChris Mason /* 177474123bd7SChris Mason * delete the item at the leaf level in path. If that empties 177574123bd7SChris Mason * the leaf, remove it from the tree 177674123bd7SChris Mason */ 1777e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1778e089f05cSChris Mason struct btrfs_path *path) 1779be0e5c09SChris Mason { 1780be0e5c09SChris Mason int slot; 1781234b63a0SChris Mason struct btrfs_leaf *leaf; 1782e20d96d6SChris Mason struct buffer_head *leaf_buf; 1783be0e5c09SChris Mason int doff; 1784be0e5c09SChris Mason int dsize; 1785aa5d6bedSChris Mason int ret = 0; 1786aa5d6bedSChris Mason int wret; 17877518a238SChris Mason u32 nritems; 1788be0e5c09SChris Mason 1789eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1790e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 17914920c9acSChris Mason slot = path->slots[0]; 17920783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 17930783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 17947518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1795be0e5c09SChris Mason 17967518a238SChris Mason if (slot != nritems - 1) { 1797be0e5c09SChris Mason int i; 1798123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 1799d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1800d6025579SChris Mason data_end + dsize, 1801123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 1802be0e5c09SChris Mason doff - data_end); 18030783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 1804123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 18050783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 18060783fcfcSChris Mason } 1807d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 1808d6025579SChris Mason leaf->items + slot + 1, 18090783fcfcSChris Mason sizeof(struct btrfs_item) * 18107518a238SChris Mason (nritems - slot - 1)); 1811be0e5c09SChris Mason } 18127518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 18137518a238SChris Mason nritems--; 181474123bd7SChris Mason /* delete the leaf if we've emptied it */ 18157518a238SChris Mason if (nritems == 0) { 1816eb60ceacSChris Mason if (leaf_buf == root->node) { 18177518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 18189a8dd150SChris Mason } else { 1819e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1820d6025579SChris Mason wait_on_buffer(leaf_buf); 1821e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 1822aa5d6bedSChris Mason if (wret) 1823aa5d6bedSChris Mason ret = wret; 1824e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 18257eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 18260f70abe2SChris Mason if (wret) 18270f70abe2SChris Mason ret = wret; 18289a8dd150SChris Mason } 1829be0e5c09SChris Mason } else { 18307518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 1831aa5d6bedSChris Mason if (slot == 0) { 1832e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 1833aa5d6bedSChris Mason &leaf->items[0].key, 1); 1834aa5d6bedSChris Mason if (wret) 1835aa5d6bedSChris Mason ret = wret; 1836aa5d6bedSChris Mason } 1837aa5d6bedSChris Mason 183874123bd7SChris Mason /* delete the leaf if it is mostly empty */ 1839123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1840be0e5c09SChris Mason /* push_leaf_left fixes the path. 1841be0e5c09SChris Mason * make sure the path still points to our leaf 1842be0e5c09SChris Mason * for possible call to del_ptr below 1843be0e5c09SChris Mason */ 18444920c9acSChris Mason slot = path->slots[1]; 1845e20d96d6SChris Mason get_bh(leaf_buf); 1846e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 184754aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 1848aa5d6bedSChris Mason ret = wret; 1849f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 18507518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 1851e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 185254aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 1853aa5d6bedSChris Mason ret = wret; 1854aa5d6bedSChris Mason } 18557518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 18567eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 1857e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1858d6025579SChris Mason wait_on_buffer(leaf_buf); 1859e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 1860aa5d6bedSChris Mason if (wret) 1861aa5d6bedSChris Mason ret = wret; 1862234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1863e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1864e089f05cSChris Mason 1, 1); 18650f70abe2SChris Mason if (wret) 18660f70abe2SChris Mason ret = wret; 18675de08d7dSChris Mason } else { 1868d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1869234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1870be0e5c09SChris Mason } 1871d5719762SChris Mason } else { 1872d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1873be0e5c09SChris Mason } 18749a8dd150SChris Mason } 1875aa5d6bedSChris Mason return ret; 18769a8dd150SChris Mason } 18779a8dd150SChris Mason 187897571fd0SChris Mason /* 187997571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 18800f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 18810f70abe2SChris Mason * returns < 0 on io errors. 188297571fd0SChris Mason */ 1883234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 1884d97e63b6SChris Mason { 1885d97e63b6SChris Mason int slot; 1886d97e63b6SChris Mason int level = 1; 1887d97e63b6SChris Mason u64 blocknr; 1888e20d96d6SChris Mason struct buffer_head *c; 1889e20d96d6SChris Mason struct btrfs_node *c_node; 1890e20d96d6SChris Mason struct buffer_head *next = NULL; 1891d97e63b6SChris Mason 1892234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 1893d97e63b6SChris Mason if (!path->nodes[level]) 18940f70abe2SChris Mason return 1; 1895d97e63b6SChris Mason slot = path->slots[level] + 1; 1896d97e63b6SChris Mason c = path->nodes[level]; 1897e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 1898e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 1899d97e63b6SChris Mason level++; 1900d97e63b6SChris Mason continue; 1901d97e63b6SChris Mason } 1902e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 1903cfaa7295SChris Mason if (next) 1904234b63a0SChris Mason btrfs_block_release(root, next); 1905d97e63b6SChris Mason next = read_tree_block(root, blocknr); 1906d97e63b6SChris Mason break; 1907d97e63b6SChris Mason } 1908d97e63b6SChris Mason path->slots[level] = slot; 1909d97e63b6SChris Mason while(1) { 1910d97e63b6SChris Mason level--; 1911d97e63b6SChris Mason c = path->nodes[level]; 1912234b63a0SChris Mason btrfs_block_release(root, c); 1913d97e63b6SChris Mason path->nodes[level] = next; 1914d97e63b6SChris Mason path->slots[level] = 0; 1915d97e63b6SChris Mason if (!level) 1916d97e63b6SChris Mason break; 19171d4f8a0cSChris Mason next = read_tree_block(root, 1918e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 1919d97e63b6SChris Mason } 1920d97e63b6SChris Mason return 0; 1921d97e63b6SChris Mason } 1922