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 19eb60ceacSChris Mason #include "ctree.h" 20eb60ceacSChris Mason #include "disk-io.h" 217f5c1516SChris Mason #include "transaction.h" 229a8dd150SChris Mason 23e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 24e089f05cSChris Mason *root, struct btrfs_path *path, int level); 25e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 26d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 27d4dbff95SChris Mason struct btrfs_path *path, int data_size); 28e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 29e20d96d6SChris Mason *root, struct buffer_head *dst, struct buffer_head 30e089f05cSChris Mason *src); 31e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 32e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 33e20d96d6SChris Mason struct buffer_head *src_buf); 34e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 35e089f05cSChris Mason struct btrfs_path *path, int level, int slot); 36d97e63b6SChris Mason 37df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p) 38df24a2b9SChris Mason { 39df24a2b9SChris Mason memset(p, 0, sizeof(*p)); 40df24a2b9SChris Mason } 41df24a2b9SChris Mason 422c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void) 432c90e5d6SChris Mason { 44df24a2b9SChris Mason struct btrfs_path *path; 45df24a2b9SChris Mason path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); 46df24a2b9SChris Mason if (path) 47df24a2b9SChris Mason btrfs_init_path(path); 48df24a2b9SChris Mason return path; 492c90e5d6SChris Mason } 502c90e5d6SChris Mason 512c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p) 522c90e5d6SChris Mason { 53df24a2b9SChris Mason btrfs_release_path(NULL, p); 542c90e5d6SChris Mason kmem_cache_free(btrfs_path_cachep, p); 552c90e5d6SChris Mason } 562c90e5d6SChris Mason 57234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) 58eb60ceacSChris Mason { 59eb60ceacSChris Mason int i; 60234b63a0SChris Mason for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 61eb60ceacSChris Mason if (!p->nodes[i]) 62eb60ceacSChris Mason break; 63234b63a0SChris Mason btrfs_block_release(root, p->nodes[i]); 64eb60ceacSChris Mason } 65aa5d6bedSChris Mason memset(p, 0, sizeof(*p)); 66eb60ceacSChris Mason } 67eb60ceacSChris Mason 68e089f05cSChris Mason static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 69e20d96d6SChris Mason *root, struct buffer_head *buf, struct buffer_head 70e20d96d6SChris Mason *parent, int parent_slot, struct buffer_head 71e089f05cSChris Mason **cow_ret) 7202217ed2SChris Mason { 73e20d96d6SChris Mason struct buffer_head *cow; 74e20d96d6SChris Mason struct btrfs_node *cow_node; 7554aa1f4dSChris Mason int ret; 7602217ed2SChris Mason 77ccd467d6SChris Mason WARN_ON(!buffer_uptodate(buf)); 78ccd467d6SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 79ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 80ccd467d6SChris Mason root->fs_info->running_transaction->transid); 81ccd467d6SChris Mason WARN_ON(1); 82ccd467d6SChris Mason } 83ccd467d6SChris Mason if (trans->transid != root->fs_info->generation) { 84ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 85ccd467d6SChris Mason root->fs_info->generation); 86ccd467d6SChris Mason WARN_ON(1); 87ccd467d6SChris Mason } 887f5c1516SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) == 897f5c1516SChris Mason trans->transid) { 9002217ed2SChris Mason *cow_ret = buf; 9102217ed2SChris Mason return 0; 9202217ed2SChris Mason } 9331f3c99bSChris Mason cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr); 9454aa1f4dSChris Mason if (IS_ERR(cow)) 9554aa1f4dSChris Mason return PTR_ERR(cow); 96e20d96d6SChris Mason cow_node = btrfs_buffer_node(cow); 972c90e5d6SChris Mason if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) 982c90e5d6SChris Mason WARN_ON(1); 99e20d96d6SChris Mason memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 1007eccb903SChris Mason btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); 1017f5c1516SChris Mason btrfs_set_header_generation(&cow_node->header, trans->transid); 1024d775673SChris Mason btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); 10354aa1f4dSChris Mason ret = btrfs_inc_ref(trans, root, buf); 10454aa1f4dSChris Mason if (ret) 10554aa1f4dSChris Mason return ret; 10602217ed2SChris Mason if (buf == root->node) { 10702217ed2SChris Mason root->node = cow; 108e20d96d6SChris Mason get_bh(cow); 1092c90e5d6SChris Mason if (buf != root->commit_root) { 1107eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 1112c90e5d6SChris Mason } 112234b63a0SChris Mason btrfs_block_release(root, buf); 11302217ed2SChris Mason } else { 114e20d96d6SChris Mason btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 1157eccb903SChris Mason bh_blocknr(cow)); 116d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1177eccb903SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 11802217ed2SChris Mason } 119234b63a0SChris Mason btrfs_block_release(root, buf); 120ccd467d6SChris Mason btrfs_mark_buffer_dirty(cow); 1212c90e5d6SChris Mason *cow_ret = cow; 12202217ed2SChris Mason return 0; 12302217ed2SChris Mason } 12402217ed2SChris Mason 12574123bd7SChris Mason /* 12674123bd7SChris Mason * The leaf data grows from end-to-front in the node. 12774123bd7SChris Mason * this returns the address of the start of the last item, 12874123bd7SChris Mason * which is the stop of the leaf data stack 12974123bd7SChris Mason */ 130123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 131123abc88SChris Mason struct btrfs_leaf *leaf) 132be0e5c09SChris Mason { 1337518a238SChris Mason u32 nr = btrfs_header_nritems(&leaf->header); 134be0e5c09SChris Mason if (nr == 0) 135123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 1360783fcfcSChris Mason return btrfs_item_offset(leaf->items + nr - 1); 137be0e5c09SChris Mason } 138be0e5c09SChris Mason 13974123bd7SChris Mason /* 14074123bd7SChris Mason * compare two keys in a memcmp fashion 14174123bd7SChris Mason */ 1429aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 143be0e5c09SChris Mason { 144e2fa7227SChris Mason struct btrfs_key k1; 145e2fa7227SChris Mason 146e2fa7227SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 147e2fa7227SChris Mason 148e2fa7227SChris Mason if (k1.objectid > k2->objectid) 149be0e5c09SChris Mason return 1; 150e2fa7227SChris Mason if (k1.objectid < k2->objectid) 151be0e5c09SChris Mason return -1; 152f254e52cSChris Mason if (k1.flags > k2->flags) 153f254e52cSChris Mason return 1; 154f254e52cSChris Mason if (k1.flags < k2->flags) 155f254e52cSChris Mason return -1; 15670b2befdSChris Mason if (k1.offset > k2->offset) 15770b2befdSChris Mason return 1; 15870b2befdSChris Mason if (k1.offset < k2->offset) 15970b2befdSChris Mason return -1; 160be0e5c09SChris Mason return 0; 161be0e5c09SChris Mason } 16274123bd7SChris Mason 163123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 164123abc88SChris Mason int level) 165aa5d6bedSChris Mason { 166234b63a0SChris Mason struct btrfs_node *parent = NULL; 167e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 168aa5d6bedSChris Mason int parent_slot; 1698d7be552SChris Mason int slot; 1708d7be552SChris Mason struct btrfs_key cpukey; 1717518a238SChris Mason u32 nritems = btrfs_header_nritems(&node->header); 172aa5d6bedSChris Mason 173aa5d6bedSChris Mason if (path->nodes[level + 1]) 174e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 175a1f39630SAneesh 1768d7be552SChris Mason slot = path->slots[level]; 1777518a238SChris Mason BUG_ON(nritems == 0); 1787518a238SChris Mason if (parent) { 179e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 180a1f39630SAneesh 181a1f39630SAneesh parent_slot = path->slots[level + 1]; 182123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 183123abc88SChris Mason BUG_ON(memcmp(parent_key, &node->ptrs[0].key, 184e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 1851d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 1867518a238SChris Mason btrfs_header_blocknr(&node->header)); 187aa5d6bedSChris Mason } 188123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 1898d7be552SChris Mason if (slot != 0) { 1908d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key); 1918d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0); 1928d7be552SChris Mason } 1938d7be552SChris Mason if (slot < nritems - 1) { 1948d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key); 1958d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0); 196aa5d6bedSChris Mason } 197aa5d6bedSChris Mason return 0; 198aa5d6bedSChris Mason } 199aa5d6bedSChris Mason 200123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 201123abc88SChris Mason int level) 202aa5d6bedSChris Mason { 203e20d96d6SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); 204234b63a0SChris Mason struct btrfs_node *parent = NULL; 205aa5d6bedSChris Mason int parent_slot; 2068d7be552SChris Mason int slot = path->slots[0]; 2078d7be552SChris Mason struct btrfs_key cpukey; 2088d7be552SChris Mason 2097518a238SChris Mason u32 nritems = btrfs_header_nritems(&leaf->header); 210aa5d6bedSChris Mason 211aa5d6bedSChris Mason if (path->nodes[level + 1]) 212e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 213a1f39630SAneesh 214123abc88SChris Mason BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 2157518a238SChris Mason 2167518a238SChris Mason if (nritems == 0) 2177518a238SChris Mason return 0; 2187518a238SChris Mason 2197518a238SChris Mason if (parent) { 220e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 221a1f39630SAneesh 222a1f39630SAneesh parent_slot = path->slots[level + 1]; 223123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 224aa5d6bedSChris Mason BUG_ON(memcmp(parent_key, &leaf->items[0].key, 225e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 2261d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 2277518a238SChris Mason btrfs_header_blocknr(&leaf->header)); 228aa5d6bedSChris Mason } 2298d7be552SChris Mason if (slot != 0) { 2308d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key); 2318d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0); 2328d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot - 1) != 2338d7be552SChris Mason btrfs_item_end(leaf->items + slot)); 234aa5d6bedSChris Mason } 2358d7be552SChris Mason if (slot < nritems - 1) { 2368d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key); 2378d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0); 2388d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot) != 2398d7be552SChris Mason btrfs_item_end(leaf->items + slot + 1)); 240aa5d6bedSChris Mason } 2418d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items) + 2428d7be552SChris Mason btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root)); 243aa5d6bedSChris Mason return 0; 244aa5d6bedSChris Mason } 245aa5d6bedSChris Mason 246123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 247123abc88SChris Mason int level) 248aa5d6bedSChris Mason { 2493eb0314dSChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 2503eb0314dSChris Mason if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, 2513eb0314dSChris Mason sizeof(node->header.fsid))) 2523eb0314dSChris Mason BUG(); 253aa5d6bedSChris Mason if (level == 0) 254123abc88SChris Mason return check_leaf(root, path, level); 255123abc88SChris Mason return check_node(root, path, level); 256aa5d6bedSChris Mason } 257aa5d6bedSChris Mason 25874123bd7SChris Mason /* 25974123bd7SChris Mason * search for key in the array p. items p are item_size apart 26074123bd7SChris Mason * and there are 'max' items in p 26174123bd7SChris Mason * the slot in the array is returned via slot, and it points to 26274123bd7SChris Mason * the place where you would insert key if it is not found in 26374123bd7SChris Mason * the array. 26474123bd7SChris Mason * 26574123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 26674123bd7SChris Mason */ 2679aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, 268be0e5c09SChris Mason int max, int *slot) 269be0e5c09SChris Mason { 270be0e5c09SChris Mason int low = 0; 271be0e5c09SChris Mason int high = max; 272be0e5c09SChris Mason int mid; 273be0e5c09SChris Mason int ret; 274e2fa7227SChris Mason struct btrfs_disk_key *tmp; 275be0e5c09SChris Mason 276be0e5c09SChris Mason while(low < high) { 277be0e5c09SChris Mason mid = (low + high) / 2; 278e2fa7227SChris Mason tmp = (struct btrfs_disk_key *)(p + mid * item_size); 279be0e5c09SChris Mason ret = comp_keys(tmp, key); 280be0e5c09SChris Mason 281be0e5c09SChris Mason if (ret < 0) 282be0e5c09SChris Mason low = mid + 1; 283be0e5c09SChris Mason else if (ret > 0) 284be0e5c09SChris Mason high = mid; 285be0e5c09SChris Mason else { 286be0e5c09SChris Mason *slot = mid; 287be0e5c09SChris Mason return 0; 288be0e5c09SChris Mason } 289be0e5c09SChris Mason } 290be0e5c09SChris Mason *slot = low; 291be0e5c09SChris Mason return 1; 292be0e5c09SChris Mason } 293be0e5c09SChris Mason 29497571fd0SChris Mason /* 29597571fd0SChris Mason * simple bin_search frontend that does the right thing for 29697571fd0SChris Mason * leaves vs nodes 29797571fd0SChris Mason */ 2989aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) 299be0e5c09SChris Mason { 3007518a238SChris Mason if (btrfs_is_leaf(c)) { 301234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 3020783fcfcSChris Mason return generic_bin_search((void *)l->items, 3030783fcfcSChris Mason sizeof(struct btrfs_item), 3047518a238SChris Mason key, btrfs_header_nritems(&c->header), 3057518a238SChris Mason slot); 306be0e5c09SChris Mason } else { 307123abc88SChris Mason return generic_bin_search((void *)c->ptrs, 308123abc88SChris Mason sizeof(struct btrfs_key_ptr), 3097518a238SChris Mason key, btrfs_header_nritems(&c->header), 3107518a238SChris Mason slot); 311be0e5c09SChris Mason } 312be0e5c09SChris Mason return -1; 313be0e5c09SChris Mason } 314be0e5c09SChris Mason 315e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root, 316e20d96d6SChris Mason struct buffer_head *parent_buf, 317bb803951SChris Mason int slot) 318bb803951SChris Mason { 319e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(parent_buf); 320bb803951SChris Mason if (slot < 0) 321bb803951SChris Mason return NULL; 3227518a238SChris Mason if (slot >= btrfs_header_nritems(&node->header)) 323bb803951SChris Mason return NULL; 3241d4f8a0cSChris Mason return read_tree_block(root, btrfs_node_blockptr(node, slot)); 325bb803951SChris Mason } 326bb803951SChris Mason 327e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 328e089f05cSChris Mason *root, struct btrfs_path *path, int level) 329bb803951SChris Mason { 330e20d96d6SChris Mason struct buffer_head *right_buf; 331e20d96d6SChris Mason struct buffer_head *mid_buf; 332e20d96d6SChris Mason struct buffer_head *left_buf; 333e20d96d6SChris Mason struct buffer_head *parent_buf = NULL; 334234b63a0SChris Mason struct btrfs_node *right = NULL; 335234b63a0SChris Mason struct btrfs_node *mid; 336234b63a0SChris Mason struct btrfs_node *left = NULL; 337234b63a0SChris Mason struct btrfs_node *parent = NULL; 338bb803951SChris Mason int ret = 0; 339bb803951SChris Mason int wret; 340bb803951SChris Mason int pslot; 341bb803951SChris Mason int orig_slot = path->slots[level]; 34254aa1f4dSChris Mason int err_on_enospc = 0; 34379f95c82SChris Mason u64 orig_ptr; 344bb803951SChris Mason 345bb803951SChris Mason if (level == 0) 346bb803951SChris Mason return 0; 347bb803951SChris Mason 348bb803951SChris Mason mid_buf = path->nodes[level]; 349e20d96d6SChris Mason mid = btrfs_buffer_node(mid_buf); 3501d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 35179f95c82SChris Mason 352234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 353bb803951SChris Mason parent_buf = path->nodes[level + 1]; 354bb803951SChris Mason pslot = path->slots[level + 1]; 355bb803951SChris Mason 35640689478SChris Mason /* 35740689478SChris Mason * deal with the case where there is only one pointer in the root 35840689478SChris Mason * by promoting the node below to a root 35940689478SChris Mason */ 360bb803951SChris Mason if (!parent_buf) { 361e20d96d6SChris Mason struct buffer_head *child; 3627eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 363bb803951SChris Mason 3647518a238SChris Mason if (btrfs_header_nritems(&mid->header) != 1) 365bb803951SChris Mason return 0; 366bb803951SChris Mason 367bb803951SChris Mason /* promote the child to a root */ 368bb803951SChris Mason child = read_node_slot(root, mid_buf, 0); 369bb803951SChris Mason BUG_ON(!child); 370bb803951SChris Mason root->node = child; 371bb803951SChris Mason path->nodes[level] = NULL; 372d6025579SChris Mason clean_tree_block(trans, root, mid_buf); 373d6025579SChris Mason wait_on_buffer(mid_buf); 374bb803951SChris Mason /* once for the path */ 375234b63a0SChris Mason btrfs_block_release(root, mid_buf); 376bb803951SChris Mason /* once for the root ptr */ 377234b63a0SChris Mason btrfs_block_release(root, mid_buf); 378e089f05cSChris Mason return btrfs_free_extent(trans, root, blocknr, 1, 1); 379bb803951SChris Mason } 380e20d96d6SChris Mason parent = btrfs_buffer_node(parent_buf); 381bb803951SChris Mason 382123abc88SChris Mason if (btrfs_header_nritems(&mid->header) > 383123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 384bb803951SChris Mason return 0; 385bb803951SChris Mason 38654aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 38754aa1f4dSChris Mason err_on_enospc = 1; 38854aa1f4dSChris Mason 389bb803951SChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 390bb803951SChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 39179f95c82SChris Mason 39279f95c82SChris Mason /* first, try to make some room in the middle buffer */ 393bb803951SChris Mason if (left_buf) { 39454aa1f4dSChris Mason wret = btrfs_cow_block(trans, root, left_buf, 39554aa1f4dSChris Mason parent_buf, pslot - 1, &left_buf); 39654aa1f4dSChris Mason if (wret) { 39754aa1f4dSChris Mason ret = wret; 39854aa1f4dSChris Mason goto enospc; 39954aa1f4dSChris Mason } 400e20d96d6SChris Mason left = btrfs_buffer_node(left_buf); 4017518a238SChris Mason orig_slot += btrfs_header_nritems(&left->header); 402e089f05cSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 40379f95c82SChris Mason if (wret < 0) 40479f95c82SChris Mason ret = wret; 40554aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 40654aa1f4dSChris Mason err_on_enospc = 1; 407bb803951SChris Mason } 40879f95c82SChris Mason 40979f95c82SChris Mason /* 41079f95c82SChris Mason * then try to empty the right most buffer into the middle 41179f95c82SChris Mason */ 412bb803951SChris Mason if (right_buf) { 41354aa1f4dSChris Mason wret = btrfs_cow_block(trans, root, right_buf, 41454aa1f4dSChris Mason parent_buf, pslot + 1, &right_buf); 41554aa1f4dSChris Mason if (wret) { 41654aa1f4dSChris Mason ret = wret; 41754aa1f4dSChris Mason goto enospc; 41854aa1f4dSChris Mason } 41954aa1f4dSChris Mason 420e20d96d6SChris Mason right = btrfs_buffer_node(right_buf); 421e089f05cSChris Mason wret = push_node_left(trans, root, mid_buf, right_buf); 42254aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 42379f95c82SChris Mason ret = wret; 4247518a238SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 4257eccb903SChris Mason u64 blocknr = bh_blocknr(right_buf); 426e089f05cSChris Mason clean_tree_block(trans, root, right_buf); 427d6025579SChris Mason wait_on_buffer(right_buf); 428d6025579SChris Mason btrfs_block_release(root, right_buf); 429bb803951SChris Mason right_buf = NULL; 430bb803951SChris Mason right = NULL; 431e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 432e089f05cSChris Mason 1); 433bb803951SChris Mason if (wret) 434bb803951SChris Mason ret = wret; 435e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 436bb803951SChris Mason if (wret) 437bb803951SChris Mason ret = wret; 438bb803951SChris Mason } else { 439d6025579SChris Mason btrfs_memcpy(root, parent, 440d6025579SChris Mason &parent->ptrs[pslot + 1].key, 441123abc88SChris Mason &right->ptrs[0].key, 442e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 443d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 444bb803951SChris Mason } 445bb803951SChris Mason } 4467518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 1) { 44779f95c82SChris Mason /* 44879f95c82SChris Mason * we're not allowed to leave a node with one item in the 44979f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 45079f95c82SChris Mason * could try to delete the only pointer in this node. 45179f95c82SChris Mason * So, pull some keys from the left. 45279f95c82SChris Mason * There has to be a left pointer at this point because 45379f95c82SChris Mason * otherwise we would have pulled some pointers from the 45479f95c82SChris Mason * right 45579f95c82SChris Mason */ 45679f95c82SChris Mason BUG_ON(!left_buf); 457e089f05cSChris Mason wret = balance_node_right(trans, root, mid_buf, left_buf); 45854aa1f4dSChris Mason if (wret < 0) { 45979f95c82SChris Mason ret = wret; 46054aa1f4dSChris Mason goto enospc; 46154aa1f4dSChris Mason } 46279f95c82SChris Mason BUG_ON(wret == 1); 46379f95c82SChris Mason } 4647518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 0) { 46579f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 4667eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 467e089f05cSChris Mason clean_tree_block(trans, root, mid_buf); 468d6025579SChris Mason wait_on_buffer(mid_buf); 469d6025579SChris Mason btrfs_block_release(root, mid_buf); 470bb803951SChris Mason mid_buf = NULL; 471bb803951SChris Mason mid = NULL; 472e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 473bb803951SChris Mason if (wret) 474bb803951SChris Mason ret = wret; 475e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 476bb803951SChris Mason if (wret) 477bb803951SChris Mason ret = wret; 47879f95c82SChris Mason } else { 47979f95c82SChris Mason /* update the parent key to reflect our changes */ 480d6025579SChris Mason btrfs_memcpy(root, parent, 481d6025579SChris Mason &parent->ptrs[pslot].key, &mid->ptrs[0].key, 482e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 483d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 48479f95c82SChris Mason } 485bb803951SChris Mason 48679f95c82SChris Mason /* update the path */ 487bb803951SChris Mason if (left_buf) { 4887518a238SChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 489e20d96d6SChris Mason get_bh(left_buf); 490bb803951SChris Mason path->nodes[level] = left_buf; 491bb803951SChris Mason path->slots[level + 1] -= 1; 492bb803951SChris Mason path->slots[level] = orig_slot; 493bb803951SChris Mason if (mid_buf) 494234b63a0SChris Mason btrfs_block_release(root, mid_buf); 495bb803951SChris Mason } else { 4967518a238SChris Mason orig_slot -= btrfs_header_nritems(&left->header); 497bb803951SChris Mason path->slots[level] = orig_slot; 498bb803951SChris Mason } 499bb803951SChris Mason } 50079f95c82SChris Mason /* double check we haven't messed things up */ 501123abc88SChris Mason check_block(root, path, level); 502e20d96d6SChris Mason if (orig_ptr != 503e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 5041d4f8a0cSChris Mason path->slots[level])) 50579f95c82SChris Mason BUG(); 50654aa1f4dSChris Mason enospc: 507bb803951SChris Mason if (right_buf) 508234b63a0SChris Mason btrfs_block_release(root, right_buf); 509bb803951SChris Mason if (left_buf) 510234b63a0SChris Mason btrfs_block_release(root, left_buf); 511bb803951SChris Mason return ret; 512bb803951SChris Mason } 513bb803951SChris Mason 514e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 515e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 516e66f709bSChris Mason struct btrfs_root *root, 517e66f709bSChris Mason struct btrfs_path *path, int level) 518e66f709bSChris Mason { 519e66f709bSChris Mason struct buffer_head *right_buf; 520e66f709bSChris Mason struct buffer_head *mid_buf; 521e66f709bSChris Mason struct buffer_head *left_buf; 522e66f709bSChris Mason struct buffer_head *parent_buf = NULL; 523e66f709bSChris Mason struct btrfs_node *right = NULL; 524e66f709bSChris Mason struct btrfs_node *mid; 525e66f709bSChris Mason struct btrfs_node *left = NULL; 526e66f709bSChris Mason struct btrfs_node *parent = NULL; 527e66f709bSChris Mason int ret = 0; 528e66f709bSChris Mason int wret; 529e66f709bSChris Mason int pslot; 530e66f709bSChris Mason int orig_slot = path->slots[level]; 531e66f709bSChris Mason u64 orig_ptr; 532e66f709bSChris Mason 533e66f709bSChris Mason if (level == 0) 534e66f709bSChris Mason return 1; 535e66f709bSChris Mason 536e66f709bSChris Mason mid_buf = path->nodes[level]; 537e66f709bSChris Mason mid = btrfs_buffer_node(mid_buf); 538e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 539e66f709bSChris Mason 540e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 541e66f709bSChris Mason parent_buf = path->nodes[level + 1]; 542e66f709bSChris Mason pslot = path->slots[level + 1]; 543e66f709bSChris Mason 544e66f709bSChris Mason if (!parent_buf) 545e66f709bSChris Mason return 1; 546e66f709bSChris Mason parent = btrfs_buffer_node(parent_buf); 547e66f709bSChris Mason 548e66f709bSChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 549e66f709bSChris Mason 550e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 551e66f709bSChris Mason if (left_buf) { 552e66f709bSChris Mason u32 left_nr; 553e66f709bSChris Mason left = btrfs_buffer_node(left_buf); 554e66f709bSChris Mason left_nr = btrfs_header_nritems(&left->header); 55533ade1f8SChris Mason if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 55633ade1f8SChris Mason wret = 1; 55733ade1f8SChris Mason } else { 55854aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, left_buf, parent_buf, 55933ade1f8SChris Mason pslot - 1, &left_buf); 56054aa1f4dSChris Mason if (ret) 56154aa1f4dSChris Mason wret = 1; 56254aa1f4dSChris Mason else { 56333ade1f8SChris Mason left = btrfs_buffer_node(left_buf); 56454aa1f4dSChris Mason wret = push_node_left(trans, root, 56554aa1f4dSChris Mason left_buf, mid_buf); 56654aa1f4dSChris Mason } 56733ade1f8SChris Mason } 568e66f709bSChris Mason if (wret < 0) 569e66f709bSChris Mason ret = wret; 570e66f709bSChris Mason if (wret == 0) { 571e66f709bSChris Mason orig_slot += left_nr; 572e66f709bSChris Mason btrfs_memcpy(root, parent, 573e66f709bSChris Mason &parent->ptrs[pslot].key, 574e66f709bSChris Mason &mid->ptrs[0].key, 575e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 576e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 577e66f709bSChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 578e66f709bSChris Mason path->nodes[level] = left_buf; 579e66f709bSChris Mason path->slots[level + 1] -= 1; 580e66f709bSChris Mason path->slots[level] = orig_slot; 581e66f709bSChris Mason btrfs_block_release(root, mid_buf); 582e66f709bSChris Mason } else { 583e66f709bSChris Mason orig_slot -= 584e66f709bSChris Mason btrfs_header_nritems(&left->header); 585e66f709bSChris Mason path->slots[level] = orig_slot; 586e66f709bSChris Mason btrfs_block_release(root, left_buf); 587e66f709bSChris Mason } 588e66f709bSChris Mason check_node(root, path, level); 589e66f709bSChris Mason return 0; 590e66f709bSChris Mason } 591e66f709bSChris Mason btrfs_block_release(root, left_buf); 592e66f709bSChris Mason } 593e66f709bSChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 594e66f709bSChris Mason 595e66f709bSChris Mason /* 596e66f709bSChris Mason * then try to empty the right most buffer into the middle 597e66f709bSChris Mason */ 598e66f709bSChris Mason if (right_buf) { 59933ade1f8SChris Mason u32 right_nr; 600e66f709bSChris Mason right = btrfs_buffer_node(right_buf); 60133ade1f8SChris Mason right_nr = btrfs_header_nritems(&right->header); 60233ade1f8SChris Mason if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 60333ade1f8SChris Mason wret = 1; 60433ade1f8SChris Mason } else { 60554aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, 60654aa1f4dSChris Mason parent_buf, pslot + 1, 60754aa1f4dSChris Mason &right_buf); 60854aa1f4dSChris Mason if (ret) 60954aa1f4dSChris Mason wret = 1; 61054aa1f4dSChris Mason else { 61133ade1f8SChris Mason right = btrfs_buffer_node(right_buf); 61233ade1f8SChris Mason wret = balance_node_right(trans, root, 61333ade1f8SChris Mason right_buf, mid_buf); 61433ade1f8SChris Mason } 61554aa1f4dSChris Mason } 616e66f709bSChris Mason if (wret < 0) 617e66f709bSChris Mason ret = wret; 618e66f709bSChris Mason if (wret == 0) { 619e66f709bSChris Mason btrfs_memcpy(root, parent, 620e66f709bSChris Mason &parent->ptrs[pslot + 1].key, 621e66f709bSChris Mason &right->ptrs[0].key, 622e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 623e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 624e66f709bSChris Mason if (btrfs_header_nritems(&mid->header) <= orig_slot) { 625e66f709bSChris Mason path->nodes[level] = right_buf; 626e66f709bSChris Mason path->slots[level + 1] += 1; 627e66f709bSChris Mason path->slots[level] = orig_slot - 628e66f709bSChris Mason btrfs_header_nritems(&mid->header); 629e66f709bSChris Mason btrfs_block_release(root, mid_buf); 630e66f709bSChris Mason } else { 631e66f709bSChris Mason btrfs_block_release(root, right_buf); 632e66f709bSChris Mason } 633e66f709bSChris Mason check_node(root, path, level); 634e66f709bSChris Mason return 0; 635e66f709bSChris Mason } 636e66f709bSChris Mason btrfs_block_release(root, right_buf); 637e66f709bSChris Mason } 638e66f709bSChris Mason check_node(root, path, level); 639e66f709bSChris Mason return 1; 640e66f709bSChris Mason } 641e66f709bSChris Mason 64274123bd7SChris Mason /* 64374123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 64474123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 64574123bd7SChris Mason * level of the path (level 0) 64674123bd7SChris Mason * 64774123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 648aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 649aa5d6bedSChris Mason * search a negative error number is returned. 65097571fd0SChris Mason * 65197571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 65297571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 65397571fd0SChris Mason * possible) 65474123bd7SChris Mason */ 655e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 656e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 657e089f05cSChris Mason ins_len, int cow) 658be0e5c09SChris Mason { 659e20d96d6SChris Mason struct buffer_head *b; 660e20d96d6SChris Mason struct buffer_head *cow_buf; 661234b63a0SChris Mason struct btrfs_node *c; 662*9f3a7427SChris Mason struct btrfs_root_item *root_item = &root->root_item; 663be0e5c09SChris Mason int slot; 664be0e5c09SChris Mason int ret; 665be0e5c09SChris Mason int level; 666*9f3a7427SChris Mason u8 lowest_level = 0; 667*9f3a7427SChris Mason 668*9f3a7427SChris Mason if (btrfs_root_refs(root_item) == 0 && root->ref_cows) { 669*9f3a7427SChris Mason lowest_level = root_item->drop_level; 670*9f3a7427SChris Mason WARN_ON(ins_len || cow); 671*9f3a7427SChris Mason } 6725c680ed6SChris Mason 67322b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 67422b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 675bb803951SChris Mason again: 676bb803951SChris Mason b = root->node; 677e20d96d6SChris Mason get_bh(b); 678eb60ceacSChris Mason while (b) { 679e20d96d6SChris Mason c = btrfs_buffer_node(b); 680e20d96d6SChris Mason level = btrfs_header_level(&c->header); 68102217ed2SChris Mason if (cow) { 68202217ed2SChris Mason int wret; 683e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 684e20d96d6SChris Mason p->nodes[level + 1], 685e20d96d6SChris Mason p->slots[level + 1], 686e089f05cSChris Mason &cow_buf); 68754aa1f4dSChris Mason if (wret) { 68854aa1f4dSChris Mason btrfs_block_release(root, cow_buf); 68954aa1f4dSChris Mason return wret; 69054aa1f4dSChris Mason } 69102217ed2SChris Mason b = cow_buf; 6922c90e5d6SChris Mason c = btrfs_buffer_node(b); 69302217ed2SChris Mason } 69402217ed2SChris Mason BUG_ON(!cow && ins_len); 6952c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 6962c90e5d6SChris Mason WARN_ON(1); 6972c90e5d6SChris Mason level = btrfs_header_level(&c->header); 698eb60ceacSChris Mason p->nodes[level] = b; 699123abc88SChris Mason ret = check_block(root, p, level); 700aa5d6bedSChris Mason if (ret) 701aa5d6bedSChris Mason return -1; 702be0e5c09SChris Mason ret = bin_search(c, key, &slot); 7037518a238SChris Mason if (!btrfs_is_leaf(c)) { 704be0e5c09SChris Mason if (ret && slot > 0) 705be0e5c09SChris Mason slot -= 1; 706be0e5c09SChris Mason p->slots[level] = slot; 707d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 708d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 709e089f05cSChris Mason int sret = split_node(trans, root, p, level); 7105c680ed6SChris Mason BUG_ON(sret > 0); 7115c680ed6SChris Mason if (sret) 7125c680ed6SChris Mason return sret; 7135c680ed6SChris Mason b = p->nodes[level]; 714e20d96d6SChris Mason c = btrfs_buffer_node(b); 7155c680ed6SChris Mason slot = p->slots[level]; 716bb803951SChris Mason } else if (ins_len < 0) { 717e089f05cSChris Mason int sret = balance_level(trans, root, p, 718e089f05cSChris Mason level); 719bb803951SChris Mason if (sret) 720bb803951SChris Mason return sret; 721bb803951SChris Mason b = p->nodes[level]; 722bb803951SChris Mason if (!b) 723bb803951SChris Mason goto again; 724e20d96d6SChris Mason c = btrfs_buffer_node(b); 725bb803951SChris Mason slot = p->slots[level]; 7267518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 7275c680ed6SChris Mason } 728*9f3a7427SChris Mason /* this is only true while dropping a snapshot */ 729*9f3a7427SChris Mason if (level == lowest_level) 730*9f3a7427SChris Mason break; 7311d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 732be0e5c09SChris Mason } else { 733234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 734be0e5c09SChris Mason p->slots[level] = slot; 735123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 7360783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 737d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 738d4dbff95SChris Mason p, ins_len); 7395c680ed6SChris Mason BUG_ON(sret > 0); 7405c680ed6SChris Mason if (sret) 7415c680ed6SChris Mason return sret; 7425c680ed6SChris Mason } 743be0e5c09SChris Mason return ret; 744be0e5c09SChris Mason } 745be0e5c09SChris Mason } 746aa5d6bedSChris Mason return 1; 747be0e5c09SChris Mason } 748be0e5c09SChris Mason 74974123bd7SChris Mason /* 75074123bd7SChris Mason * adjust the pointers going up the tree, starting at level 75174123bd7SChris Mason * making sure the right key of each node is points to 'key'. 75274123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 75374123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 75474123bd7SChris Mason * higher levels 755aa5d6bedSChris Mason * 756aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 757aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 75874123bd7SChris Mason */ 759e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 760e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 761e089f05cSChris Mason *key, int level) 762be0e5c09SChris Mason { 763be0e5c09SChris Mason int i; 764aa5d6bedSChris Mason int ret = 0; 765234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 766234b63a0SChris Mason struct btrfs_node *t; 767be0e5c09SChris Mason int tslot = path->slots[i]; 768eb60ceacSChris Mason if (!path->nodes[i]) 769be0e5c09SChris Mason break; 770e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 771d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 772d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 773be0e5c09SChris Mason if (tslot != 0) 774be0e5c09SChris Mason break; 775be0e5c09SChris Mason } 776aa5d6bedSChris Mason return ret; 777be0e5c09SChris Mason } 778be0e5c09SChris Mason 77974123bd7SChris Mason /* 78074123bd7SChris Mason * try to push data from one node into the next node left in the 78179f95c82SChris Mason * tree. 782aa5d6bedSChris Mason * 783aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 784aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 78574123bd7SChris Mason */ 786e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 787e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 788e20d96d6SChris Mason buffer_head *src_buf) 789be0e5c09SChris Mason { 790e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 791e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 792be0e5c09SChris Mason int push_items = 0; 793bb803951SChris Mason int src_nritems; 794bb803951SChris Mason int dst_nritems; 795aa5d6bedSChris Mason int ret = 0; 796be0e5c09SChris Mason 7977518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7987518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 799123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 80054aa1f4dSChris Mason 801eb60ceacSChris Mason if (push_items <= 0) { 802be0e5c09SChris Mason return 1; 803eb60ceacSChris Mason } 804be0e5c09SChris Mason 805be0e5c09SChris Mason if (src_nritems < push_items) 806be0e5c09SChris Mason push_items = src_nritems; 80779f95c82SChris Mason 808d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 809123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 810bb803951SChris Mason if (push_items < src_nritems) { 811d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 812e2fa7227SChris Mason (src_nritems - push_items) * 813123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 814bb803951SChris Mason } 8157518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 8167518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 817d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 818d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 819bb803951SChris Mason return ret; 820be0e5c09SChris Mason } 821be0e5c09SChris Mason 82297571fd0SChris Mason /* 82379f95c82SChris Mason * try to push data from one node into the next node right in the 82479f95c82SChris Mason * tree. 82579f95c82SChris Mason * 82679f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 82779f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 82879f95c82SChris Mason * 82979f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 83079f95c82SChris Mason */ 831e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 832e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 833e20d96d6SChris Mason struct buffer_head *src_buf) 83479f95c82SChris Mason { 835e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 836e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 83779f95c82SChris Mason int push_items = 0; 83879f95c82SChris Mason int max_push; 83979f95c82SChris Mason int src_nritems; 84079f95c82SChris Mason int dst_nritems; 84179f95c82SChris Mason int ret = 0; 84279f95c82SChris Mason 8437518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 8447518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 845123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 84679f95c82SChris Mason if (push_items <= 0) { 84779f95c82SChris Mason return 1; 84879f95c82SChris Mason } 84979f95c82SChris Mason 85079f95c82SChris Mason max_push = src_nritems / 2 + 1; 85179f95c82SChris Mason /* don't try to empty the node */ 85279f95c82SChris Mason if (max_push > src_nritems) 85379f95c82SChris Mason return 1; 85479f95c82SChris Mason if (max_push < push_items) 85579f95c82SChris Mason push_items = max_push; 85679f95c82SChris Mason 857d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 858123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 859d6025579SChris Mason 860d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 861d6025579SChris Mason src->ptrs + src_nritems - push_items, 862123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 86379f95c82SChris Mason 8647518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 8657518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 86679f95c82SChris Mason 867d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 868d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 86979f95c82SChris Mason return ret; 87079f95c82SChris Mason } 87179f95c82SChris Mason 87279f95c82SChris Mason /* 87397571fd0SChris Mason * helper function to insert a new root level in the tree. 87497571fd0SChris Mason * A new node is allocated, and a single item is inserted to 87597571fd0SChris Mason * point to the existing root 876aa5d6bedSChris Mason * 877aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 87897571fd0SChris Mason */ 879e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 880e089f05cSChris Mason *root, struct btrfs_path *path, int level) 88174123bd7SChris Mason { 882e20d96d6SChris Mason struct buffer_head *t; 883234b63a0SChris Mason struct btrfs_node *lower; 884234b63a0SChris Mason struct btrfs_node *c; 885e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 8865c680ed6SChris Mason 8875c680ed6SChris Mason BUG_ON(path->nodes[level]); 8885c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 8895c680ed6SChris Mason 89031f3c99bSChris Mason t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr); 89154aa1f4dSChris Mason if (IS_ERR(t)) 89254aa1f4dSChris Mason return PTR_ERR(t); 893e20d96d6SChris Mason c = btrfs_buffer_node(t); 894123abc88SChris Mason memset(c, 0, root->blocksize); 8957518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 8967518a238SChris Mason btrfs_set_header_level(&c->header, level); 8977eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 8987f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 8994d775673SChris Mason btrfs_set_header_owner(&c->header, root->root_key.objectid); 900e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 9013eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 9023eb0314dSChris Mason sizeof(c->header.fsid)); 9037518a238SChris Mason if (btrfs_is_leaf(lower)) 904234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 90574123bd7SChris Mason else 906123abc88SChris Mason lower_key = &lower->ptrs[0].key; 907d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 908d6025579SChris Mason sizeof(struct btrfs_disk_key)); 9097eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 910d5719762SChris Mason 911d6025579SChris Mason btrfs_mark_buffer_dirty(t); 912d5719762SChris Mason 913cfaa7295SChris Mason /* the super has an extra ref to root->node */ 914234b63a0SChris Mason btrfs_block_release(root, root->node); 91574123bd7SChris Mason root->node = t; 916e20d96d6SChris Mason get_bh(t); 91774123bd7SChris Mason path->nodes[level] = t; 91874123bd7SChris Mason path->slots[level] = 0; 91974123bd7SChris Mason return 0; 92074123bd7SChris Mason } 9215c680ed6SChris Mason 9225c680ed6SChris Mason /* 9235c680ed6SChris Mason * worker function to insert a single pointer in a node. 9245c680ed6SChris Mason * the node should have enough room for the pointer already 92597571fd0SChris Mason * 9265c680ed6SChris Mason * slot and level indicate where you want the key to go, and 9275c680ed6SChris Mason * blocknr is the block the key points to. 928aa5d6bedSChris Mason * 929aa5d6bedSChris Mason * returns zero on success and < 0 on any error 9305c680ed6SChris Mason */ 931e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 932e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 933e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 9345c680ed6SChris Mason { 935234b63a0SChris Mason struct btrfs_node *lower; 9365c680ed6SChris Mason int nritems; 9375c680ed6SChris Mason 9385c680ed6SChris Mason BUG_ON(!path->nodes[level]); 939e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 9407518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 94174123bd7SChris Mason if (slot > nritems) 94274123bd7SChris Mason BUG(); 943123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 94474123bd7SChris Mason BUG(); 94574123bd7SChris Mason if (slot != nritems) { 946d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 947d6025579SChris Mason lower->ptrs + slot, 948123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 94974123bd7SChris Mason } 950d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 951d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 9521d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 9537518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 954d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 955098f59c2SChris Mason check_node(root, path, level); 95674123bd7SChris Mason return 0; 95774123bd7SChris Mason } 95874123bd7SChris Mason 95997571fd0SChris Mason /* 96097571fd0SChris Mason * split the node at the specified level in path in two. 96197571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 96297571fd0SChris Mason * 96397571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 96497571fd0SChris Mason * left and right, if either one works, it returns right away. 965aa5d6bedSChris Mason * 966aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 96797571fd0SChris Mason */ 968e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 969e089f05cSChris Mason *root, struct btrfs_path *path, int level) 970be0e5c09SChris Mason { 971e20d96d6SChris Mason struct buffer_head *t; 972234b63a0SChris Mason struct btrfs_node *c; 973e20d96d6SChris Mason struct buffer_head *split_buffer; 974234b63a0SChris Mason struct btrfs_node *split; 975be0e5c09SChris Mason int mid; 9765c680ed6SChris Mason int ret; 977aa5d6bedSChris Mason int wret; 9787518a238SChris Mason u32 c_nritems; 979be0e5c09SChris Mason 9805c680ed6SChris Mason t = path->nodes[level]; 981e20d96d6SChris Mason c = btrfs_buffer_node(t); 9825c680ed6SChris Mason if (t == root->node) { 9835c680ed6SChris Mason /* trying to split the root, lets make a new one */ 984e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 9855c680ed6SChris Mason if (ret) 9865c680ed6SChris Mason return ret; 987e66f709bSChris Mason } else { 988e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 989e66f709bSChris Mason t = path->nodes[level]; 990e66f709bSChris Mason c = btrfs_buffer_node(t); 991e66f709bSChris Mason if (!ret && 992e66f709bSChris Mason btrfs_header_nritems(&c->header) < 993e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 994e66f709bSChris Mason return 0; 99554aa1f4dSChris Mason if (ret < 0) 99654aa1f4dSChris Mason return ret; 9975c680ed6SChris Mason } 998e66f709bSChris Mason 9997518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 100031f3c99bSChris Mason split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr); 100154aa1f4dSChris Mason if (IS_ERR(split_buffer)) 100254aa1f4dSChris Mason return PTR_ERR(split_buffer); 100354aa1f4dSChris Mason 1004e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 10057518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 10069a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 10077eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 10087f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 10094d775673SChris Mason btrfs_set_header_owner(&split->header, root->root_key.objectid); 10103eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 10113eb0314dSChris Mason sizeof(split->header.fsid)); 10127518a238SChris Mason mid = (c_nritems + 1) / 2; 1013d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 1014123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 10157518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 10167518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 1017aa5d6bedSChris Mason ret = 0; 1018aa5d6bedSChris Mason 1019d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1020d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 1021e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 10227eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 1023123abc88SChris Mason level + 1); 1024aa5d6bedSChris Mason if (wret) 1025aa5d6bedSChris Mason ret = wret; 1026aa5d6bedSChris Mason 10275de08d7dSChris Mason if (path->slots[level] >= mid) { 10285c680ed6SChris Mason path->slots[level] -= mid; 1029234b63a0SChris Mason btrfs_block_release(root, t); 10305c680ed6SChris Mason path->nodes[level] = split_buffer; 10315c680ed6SChris Mason path->slots[level + 1] += 1; 1032eb60ceacSChris Mason } else { 1033234b63a0SChris Mason btrfs_block_release(root, split_buffer); 1034be0e5c09SChris Mason } 1035aa5d6bedSChris Mason return ret; 1036be0e5c09SChris Mason } 1037be0e5c09SChris Mason 103874123bd7SChris Mason /* 103974123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 104074123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 104174123bd7SChris Mason * space used both by the item structs and the item data 104274123bd7SChris Mason */ 1043234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 1044be0e5c09SChris Mason { 1045be0e5c09SChris Mason int data_len; 1046d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 1047d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 1048be0e5c09SChris Mason 1049be0e5c09SChris Mason if (!nr) 1050be0e5c09SChris Mason return 0; 10510783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 10520783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 10530783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 1054d4dbff95SChris Mason WARN_ON(data_len < 0); 1055be0e5c09SChris Mason return data_len; 1056be0e5c09SChris Mason } 1057be0e5c09SChris Mason 105874123bd7SChris Mason /* 1059d4dbff95SChris Mason * The space between the end of the leaf items and 1060d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 1061d4dbff95SChris Mason * the leaf has left for both items and data 1062d4dbff95SChris Mason */ 1063d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 1064d4dbff95SChris Mason { 1065d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 1066d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 1067d4dbff95SChris Mason } 1068d4dbff95SChris Mason 1069d4dbff95SChris Mason /* 107000ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 107100ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 1072aa5d6bedSChris Mason * 1073aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 1074aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 107500ec4c51SChris Mason */ 1076e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 1077e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 107800ec4c51SChris Mason { 1079e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 1080e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 1081234b63a0SChris Mason struct btrfs_leaf *right; 1082e20d96d6SChris Mason struct buffer_head *right_buf; 1083e20d96d6SChris Mason struct buffer_head *upper; 1084e20d96d6SChris Mason struct btrfs_node *upper_node; 108500ec4c51SChris Mason int slot; 108600ec4c51SChris Mason int i; 108700ec4c51SChris Mason int free_space; 108800ec4c51SChris Mason int push_space = 0; 108900ec4c51SChris Mason int push_items = 0; 10900783fcfcSChris Mason struct btrfs_item *item; 10917518a238SChris Mason u32 left_nritems; 10927518a238SChris Mason u32 right_nritems; 109354aa1f4dSChris Mason int ret; 109400ec4c51SChris Mason 109500ec4c51SChris Mason slot = path->slots[1]; 109600ec4c51SChris Mason if (!path->nodes[1]) { 109700ec4c51SChris Mason return 1; 109800ec4c51SChris Mason } 109900ec4c51SChris Mason upper = path->nodes[1]; 1100e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1101e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 110200ec4c51SChris Mason return 1; 110300ec4c51SChris Mason } 1104e20d96d6SChris Mason right_buf = read_tree_block(root, 1105e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 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); 111000ec4c51SChris Mason return 1; 111100ec4c51SChris Mason } 111202217ed2SChris Mason /* cow and double check */ 111354aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, upper, 111454aa1f4dSChris Mason slot + 1, &right_buf); 111554aa1f4dSChris Mason if (ret) { 111654aa1f4dSChris Mason btrfs_block_release(root, right_buf); 111754aa1f4dSChris Mason return 1; 111854aa1f4dSChris Mason } 1119e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1120123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 11210783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1122234b63a0SChris Mason btrfs_block_release(root, right_buf); 112302217ed2SChris Mason return 1; 112402217ed2SChris Mason } 112502217ed2SChris Mason 11267518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1127a429e513SChris Mason if (left_nritems == 0) { 1128a429e513SChris Mason btrfs_block_release(root, right_buf); 1129a429e513SChris Mason return 1; 1130a429e513SChris Mason } 1131a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 113200ec4c51SChris Mason item = left->items + i; 113300ec4c51SChris Mason if (path->slots[0] == i) 113400ec4c51SChris Mason push_space += data_size + sizeof(*item); 11350783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 11360783fcfcSChris Mason free_space) 113700ec4c51SChris Mason break; 113800ec4c51SChris Mason push_items++; 11390783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 114000ec4c51SChris Mason } 114100ec4c51SChris Mason if (push_items == 0) { 1142234b63a0SChris Mason btrfs_block_release(root, right_buf); 114300ec4c51SChris Mason return 1; 114400ec4c51SChris Mason } 1145a429e513SChris Mason if (push_items == left_nritems) 1146a429e513SChris Mason WARN_ON(1); 11477518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 114800ec4c51SChris Mason /* push left to right */ 11490783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1150123abc88SChris Mason push_space -= leaf_data_end(root, left); 115100ec4c51SChris Mason /* make room in the right data area */ 1152d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1153d6025579SChris Mason leaf_data_end(root, right) - push_space, 1154d6025579SChris Mason btrfs_leaf_data(right) + 1155d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1156d6025579SChris Mason leaf_data_end(root, right)); 115700ec4c51SChris Mason /* copy from the left data area */ 1158d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1159d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1160d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1161d6025579SChris Mason push_space); 1162d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 11630783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 116400ec4c51SChris Mason /* copy the items from left to right */ 1165d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1166d6025579SChris Mason left_nritems - push_items, 11670783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 116800ec4c51SChris Mason 116900ec4c51SChris Mason /* update the item pointers */ 11707518a238SChris Mason right_nritems += push_items; 11717518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1172123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 11737518a238SChris Mason for (i = 0; i < right_nritems; i++) { 11740783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 11750783fcfcSChris Mason btrfs_item_size(right->items + i)); 11760783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 117700ec4c51SChris Mason } 11787518a238SChris Mason left_nritems -= push_items; 11797518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 118000ec4c51SChris Mason 1181d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1182d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1183a429e513SChris Mason 1184d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1185e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1186d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 118702217ed2SChris Mason 118800ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 11897518a238SChris Mason if (path->slots[0] >= left_nritems) { 11907518a238SChris Mason path->slots[0] -= left_nritems; 1191234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 119200ec4c51SChris Mason path->nodes[0] = right_buf; 119300ec4c51SChris Mason path->slots[1] += 1; 119400ec4c51SChris Mason } else { 1195234b63a0SChris Mason btrfs_block_release(root, right_buf); 119600ec4c51SChris Mason } 1197098f59c2SChris Mason if (path->nodes[1]) 1198098f59c2SChris Mason check_node(root, path, 1); 119900ec4c51SChris Mason return 0; 120000ec4c51SChris Mason } 120100ec4c51SChris Mason /* 120274123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 120374123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 120474123bd7SChris Mason */ 1205e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1206e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1207be0e5c09SChris Mason { 1208e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1209e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1210e20d96d6SChris Mason struct buffer_head *t; 1211234b63a0SChris Mason struct btrfs_leaf *left; 1212be0e5c09SChris Mason int slot; 1213be0e5c09SChris Mason int i; 1214be0e5c09SChris Mason int free_space; 1215be0e5c09SChris Mason int push_space = 0; 1216be0e5c09SChris Mason int push_items = 0; 12170783fcfcSChris Mason struct btrfs_item *item; 12187518a238SChris Mason u32 old_left_nritems; 1219aa5d6bedSChris Mason int ret = 0; 1220aa5d6bedSChris Mason int wret; 1221be0e5c09SChris Mason 1222be0e5c09SChris Mason slot = path->slots[1]; 1223be0e5c09SChris Mason if (slot == 0) { 1224be0e5c09SChris Mason return 1; 1225be0e5c09SChris Mason } 1226be0e5c09SChris Mason if (!path->nodes[1]) { 1227be0e5c09SChris Mason return 1; 1228be0e5c09SChris Mason } 1229e20d96d6SChris Mason t = read_tree_block(root, 1230e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 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); 1235be0e5c09SChris Mason return 1; 1236be0e5c09SChris Mason } 123702217ed2SChris Mason 123802217ed2SChris Mason /* cow and double check */ 123954aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 124054aa1f4dSChris Mason if (ret) { 124154aa1f4dSChris Mason /* we hit -ENOSPC, but it isn't fatal here */ 124254aa1f4dSChris Mason return 1; 124354aa1f4dSChris Mason } 1244e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1245123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 12460783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1247234b63a0SChris Mason btrfs_block_release(root, t); 124802217ed2SChris Mason return 1; 124902217ed2SChris Mason } 125002217ed2SChris Mason 1251a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1252a429e513SChris Mason btrfs_block_release(root, t); 1253a429e513SChris Mason return 1; 1254a429e513SChris Mason } 1255a429e513SChris Mason 1256a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1257be0e5c09SChris Mason item = right->items + i; 1258be0e5c09SChris Mason if (path->slots[0] == i) 1259be0e5c09SChris Mason push_space += data_size + sizeof(*item); 12600783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 12610783fcfcSChris Mason free_space) 1262be0e5c09SChris Mason break; 1263be0e5c09SChris Mason push_items++; 12640783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1265be0e5c09SChris Mason } 1266be0e5c09SChris Mason if (push_items == 0) { 1267234b63a0SChris Mason btrfs_block_release(root, t); 1268be0e5c09SChris Mason return 1; 1269be0e5c09SChris Mason } 1270a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1271a429e513SChris Mason WARN_ON(1); 1272be0e5c09SChris Mason /* push data from right to left */ 1273d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1274d6025579SChris Mason btrfs_header_nritems(&left->header), 12750783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1276123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 12770783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1278d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1279d6025579SChris Mason leaf_data_end(root, left) - push_space, 1280123abc88SChris Mason btrfs_leaf_data(right) + 1281123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1282be0e5c09SChris Mason push_space); 12837518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1284eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1285eb60ceacSChris Mason 1286be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1287123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1288123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1289123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 12900783fcfcSChris Mason btrfs_item_offset(left->items + 12910783fcfcSChris Mason old_left_nritems - 1))); 1292be0e5c09SChris Mason } 12937518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1294be0e5c09SChris Mason 1295be0e5c09SChris Mason /* fixup right node */ 12960783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1297123abc88SChris Mason leaf_data_end(root, right); 1298d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1299d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1300d6025579SChris Mason btrfs_leaf_data(right) + 1301123abc88SChris Mason leaf_data_end(root, right), push_space); 1302d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 13037518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 13040783fcfcSChris Mason sizeof(struct btrfs_item)); 13057518a238SChris Mason btrfs_set_header_nritems(&right->header, 13067518a238SChris Mason btrfs_header_nritems(&right->header) - 13077518a238SChris Mason push_items); 1308123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1309eb60ceacSChris Mason 13107518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 13110783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 13120783fcfcSChris Mason btrfs_item_size(right->items + i)); 13130783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1314be0e5c09SChris Mason } 1315eb60ceacSChris Mason 1316d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1317d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1318098f59c2SChris Mason 1319e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1320aa5d6bedSChris Mason if (wret) 1321aa5d6bedSChris Mason ret = wret; 1322be0e5c09SChris Mason 1323be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1324be0e5c09SChris Mason if (path->slots[0] < push_items) { 1325be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1326234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1327eb60ceacSChris Mason path->nodes[0] = t; 1328be0e5c09SChris Mason path->slots[1] -= 1; 1329be0e5c09SChris Mason } else { 1330234b63a0SChris Mason btrfs_block_release(root, t); 1331be0e5c09SChris Mason path->slots[0] -= push_items; 1332be0e5c09SChris Mason } 1333eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1334098f59c2SChris Mason if (path->nodes[1]) 1335098f59c2SChris Mason check_node(root, path, 1); 1336aa5d6bedSChris Mason return ret; 1337be0e5c09SChris Mason } 1338be0e5c09SChris Mason 133974123bd7SChris Mason /* 134074123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 134174123bd7SChris Mason * available for the resulting leaf level of the path. 1342aa5d6bedSChris Mason * 1343aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 134474123bd7SChris Mason */ 1345e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1346d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1347d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1348be0e5c09SChris Mason { 1349e20d96d6SChris Mason struct buffer_head *l_buf; 1350234b63a0SChris Mason struct btrfs_leaf *l; 13517518a238SChris Mason u32 nritems; 1352eb60ceacSChris Mason int mid; 1353eb60ceacSChris Mason int slot; 1354234b63a0SChris Mason struct btrfs_leaf *right; 1355e20d96d6SChris Mason struct buffer_head *right_buffer; 13560783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1357be0e5c09SChris Mason int data_copy_size; 1358be0e5c09SChris Mason int rt_data_off; 1359be0e5c09SChris Mason int i; 1360d4dbff95SChris Mason int ret = 0; 1361aa5d6bedSChris Mason int wret; 1362d4dbff95SChris Mason int double_split = 0; 1363d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1364be0e5c09SChris Mason 136540689478SChris Mason /* first try to make some room by pushing left and right */ 1366e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1367eaee50e8SChris Mason if (wret < 0) 1368eaee50e8SChris Mason return wret; 1369eaee50e8SChris Mason if (wret) { 1370e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1371eaee50e8SChris Mason if (wret < 0) 1372eaee50e8SChris Mason return wret; 1373eaee50e8SChris Mason } 1374eb60ceacSChris Mason l_buf = path->nodes[0]; 1375e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1376aa5d6bedSChris Mason 1377aa5d6bedSChris Mason /* did the pushes work? */ 1378123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1379123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1380be0e5c09SChris Mason return 0; 1381aa5d6bedSChris Mason 13825c680ed6SChris Mason if (!path->nodes[1]) { 1383e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 13845c680ed6SChris Mason if (ret) 13855c680ed6SChris Mason return ret; 13865c680ed6SChris Mason } 1387eb60ceacSChris Mason slot = path->slots[0]; 13887518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1389eb60ceacSChris Mason mid = (nritems + 1)/ 2; 139054aa1f4dSChris Mason 139131f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 139254aa1f4dSChris Mason if (IS_ERR(right_buffer)) 139354aa1f4dSChris Mason return PTR_ERR(right_buffer); 139454aa1f4dSChris Mason 1395e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1396123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 13977eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 13987f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 13994d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 14007518a238SChris Mason btrfs_set_header_level(&right->header, 0); 14013eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 14023eb0314dSChris Mason sizeof(right->header.fsid)); 1403d4dbff95SChris Mason if (mid <= slot) { 1404d4dbff95SChris Mason if (nritems == 1 || 1405d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1406d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1407d4dbff95SChris Mason if (slot >= nritems) { 1408d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1409d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1410d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1411d4dbff95SChris Mason &disk_key, 14127eccb903SChris Mason bh_blocknr(right_buffer), 1413d4dbff95SChris Mason path->slots[1] + 1, 1); 1414d4dbff95SChris Mason if (wret) 1415d4dbff95SChris Mason ret = wret; 1416d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1417d4dbff95SChris Mason path->nodes[0] = right_buffer; 1418d4dbff95SChris Mason path->slots[0] = 0; 1419d4dbff95SChris Mason path->slots[1] += 1; 1420d4dbff95SChris Mason return ret; 1421d4dbff95SChris Mason } 1422d4dbff95SChris Mason mid = slot; 1423d4dbff95SChris Mason double_split = 1; 1424d4dbff95SChris Mason } 1425d4dbff95SChris Mason } else { 1426d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1427d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1428d4dbff95SChris Mason if (slot == 0) { 1429d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1430d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1431d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1432d4dbff95SChris Mason &disk_key, 14337eccb903SChris Mason bh_blocknr(right_buffer), 1434098f59c2SChris Mason path->slots[1], 1); 1435d4dbff95SChris Mason if (wret) 1436d4dbff95SChris Mason ret = wret; 1437d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1438d4dbff95SChris Mason path->nodes[0] = right_buffer; 1439d4dbff95SChris Mason path->slots[0] = 0; 1440a429e513SChris Mason if (path->slots[1] == 0) { 1441a429e513SChris Mason wret = fixup_low_keys(trans, root, 1442a429e513SChris Mason path, &disk_key, 1); 1443a429e513SChris Mason if (wret) 1444a429e513SChris Mason ret = wret; 1445a429e513SChris Mason } 1446d4dbff95SChris Mason return ret; 1447d4dbff95SChris Mason } 1448d4dbff95SChris Mason mid = slot; 1449d4dbff95SChris Mason double_split = 1; 1450d4dbff95SChris Mason } 1451d4dbff95SChris Mason } 1452d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1453123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1454123abc88SChris Mason leaf_data_end(root, l); 1455d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 14560783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1457d6025579SChris Mason btrfs_memcpy(root, right, 1458d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1459123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1460123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1461123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1462123abc88SChris Mason btrfs_item_end(l->items + mid); 146374123bd7SChris Mason 14640783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1465123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 14660783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 14670783fcfcSChris Mason } 146874123bd7SChris Mason 14697518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1470aa5d6bedSChris Mason ret = 0; 1471e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 14727eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1473aa5d6bedSChris Mason if (wret) 1474aa5d6bedSChris Mason ret = wret; 1475d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1476d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1477eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1478be0e5c09SChris Mason if (mid <= slot) { 1479234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1480eb60ceacSChris Mason path->nodes[0] = right_buffer; 1481be0e5c09SChris Mason path->slots[0] -= mid; 1482be0e5c09SChris Mason path->slots[1] += 1; 1483eb60ceacSChris Mason } else 1484234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1485eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1486098f59c2SChris Mason check_node(root, path, 1); 1487d4dbff95SChris Mason 1488d4dbff95SChris Mason if (!double_split) 1489d4dbff95SChris Mason return ret; 149031f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 149154aa1f4dSChris Mason if (IS_ERR(right_buffer)) 149254aa1f4dSChris Mason return PTR_ERR(right_buffer); 149354aa1f4dSChris Mason 1494d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1495d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 14967eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1497d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 14984d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 1499d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 15003eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 15013eb0314dSChris Mason sizeof(right->header.fsid)); 1502d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1503d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1504d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1505d4dbff95SChris Mason &disk_key, 15067eccb903SChris Mason bh_blocknr(right_buffer), 1507d4dbff95SChris Mason path->slots[1], 1); 1508d4dbff95SChris Mason if (wret) 1509d4dbff95SChris Mason ret = wret; 1510a429e513SChris Mason if (path->slots[1] == 0) { 1511a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1512a429e513SChris Mason if (wret) 1513a429e513SChris Mason ret = wret; 1514a429e513SChris Mason } 1515d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1516d4dbff95SChris Mason path->nodes[0] = right_buffer; 1517d4dbff95SChris Mason path->slots[0] = 0; 1518d4dbff95SChris Mason check_node(root, path, 1); 1519d4dbff95SChris Mason check_leaf(root, path, 0); 1520be0e5c09SChris Mason return ret; 1521be0e5c09SChris Mason } 1522be0e5c09SChris Mason 1523b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1524b18c6685SChris Mason struct btrfs_root *root, 1525b18c6685SChris Mason struct btrfs_path *path, 1526b18c6685SChris Mason u32 new_size) 1527b18c6685SChris Mason { 1528b18c6685SChris Mason int ret = 0; 1529b18c6685SChris Mason int slot; 1530b18c6685SChris Mason int slot_orig; 1531b18c6685SChris Mason struct btrfs_leaf *leaf; 1532b18c6685SChris Mason struct buffer_head *leaf_buf; 1533b18c6685SChris Mason u32 nritems; 1534b18c6685SChris Mason unsigned int data_end; 1535b18c6685SChris Mason unsigned int old_data_start; 1536b18c6685SChris Mason unsigned int old_size; 1537b18c6685SChris Mason unsigned int size_diff; 1538b18c6685SChris Mason int i; 1539b18c6685SChris Mason 1540b18c6685SChris Mason slot_orig = path->slots[0]; 1541b18c6685SChris Mason leaf_buf = path->nodes[0]; 1542b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1543b18c6685SChris Mason 1544b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1545b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1546b18c6685SChris Mason 1547b18c6685SChris Mason slot = path->slots[0]; 1548b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1549b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1550b18c6685SChris Mason BUG_ON(old_size <= new_size); 1551b18c6685SChris Mason size_diff = old_size - new_size; 1552b18c6685SChris Mason 1553b18c6685SChris Mason BUG_ON(slot < 0); 1554b18c6685SChris Mason BUG_ON(slot >= nritems); 1555b18c6685SChris Mason 1556b18c6685SChris Mason /* 1557b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1558b18c6685SChris Mason */ 1559b18c6685SChris Mason /* first correct the data pointers */ 1560b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1561b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1562b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1563b18c6685SChris Mason ioff + size_diff); 1564b18c6685SChris Mason } 1565b18c6685SChris Mason /* shift the data */ 1566b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1567b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1568b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1569b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1570b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1571b18c6685SChris Mason 1572b18c6685SChris Mason ret = 0; 1573b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1574b18c6685SChris Mason BUG(); 1575b18c6685SChris Mason check_leaf(root, path, 0); 1576b18c6685SChris Mason return ret; 1577b18c6685SChris Mason } 1578b18c6685SChris Mason 15796567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 15806567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 15816567e837SChris Mason { 15826567e837SChris Mason int ret = 0; 15836567e837SChris Mason int slot; 15846567e837SChris Mason int slot_orig; 15856567e837SChris Mason struct btrfs_leaf *leaf; 15866567e837SChris Mason struct buffer_head *leaf_buf; 15876567e837SChris Mason u32 nritems; 15886567e837SChris Mason unsigned int data_end; 15896567e837SChris Mason unsigned int old_data; 15906567e837SChris Mason unsigned int old_size; 15916567e837SChris Mason int i; 15926567e837SChris Mason 15936567e837SChris Mason slot_orig = path->slots[0]; 15946567e837SChris Mason leaf_buf = path->nodes[0]; 15956567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 15966567e837SChris Mason 15976567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 15986567e837SChris Mason data_end = leaf_data_end(root, leaf); 15996567e837SChris Mason 16006567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 16016567e837SChris Mason BUG(); 16026567e837SChris Mason slot = path->slots[0]; 16036567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 16046567e837SChris Mason 16056567e837SChris Mason BUG_ON(slot < 0); 16066567e837SChris Mason BUG_ON(slot >= nritems); 16076567e837SChris Mason 16086567e837SChris Mason /* 16096567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 16106567e837SChris Mason */ 16116567e837SChris Mason /* first correct the data pointers */ 16126567e837SChris Mason for (i = slot; i < nritems; i++) { 16136567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 16146567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 16156567e837SChris Mason ioff - data_size); 16166567e837SChris Mason } 16176567e837SChris Mason /* shift the data */ 16186567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 16196567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 16206567e837SChris Mason data_end, old_data - data_end); 16216567e837SChris Mason data_end = old_data; 16226567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 16236567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 16246567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 16256567e837SChris Mason 16266567e837SChris Mason ret = 0; 16276567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 16286567e837SChris Mason BUG(); 16296567e837SChris Mason check_leaf(root, path, 0); 16306567e837SChris Mason return ret; 16316567e837SChris Mason } 16326567e837SChris Mason 163374123bd7SChris Mason /* 163474123bd7SChris Mason * Given a key and some data, insert an item into the tree. 163574123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 163674123bd7SChris Mason */ 1637e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1638e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1639e089f05cSChris Mason *cpu_key, u32 data_size) 1640be0e5c09SChris Mason { 1641aa5d6bedSChris Mason int ret = 0; 1642be0e5c09SChris Mason int slot; 1643eb60ceacSChris Mason int slot_orig; 1644234b63a0SChris Mason struct btrfs_leaf *leaf; 1645e20d96d6SChris Mason struct buffer_head *leaf_buf; 16467518a238SChris Mason u32 nritems; 1647be0e5c09SChris Mason unsigned int data_end; 1648e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1649e2fa7227SChris Mason 1650e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1651be0e5c09SChris Mason 165274123bd7SChris Mason /* create a root if there isn't one */ 16535c680ed6SChris Mason if (!root->node) 1654cfaa7295SChris Mason BUG(); 1655e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1656eb60ceacSChris Mason if (ret == 0) { 1657f0930a37SChris Mason return -EEXIST; 1658aa5d6bedSChris Mason } 1659ed2ff2cbSChris Mason if (ret < 0) 1660ed2ff2cbSChris Mason goto out; 1661be0e5c09SChris Mason 166262e2749eSChris Mason slot_orig = path->slots[0]; 166362e2749eSChris Mason leaf_buf = path->nodes[0]; 1664e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 166574123bd7SChris Mason 16667518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1667123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1668eb60ceacSChris Mason 1669123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1670d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1671be0e5c09SChris Mason BUG(); 1672d4dbff95SChris Mason } 167362e2749eSChris Mason slot = path->slots[0]; 1674eb60ceacSChris Mason BUG_ON(slot < 0); 1675be0e5c09SChris Mason if (slot != nritems) { 1676be0e5c09SChris Mason int i; 16770783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1678be0e5c09SChris Mason 1679be0e5c09SChris Mason /* 1680be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1681be0e5c09SChris Mason */ 1682be0e5c09SChris Mason /* first correct the data pointers */ 16830783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1684123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 16850783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 16860783fcfcSChris Mason ioff - data_size); 16870783fcfcSChris Mason } 1688be0e5c09SChris Mason 1689be0e5c09SChris Mason /* shift the items */ 1690d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1691d6025579SChris Mason leaf->items + slot, 16920783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1693be0e5c09SChris Mason 1694be0e5c09SChris Mason /* shift the data */ 1695d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1696d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1697be0e5c09SChris Mason data_end, old_data - data_end); 1698be0e5c09SChris Mason data_end = old_data; 1699be0e5c09SChris Mason } 170062e2749eSChris Mason /* setup the item for the new data */ 1701d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1702e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 17030783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 17040783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 17057518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1706d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1707aa5d6bedSChris Mason 1708aa5d6bedSChris Mason ret = 0; 17098e19f2cdSChris Mason if (slot == 0) 1710e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1711aa5d6bedSChris Mason 1712123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1713be0e5c09SChris Mason BUG(); 171462e2749eSChris Mason check_leaf(root, path, 0); 1715ed2ff2cbSChris Mason out: 171662e2749eSChris Mason return ret; 171762e2749eSChris Mason } 171862e2749eSChris Mason 171962e2749eSChris Mason /* 172062e2749eSChris Mason * Given a key and some data, insert an item into the tree. 172162e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 172262e2749eSChris Mason */ 1723e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1724e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1725e089f05cSChris Mason data_size) 172662e2749eSChris Mason { 172762e2749eSChris Mason int ret = 0; 17282c90e5d6SChris Mason struct btrfs_path *path; 172962e2749eSChris Mason u8 *ptr; 173062e2749eSChris Mason 17312c90e5d6SChris Mason path = btrfs_alloc_path(); 17322c90e5d6SChris Mason BUG_ON(!path); 17332c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 173462e2749eSChris Mason if (!ret) { 17352c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 17362c90e5d6SChris Mason path->slots[0], u8); 17372c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1738d6025579SChris Mason ptr, data, data_size); 17392c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 174062e2749eSChris Mason } 17412c90e5d6SChris Mason btrfs_free_path(path); 1742aa5d6bedSChris Mason return ret; 1743be0e5c09SChris Mason } 1744be0e5c09SChris Mason 174574123bd7SChris Mason /* 17465de08d7dSChris Mason * delete the pointer from a given node. 174774123bd7SChris Mason * 174874123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 174974123bd7SChris Mason * continuing all the way the root if required. The root is converted into 175074123bd7SChris Mason * a leaf if all the nodes are emptied. 175174123bd7SChris Mason */ 1752e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1753e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1754be0e5c09SChris Mason { 1755234b63a0SChris Mason struct btrfs_node *node; 1756e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 17577518a238SChris Mason u32 nritems; 1758aa5d6bedSChris Mason int ret = 0; 1759bb803951SChris Mason int wret; 1760be0e5c09SChris Mason 1761e20d96d6SChris Mason node = btrfs_buffer_node(parent); 17627518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1763be0e5c09SChris Mason if (slot != nritems -1) { 1764d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1765d6025579SChris Mason node->ptrs + slot + 1, 1766d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1767d6025579SChris Mason (nritems - slot - 1)); 1768be0e5c09SChris Mason } 17697518a238SChris Mason nritems--; 17707518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 17717518a238SChris Mason if (nritems == 0 && parent == root->node) { 1772e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1773e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1774eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1775e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1776bb803951SChris Mason } else if (slot == 0) { 1777e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1778123abc88SChris Mason level + 1); 17790f70abe2SChris Mason if (wret) 17800f70abe2SChris Mason ret = wret; 1781be0e5c09SChris Mason } 1782d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1783aa5d6bedSChris Mason return ret; 1784be0e5c09SChris Mason } 1785be0e5c09SChris Mason 178674123bd7SChris Mason /* 178774123bd7SChris Mason * delete the item at the leaf level in path. If that empties 178874123bd7SChris Mason * the leaf, remove it from the tree 178974123bd7SChris Mason */ 1790e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1791e089f05cSChris Mason struct btrfs_path *path) 1792be0e5c09SChris Mason { 1793be0e5c09SChris Mason int slot; 1794234b63a0SChris Mason struct btrfs_leaf *leaf; 1795e20d96d6SChris Mason struct buffer_head *leaf_buf; 1796be0e5c09SChris Mason int doff; 1797be0e5c09SChris Mason int dsize; 1798aa5d6bedSChris Mason int ret = 0; 1799aa5d6bedSChris Mason int wret; 18007518a238SChris Mason u32 nritems; 1801be0e5c09SChris Mason 1802eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1803e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 18044920c9acSChris Mason slot = path->slots[0]; 18050783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 18060783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 18077518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1808be0e5c09SChris Mason 18097518a238SChris Mason if (slot != nritems - 1) { 1810be0e5c09SChris Mason int i; 1811123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 1812d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1813d6025579SChris Mason data_end + dsize, 1814123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 1815be0e5c09SChris Mason doff - data_end); 18160783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 1817123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 18180783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 18190783fcfcSChris Mason } 1820d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 1821d6025579SChris Mason leaf->items + slot + 1, 18220783fcfcSChris Mason sizeof(struct btrfs_item) * 18237518a238SChris Mason (nritems - slot - 1)); 1824be0e5c09SChris Mason } 18257518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 18267518a238SChris Mason nritems--; 182774123bd7SChris Mason /* delete the leaf if we've emptied it */ 18287518a238SChris Mason if (nritems == 0) { 1829eb60ceacSChris Mason if (leaf_buf == root->node) { 18307518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 18319a8dd150SChris Mason } else { 1832e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1833d6025579SChris Mason wait_on_buffer(leaf_buf); 1834e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 1835aa5d6bedSChris Mason if (wret) 1836aa5d6bedSChris Mason ret = wret; 1837e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 18387eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 18390f70abe2SChris Mason if (wret) 18400f70abe2SChris Mason ret = wret; 18419a8dd150SChris Mason } 1842be0e5c09SChris Mason } else { 18437518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 1844aa5d6bedSChris Mason if (slot == 0) { 1845e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 1846aa5d6bedSChris Mason &leaf->items[0].key, 1); 1847aa5d6bedSChris Mason if (wret) 1848aa5d6bedSChris Mason ret = wret; 1849aa5d6bedSChris Mason } 1850aa5d6bedSChris Mason 185174123bd7SChris Mason /* delete the leaf if it is mostly empty */ 1852123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1853be0e5c09SChris Mason /* push_leaf_left fixes the path. 1854be0e5c09SChris Mason * make sure the path still points to our leaf 1855be0e5c09SChris Mason * for possible call to del_ptr below 1856be0e5c09SChris Mason */ 18574920c9acSChris Mason slot = path->slots[1]; 1858e20d96d6SChris Mason get_bh(leaf_buf); 1859e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 186054aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 1861aa5d6bedSChris Mason ret = wret; 1862f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 18637518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 1864e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 186554aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 1866aa5d6bedSChris Mason ret = wret; 1867aa5d6bedSChris Mason } 18687518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 18697eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 1870e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1871d6025579SChris Mason wait_on_buffer(leaf_buf); 1872e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 1873aa5d6bedSChris Mason if (wret) 1874aa5d6bedSChris Mason ret = wret; 1875234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1876e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1877e089f05cSChris Mason 1, 1); 18780f70abe2SChris Mason if (wret) 18790f70abe2SChris Mason ret = wret; 18805de08d7dSChris Mason } else { 1881d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1882234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1883be0e5c09SChris Mason } 1884d5719762SChris Mason } else { 1885d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1886be0e5c09SChris Mason } 18879a8dd150SChris Mason } 1888aa5d6bedSChris Mason return ret; 18899a8dd150SChris Mason } 18909a8dd150SChris Mason 189197571fd0SChris Mason /* 189297571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 18930f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 18940f70abe2SChris Mason * returns < 0 on io errors. 189597571fd0SChris Mason */ 1896234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 1897d97e63b6SChris Mason { 1898d97e63b6SChris Mason int slot; 1899d97e63b6SChris Mason int level = 1; 1900d97e63b6SChris Mason u64 blocknr; 1901e20d96d6SChris Mason struct buffer_head *c; 1902e20d96d6SChris Mason struct btrfs_node *c_node; 1903e20d96d6SChris Mason struct buffer_head *next = NULL; 1904d97e63b6SChris Mason 1905234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 1906d97e63b6SChris Mason if (!path->nodes[level]) 19070f70abe2SChris Mason return 1; 1908d97e63b6SChris Mason slot = path->slots[level] + 1; 1909d97e63b6SChris Mason c = path->nodes[level]; 1910e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 1911e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 1912d97e63b6SChris Mason level++; 1913d97e63b6SChris Mason continue; 1914d97e63b6SChris Mason } 1915e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 1916cfaa7295SChris Mason if (next) 1917234b63a0SChris Mason btrfs_block_release(root, next); 1918d97e63b6SChris Mason next = read_tree_block(root, blocknr); 1919d97e63b6SChris Mason break; 1920d97e63b6SChris Mason } 1921d97e63b6SChris Mason path->slots[level] = slot; 1922d97e63b6SChris Mason while(1) { 1923d97e63b6SChris Mason level--; 1924d97e63b6SChris Mason c = path->nodes[level]; 1925234b63a0SChris Mason btrfs_block_release(root, c); 1926d97e63b6SChris Mason path->nodes[level] = next; 1927d97e63b6SChris Mason path->slots[level] = 0; 1928d97e63b6SChris Mason if (!level) 1929d97e63b6SChris Mason break; 19301d4f8a0cSChris Mason next = read_tree_block(root, 1931e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 1932d97e63b6SChris Mason } 1933d97e63b6SChris Mason return 0; 1934d97e63b6SChris Mason } 1935