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]); 175*a1f39630SAneesh 1768d7be552SChris Mason slot = path->slots[level]; 1777518a238SChris Mason BUG_ON(nritems == 0); 1787518a238SChris Mason if (parent) { 179e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 180*a1f39630SAneesh 181*a1f39630SAneesh 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]); 213*a1f39630SAneesh 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; 221*a1f39630SAneesh 222*a1f39630SAneesh 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; 662be0e5c09SChris Mason int slot; 663be0e5c09SChris Mason int ret; 664be0e5c09SChris Mason int level; 6655c680ed6SChris Mason 66622b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 66722b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 668bb803951SChris Mason again: 669bb803951SChris Mason b = root->node; 670e20d96d6SChris Mason get_bh(b); 671eb60ceacSChris Mason while (b) { 672e20d96d6SChris Mason c = btrfs_buffer_node(b); 673e20d96d6SChris Mason level = btrfs_header_level(&c->header); 67402217ed2SChris Mason if (cow) { 67502217ed2SChris Mason int wret; 676e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 677e20d96d6SChris Mason p->nodes[level + 1], 678e20d96d6SChris Mason p->slots[level + 1], 679e089f05cSChris Mason &cow_buf); 68054aa1f4dSChris Mason if (wret) { 68154aa1f4dSChris Mason btrfs_block_release(root, cow_buf); 68254aa1f4dSChris Mason return wret; 68354aa1f4dSChris Mason } 68402217ed2SChris Mason b = cow_buf; 6852c90e5d6SChris Mason c = btrfs_buffer_node(b); 68602217ed2SChris Mason } 68702217ed2SChris Mason BUG_ON(!cow && ins_len); 6882c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 6892c90e5d6SChris Mason WARN_ON(1); 6902c90e5d6SChris Mason level = btrfs_header_level(&c->header); 691eb60ceacSChris Mason p->nodes[level] = b; 692123abc88SChris Mason ret = check_block(root, p, level); 693aa5d6bedSChris Mason if (ret) 694aa5d6bedSChris Mason return -1; 695be0e5c09SChris Mason ret = bin_search(c, key, &slot); 6967518a238SChris Mason if (!btrfs_is_leaf(c)) { 697be0e5c09SChris Mason if (ret && slot > 0) 698be0e5c09SChris Mason slot -= 1; 699be0e5c09SChris Mason p->slots[level] = slot; 700d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 701d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 702e089f05cSChris Mason int sret = split_node(trans, root, p, level); 7035c680ed6SChris Mason BUG_ON(sret > 0); 7045c680ed6SChris Mason if (sret) 7055c680ed6SChris Mason return sret; 7065c680ed6SChris Mason b = p->nodes[level]; 707e20d96d6SChris Mason c = btrfs_buffer_node(b); 7085c680ed6SChris Mason slot = p->slots[level]; 709bb803951SChris Mason } else if (ins_len < 0) { 710e089f05cSChris Mason int sret = balance_level(trans, root, p, 711e089f05cSChris Mason level); 712bb803951SChris Mason if (sret) 713bb803951SChris Mason return sret; 714bb803951SChris Mason b = p->nodes[level]; 715bb803951SChris Mason if (!b) 716bb803951SChris Mason goto again; 717e20d96d6SChris Mason c = btrfs_buffer_node(b); 718bb803951SChris Mason slot = p->slots[level]; 7197518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 7205c680ed6SChris Mason } 7211d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 722be0e5c09SChris Mason } else { 723234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 724be0e5c09SChris Mason p->slots[level] = slot; 725123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 7260783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 727d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 728d4dbff95SChris Mason p, ins_len); 7295c680ed6SChris Mason BUG_ON(sret > 0); 7305c680ed6SChris Mason if (sret) 7315c680ed6SChris Mason return sret; 7325c680ed6SChris Mason } 733be0e5c09SChris Mason return ret; 734be0e5c09SChris Mason } 735be0e5c09SChris Mason } 736aa5d6bedSChris Mason return 1; 737be0e5c09SChris Mason } 738be0e5c09SChris Mason 73974123bd7SChris Mason /* 74074123bd7SChris Mason * adjust the pointers going up the tree, starting at level 74174123bd7SChris Mason * making sure the right key of each node is points to 'key'. 74274123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 74374123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 74474123bd7SChris Mason * higher levels 745aa5d6bedSChris Mason * 746aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 747aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 74874123bd7SChris Mason */ 749e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 750e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 751e089f05cSChris Mason *key, int level) 752be0e5c09SChris Mason { 753be0e5c09SChris Mason int i; 754aa5d6bedSChris Mason int ret = 0; 755234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 756234b63a0SChris Mason struct btrfs_node *t; 757be0e5c09SChris Mason int tslot = path->slots[i]; 758eb60ceacSChris Mason if (!path->nodes[i]) 759be0e5c09SChris Mason break; 760e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 761d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 762d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 763be0e5c09SChris Mason if (tslot != 0) 764be0e5c09SChris Mason break; 765be0e5c09SChris Mason } 766aa5d6bedSChris Mason return ret; 767be0e5c09SChris Mason } 768be0e5c09SChris Mason 76974123bd7SChris Mason /* 77074123bd7SChris Mason * try to push data from one node into the next node left in the 77179f95c82SChris Mason * tree. 772aa5d6bedSChris Mason * 773aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 774aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 77574123bd7SChris Mason */ 776e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 777e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 778e20d96d6SChris Mason buffer_head *src_buf) 779be0e5c09SChris Mason { 780e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 781e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 782be0e5c09SChris Mason int push_items = 0; 783bb803951SChris Mason int src_nritems; 784bb803951SChris Mason int dst_nritems; 785aa5d6bedSChris Mason int ret = 0; 786be0e5c09SChris Mason 7877518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 7887518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 789123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 79054aa1f4dSChris Mason 791eb60ceacSChris Mason if (push_items <= 0) { 792be0e5c09SChris Mason return 1; 793eb60ceacSChris Mason } 794be0e5c09SChris Mason 795be0e5c09SChris Mason if (src_nritems < push_items) 796be0e5c09SChris Mason push_items = src_nritems; 79779f95c82SChris Mason 798d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 799123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 800bb803951SChris Mason if (push_items < src_nritems) { 801d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 802e2fa7227SChris Mason (src_nritems - push_items) * 803123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 804bb803951SChris Mason } 8057518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 8067518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 807d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 808d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 809bb803951SChris Mason return ret; 810be0e5c09SChris Mason } 811be0e5c09SChris Mason 81297571fd0SChris Mason /* 81379f95c82SChris Mason * try to push data from one node into the next node right in the 81479f95c82SChris Mason * tree. 81579f95c82SChris Mason * 81679f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 81779f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 81879f95c82SChris Mason * 81979f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 82079f95c82SChris Mason */ 821e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 822e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 823e20d96d6SChris Mason struct buffer_head *src_buf) 82479f95c82SChris Mason { 825e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 826e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 82779f95c82SChris Mason int push_items = 0; 82879f95c82SChris Mason int max_push; 82979f95c82SChris Mason int src_nritems; 83079f95c82SChris Mason int dst_nritems; 83179f95c82SChris Mason int ret = 0; 83279f95c82SChris Mason 8337518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 8347518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 835123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 83679f95c82SChris Mason if (push_items <= 0) { 83779f95c82SChris Mason return 1; 83879f95c82SChris Mason } 83979f95c82SChris Mason 84079f95c82SChris Mason max_push = src_nritems / 2 + 1; 84179f95c82SChris Mason /* don't try to empty the node */ 84279f95c82SChris Mason if (max_push > src_nritems) 84379f95c82SChris Mason return 1; 84479f95c82SChris Mason if (max_push < push_items) 84579f95c82SChris Mason push_items = max_push; 84679f95c82SChris Mason 847d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 848123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 849d6025579SChris Mason 850d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 851d6025579SChris Mason src->ptrs + src_nritems - push_items, 852123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 85379f95c82SChris Mason 8547518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 8557518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 85679f95c82SChris Mason 857d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 858d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 85979f95c82SChris Mason return ret; 86079f95c82SChris Mason } 86179f95c82SChris Mason 86279f95c82SChris Mason /* 86397571fd0SChris Mason * helper function to insert a new root level in the tree. 86497571fd0SChris Mason * A new node is allocated, and a single item is inserted to 86597571fd0SChris Mason * point to the existing root 866aa5d6bedSChris Mason * 867aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 86897571fd0SChris Mason */ 869e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 870e089f05cSChris Mason *root, struct btrfs_path *path, int level) 87174123bd7SChris Mason { 872e20d96d6SChris Mason struct buffer_head *t; 873234b63a0SChris Mason struct btrfs_node *lower; 874234b63a0SChris Mason struct btrfs_node *c; 875e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 8765c680ed6SChris Mason 8775c680ed6SChris Mason BUG_ON(path->nodes[level]); 8785c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 8795c680ed6SChris Mason 88031f3c99bSChris Mason t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr); 88154aa1f4dSChris Mason if (IS_ERR(t)) 88254aa1f4dSChris Mason return PTR_ERR(t); 883e20d96d6SChris Mason c = btrfs_buffer_node(t); 884123abc88SChris Mason memset(c, 0, root->blocksize); 8857518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 8867518a238SChris Mason btrfs_set_header_level(&c->header, level); 8877eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 8887f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 8894d775673SChris Mason btrfs_set_header_owner(&c->header, root->root_key.objectid); 890e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 8913eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 8923eb0314dSChris Mason sizeof(c->header.fsid)); 8937518a238SChris Mason if (btrfs_is_leaf(lower)) 894234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 89574123bd7SChris Mason else 896123abc88SChris Mason lower_key = &lower->ptrs[0].key; 897d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 898d6025579SChris Mason sizeof(struct btrfs_disk_key)); 8997eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 900d5719762SChris Mason 901d6025579SChris Mason btrfs_mark_buffer_dirty(t); 902d5719762SChris Mason 903cfaa7295SChris Mason /* the super has an extra ref to root->node */ 904234b63a0SChris Mason btrfs_block_release(root, root->node); 90574123bd7SChris Mason root->node = t; 906e20d96d6SChris Mason get_bh(t); 90774123bd7SChris Mason path->nodes[level] = t; 90874123bd7SChris Mason path->slots[level] = 0; 90974123bd7SChris Mason return 0; 91074123bd7SChris Mason } 9115c680ed6SChris Mason 9125c680ed6SChris Mason /* 9135c680ed6SChris Mason * worker function to insert a single pointer in a node. 9145c680ed6SChris Mason * the node should have enough room for the pointer already 91597571fd0SChris Mason * 9165c680ed6SChris Mason * slot and level indicate where you want the key to go, and 9175c680ed6SChris Mason * blocknr is the block the key points to. 918aa5d6bedSChris Mason * 919aa5d6bedSChris Mason * returns zero on success and < 0 on any error 9205c680ed6SChris Mason */ 921e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 922e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 923e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 9245c680ed6SChris Mason { 925234b63a0SChris Mason struct btrfs_node *lower; 9265c680ed6SChris Mason int nritems; 9275c680ed6SChris Mason 9285c680ed6SChris Mason BUG_ON(!path->nodes[level]); 929e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 9307518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 93174123bd7SChris Mason if (slot > nritems) 93274123bd7SChris Mason BUG(); 933123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 93474123bd7SChris Mason BUG(); 93574123bd7SChris Mason if (slot != nritems) { 936d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 937d6025579SChris Mason lower->ptrs + slot, 938123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 93974123bd7SChris Mason } 940d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 941d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 9421d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 9437518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 944d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 945098f59c2SChris Mason check_node(root, path, level); 94674123bd7SChris Mason return 0; 94774123bd7SChris Mason } 94874123bd7SChris Mason 94997571fd0SChris Mason /* 95097571fd0SChris Mason * split the node at the specified level in path in two. 95197571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 95297571fd0SChris Mason * 95397571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 95497571fd0SChris Mason * left and right, if either one works, it returns right away. 955aa5d6bedSChris Mason * 956aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 95797571fd0SChris Mason */ 958e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 959e089f05cSChris Mason *root, struct btrfs_path *path, int level) 960be0e5c09SChris Mason { 961e20d96d6SChris Mason struct buffer_head *t; 962234b63a0SChris Mason struct btrfs_node *c; 963e20d96d6SChris Mason struct buffer_head *split_buffer; 964234b63a0SChris Mason struct btrfs_node *split; 965be0e5c09SChris Mason int mid; 9665c680ed6SChris Mason int ret; 967aa5d6bedSChris Mason int wret; 9687518a238SChris Mason u32 c_nritems; 969be0e5c09SChris Mason 9705c680ed6SChris Mason t = path->nodes[level]; 971e20d96d6SChris Mason c = btrfs_buffer_node(t); 9725c680ed6SChris Mason if (t == root->node) { 9735c680ed6SChris Mason /* trying to split the root, lets make a new one */ 974e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 9755c680ed6SChris Mason if (ret) 9765c680ed6SChris Mason return ret; 977e66f709bSChris Mason } else { 978e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 979e66f709bSChris Mason t = path->nodes[level]; 980e66f709bSChris Mason c = btrfs_buffer_node(t); 981e66f709bSChris Mason if (!ret && 982e66f709bSChris Mason btrfs_header_nritems(&c->header) < 983e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 984e66f709bSChris Mason return 0; 98554aa1f4dSChris Mason if (ret < 0) 98654aa1f4dSChris Mason return ret; 9875c680ed6SChris Mason } 988e66f709bSChris Mason 9897518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 99031f3c99bSChris Mason split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr); 99154aa1f4dSChris Mason if (IS_ERR(split_buffer)) 99254aa1f4dSChris Mason return PTR_ERR(split_buffer); 99354aa1f4dSChris Mason 994e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 9957518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 9969a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 9977eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 9987f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 9994d775673SChris Mason btrfs_set_header_owner(&split->header, root->root_key.objectid); 10003eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 10013eb0314dSChris Mason sizeof(split->header.fsid)); 10027518a238SChris Mason mid = (c_nritems + 1) / 2; 1003d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 1004123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 10057518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 10067518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 1007aa5d6bedSChris Mason ret = 0; 1008aa5d6bedSChris Mason 1009d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1010d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 1011e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 10127eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 1013123abc88SChris Mason level + 1); 1014aa5d6bedSChris Mason if (wret) 1015aa5d6bedSChris Mason ret = wret; 1016aa5d6bedSChris Mason 10175de08d7dSChris Mason if (path->slots[level] >= mid) { 10185c680ed6SChris Mason path->slots[level] -= mid; 1019234b63a0SChris Mason btrfs_block_release(root, t); 10205c680ed6SChris Mason path->nodes[level] = split_buffer; 10215c680ed6SChris Mason path->slots[level + 1] += 1; 1022eb60ceacSChris Mason } else { 1023234b63a0SChris Mason btrfs_block_release(root, split_buffer); 1024be0e5c09SChris Mason } 1025aa5d6bedSChris Mason return ret; 1026be0e5c09SChris Mason } 1027be0e5c09SChris Mason 102874123bd7SChris Mason /* 102974123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 103074123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 103174123bd7SChris Mason * space used both by the item structs and the item data 103274123bd7SChris Mason */ 1033234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 1034be0e5c09SChris Mason { 1035be0e5c09SChris Mason int data_len; 1036d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 1037d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 1038be0e5c09SChris Mason 1039be0e5c09SChris Mason if (!nr) 1040be0e5c09SChris Mason return 0; 10410783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 10420783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 10430783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 1044d4dbff95SChris Mason WARN_ON(data_len < 0); 1045be0e5c09SChris Mason return data_len; 1046be0e5c09SChris Mason } 1047be0e5c09SChris Mason 104874123bd7SChris Mason /* 1049d4dbff95SChris Mason * The space between the end of the leaf items and 1050d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 1051d4dbff95SChris Mason * the leaf has left for both items and data 1052d4dbff95SChris Mason */ 1053d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 1054d4dbff95SChris Mason { 1055d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 1056d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 1057d4dbff95SChris Mason } 1058d4dbff95SChris Mason 1059d4dbff95SChris Mason /* 106000ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 106100ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 1062aa5d6bedSChris Mason * 1063aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 1064aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 106500ec4c51SChris Mason */ 1066e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 1067e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 106800ec4c51SChris Mason { 1069e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 1070e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 1071234b63a0SChris Mason struct btrfs_leaf *right; 1072e20d96d6SChris Mason struct buffer_head *right_buf; 1073e20d96d6SChris Mason struct buffer_head *upper; 1074e20d96d6SChris Mason struct btrfs_node *upper_node; 107500ec4c51SChris Mason int slot; 107600ec4c51SChris Mason int i; 107700ec4c51SChris Mason int free_space; 107800ec4c51SChris Mason int push_space = 0; 107900ec4c51SChris Mason int push_items = 0; 10800783fcfcSChris Mason struct btrfs_item *item; 10817518a238SChris Mason u32 left_nritems; 10827518a238SChris Mason u32 right_nritems; 108354aa1f4dSChris Mason int ret; 108400ec4c51SChris Mason 108500ec4c51SChris Mason slot = path->slots[1]; 108600ec4c51SChris Mason if (!path->nodes[1]) { 108700ec4c51SChris Mason return 1; 108800ec4c51SChris Mason } 108900ec4c51SChris Mason upper = path->nodes[1]; 1090e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1091e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 109200ec4c51SChris Mason return 1; 109300ec4c51SChris Mason } 1094e20d96d6SChris Mason right_buf = read_tree_block(root, 1095e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 1096e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1097123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 10980783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1099234b63a0SChris Mason btrfs_block_release(root, right_buf); 110000ec4c51SChris Mason return 1; 110100ec4c51SChris Mason } 110202217ed2SChris Mason /* cow and double check */ 110354aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, upper, 110454aa1f4dSChris Mason slot + 1, &right_buf); 110554aa1f4dSChris Mason if (ret) { 110654aa1f4dSChris Mason btrfs_block_release(root, right_buf); 110754aa1f4dSChris Mason return 1; 110854aa1f4dSChris Mason } 1109e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1110123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 11110783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1112234b63a0SChris Mason btrfs_block_release(root, right_buf); 111302217ed2SChris Mason return 1; 111402217ed2SChris Mason } 111502217ed2SChris Mason 11167518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1117a429e513SChris Mason if (left_nritems == 0) { 1118a429e513SChris Mason btrfs_block_release(root, right_buf); 1119a429e513SChris Mason return 1; 1120a429e513SChris Mason } 1121a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 112200ec4c51SChris Mason item = left->items + i; 112300ec4c51SChris Mason if (path->slots[0] == i) 112400ec4c51SChris Mason push_space += data_size + sizeof(*item); 11250783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 11260783fcfcSChris Mason free_space) 112700ec4c51SChris Mason break; 112800ec4c51SChris Mason push_items++; 11290783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 113000ec4c51SChris Mason } 113100ec4c51SChris Mason if (push_items == 0) { 1132234b63a0SChris Mason btrfs_block_release(root, right_buf); 113300ec4c51SChris Mason return 1; 113400ec4c51SChris Mason } 1135a429e513SChris Mason if (push_items == left_nritems) 1136a429e513SChris Mason WARN_ON(1); 11377518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 113800ec4c51SChris Mason /* push left to right */ 11390783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1140123abc88SChris Mason push_space -= leaf_data_end(root, left); 114100ec4c51SChris Mason /* make room in the right data area */ 1142d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1143d6025579SChris Mason leaf_data_end(root, right) - push_space, 1144d6025579SChris Mason btrfs_leaf_data(right) + 1145d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1146d6025579SChris Mason leaf_data_end(root, right)); 114700ec4c51SChris Mason /* copy from the left data area */ 1148d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1149d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1150d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1151d6025579SChris Mason push_space); 1152d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 11530783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 115400ec4c51SChris Mason /* copy the items from left to right */ 1155d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1156d6025579SChris Mason left_nritems - push_items, 11570783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 115800ec4c51SChris Mason 115900ec4c51SChris Mason /* update the item pointers */ 11607518a238SChris Mason right_nritems += push_items; 11617518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1162123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 11637518a238SChris Mason for (i = 0; i < right_nritems; i++) { 11640783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 11650783fcfcSChris Mason btrfs_item_size(right->items + i)); 11660783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 116700ec4c51SChris Mason } 11687518a238SChris Mason left_nritems -= push_items; 11697518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 117000ec4c51SChris Mason 1171d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1172d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1173a429e513SChris Mason 1174d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1175e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1176d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 117702217ed2SChris Mason 117800ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 11797518a238SChris Mason if (path->slots[0] >= left_nritems) { 11807518a238SChris Mason path->slots[0] -= left_nritems; 1181234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 118200ec4c51SChris Mason path->nodes[0] = right_buf; 118300ec4c51SChris Mason path->slots[1] += 1; 118400ec4c51SChris Mason } else { 1185234b63a0SChris Mason btrfs_block_release(root, right_buf); 118600ec4c51SChris Mason } 1187098f59c2SChris Mason if (path->nodes[1]) 1188098f59c2SChris Mason check_node(root, path, 1); 118900ec4c51SChris Mason return 0; 119000ec4c51SChris Mason } 119100ec4c51SChris Mason /* 119274123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 119374123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 119474123bd7SChris Mason */ 1195e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1196e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1197be0e5c09SChris Mason { 1198e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1199e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1200e20d96d6SChris Mason struct buffer_head *t; 1201234b63a0SChris Mason struct btrfs_leaf *left; 1202be0e5c09SChris Mason int slot; 1203be0e5c09SChris Mason int i; 1204be0e5c09SChris Mason int free_space; 1205be0e5c09SChris Mason int push_space = 0; 1206be0e5c09SChris Mason int push_items = 0; 12070783fcfcSChris Mason struct btrfs_item *item; 12087518a238SChris Mason u32 old_left_nritems; 1209aa5d6bedSChris Mason int ret = 0; 1210aa5d6bedSChris Mason int wret; 1211be0e5c09SChris Mason 1212be0e5c09SChris Mason slot = path->slots[1]; 1213be0e5c09SChris Mason if (slot == 0) { 1214be0e5c09SChris Mason return 1; 1215be0e5c09SChris Mason } 1216be0e5c09SChris Mason if (!path->nodes[1]) { 1217be0e5c09SChris Mason return 1; 1218be0e5c09SChris Mason } 1219e20d96d6SChris Mason t = read_tree_block(root, 1220e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1221e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1222123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 12230783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1224234b63a0SChris Mason btrfs_block_release(root, t); 1225be0e5c09SChris Mason return 1; 1226be0e5c09SChris Mason } 122702217ed2SChris Mason 122802217ed2SChris Mason /* cow and double check */ 122954aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 123054aa1f4dSChris Mason if (ret) { 123154aa1f4dSChris Mason /* we hit -ENOSPC, but it isn't fatal here */ 123254aa1f4dSChris Mason return 1; 123354aa1f4dSChris Mason } 1234e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1235123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 12360783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1237234b63a0SChris Mason btrfs_block_release(root, t); 123802217ed2SChris Mason return 1; 123902217ed2SChris Mason } 124002217ed2SChris Mason 1241a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1242a429e513SChris Mason btrfs_block_release(root, t); 1243a429e513SChris Mason return 1; 1244a429e513SChris Mason } 1245a429e513SChris Mason 1246a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1247be0e5c09SChris Mason item = right->items + i; 1248be0e5c09SChris Mason if (path->slots[0] == i) 1249be0e5c09SChris Mason push_space += data_size + sizeof(*item); 12500783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 12510783fcfcSChris Mason free_space) 1252be0e5c09SChris Mason break; 1253be0e5c09SChris Mason push_items++; 12540783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1255be0e5c09SChris Mason } 1256be0e5c09SChris Mason if (push_items == 0) { 1257234b63a0SChris Mason btrfs_block_release(root, t); 1258be0e5c09SChris Mason return 1; 1259be0e5c09SChris Mason } 1260a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1261a429e513SChris Mason WARN_ON(1); 1262be0e5c09SChris Mason /* push data from right to left */ 1263d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1264d6025579SChris Mason btrfs_header_nritems(&left->header), 12650783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1266123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 12670783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1268d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1269d6025579SChris Mason leaf_data_end(root, left) - push_space, 1270123abc88SChris Mason btrfs_leaf_data(right) + 1271123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1272be0e5c09SChris Mason push_space); 12737518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1274eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1275eb60ceacSChris Mason 1276be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1277123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1278123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1279123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 12800783fcfcSChris Mason btrfs_item_offset(left->items + 12810783fcfcSChris Mason old_left_nritems - 1))); 1282be0e5c09SChris Mason } 12837518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1284be0e5c09SChris Mason 1285be0e5c09SChris Mason /* fixup right node */ 12860783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1287123abc88SChris Mason leaf_data_end(root, right); 1288d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1289d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1290d6025579SChris Mason btrfs_leaf_data(right) + 1291123abc88SChris Mason leaf_data_end(root, right), push_space); 1292d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 12937518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 12940783fcfcSChris Mason sizeof(struct btrfs_item)); 12957518a238SChris Mason btrfs_set_header_nritems(&right->header, 12967518a238SChris Mason btrfs_header_nritems(&right->header) - 12977518a238SChris Mason push_items); 1298123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1299eb60ceacSChris Mason 13007518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 13010783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 13020783fcfcSChris Mason btrfs_item_size(right->items + i)); 13030783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1304be0e5c09SChris Mason } 1305eb60ceacSChris Mason 1306d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1307d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1308098f59c2SChris Mason 1309e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1310aa5d6bedSChris Mason if (wret) 1311aa5d6bedSChris Mason ret = wret; 1312be0e5c09SChris Mason 1313be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1314be0e5c09SChris Mason if (path->slots[0] < push_items) { 1315be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1316234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1317eb60ceacSChris Mason path->nodes[0] = t; 1318be0e5c09SChris Mason path->slots[1] -= 1; 1319be0e5c09SChris Mason } else { 1320234b63a0SChris Mason btrfs_block_release(root, t); 1321be0e5c09SChris Mason path->slots[0] -= push_items; 1322be0e5c09SChris Mason } 1323eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1324098f59c2SChris Mason if (path->nodes[1]) 1325098f59c2SChris Mason check_node(root, path, 1); 1326aa5d6bedSChris Mason return ret; 1327be0e5c09SChris Mason } 1328be0e5c09SChris Mason 132974123bd7SChris Mason /* 133074123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 133174123bd7SChris Mason * available for the resulting leaf level of the path. 1332aa5d6bedSChris Mason * 1333aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 133474123bd7SChris Mason */ 1335e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1336d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1337d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1338be0e5c09SChris Mason { 1339e20d96d6SChris Mason struct buffer_head *l_buf; 1340234b63a0SChris Mason struct btrfs_leaf *l; 13417518a238SChris Mason u32 nritems; 1342eb60ceacSChris Mason int mid; 1343eb60ceacSChris Mason int slot; 1344234b63a0SChris Mason struct btrfs_leaf *right; 1345e20d96d6SChris Mason struct buffer_head *right_buffer; 13460783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1347be0e5c09SChris Mason int data_copy_size; 1348be0e5c09SChris Mason int rt_data_off; 1349be0e5c09SChris Mason int i; 1350d4dbff95SChris Mason int ret = 0; 1351aa5d6bedSChris Mason int wret; 1352d4dbff95SChris Mason int double_split = 0; 1353d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1354be0e5c09SChris Mason 135540689478SChris Mason /* first try to make some room by pushing left and right */ 1356e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1357eaee50e8SChris Mason if (wret < 0) 1358eaee50e8SChris Mason return wret; 1359eaee50e8SChris Mason if (wret) { 1360e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1361eaee50e8SChris Mason if (wret < 0) 1362eaee50e8SChris Mason return wret; 1363eaee50e8SChris Mason } 1364eb60ceacSChris Mason l_buf = path->nodes[0]; 1365e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1366aa5d6bedSChris Mason 1367aa5d6bedSChris Mason /* did the pushes work? */ 1368123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1369123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1370be0e5c09SChris Mason return 0; 1371aa5d6bedSChris Mason 13725c680ed6SChris Mason if (!path->nodes[1]) { 1373e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 13745c680ed6SChris Mason if (ret) 13755c680ed6SChris Mason return ret; 13765c680ed6SChris Mason } 1377eb60ceacSChris Mason slot = path->slots[0]; 13787518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1379eb60ceacSChris Mason mid = (nritems + 1)/ 2; 138054aa1f4dSChris Mason 138131f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 138254aa1f4dSChris Mason if (IS_ERR(right_buffer)) 138354aa1f4dSChris Mason return PTR_ERR(right_buffer); 138454aa1f4dSChris Mason 1385e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1386123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 13877eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 13887f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 13894d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 13907518a238SChris Mason btrfs_set_header_level(&right->header, 0); 13913eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 13923eb0314dSChris Mason sizeof(right->header.fsid)); 1393d4dbff95SChris Mason if (mid <= slot) { 1394d4dbff95SChris Mason if (nritems == 1 || 1395d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1396d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1397d4dbff95SChris Mason if (slot >= nritems) { 1398d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1399d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1400d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1401d4dbff95SChris Mason &disk_key, 14027eccb903SChris Mason bh_blocknr(right_buffer), 1403d4dbff95SChris Mason path->slots[1] + 1, 1); 1404d4dbff95SChris Mason if (wret) 1405d4dbff95SChris Mason ret = wret; 1406d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1407d4dbff95SChris Mason path->nodes[0] = right_buffer; 1408d4dbff95SChris Mason path->slots[0] = 0; 1409d4dbff95SChris Mason path->slots[1] += 1; 1410d4dbff95SChris Mason return ret; 1411d4dbff95SChris Mason } 1412d4dbff95SChris Mason mid = slot; 1413d4dbff95SChris Mason double_split = 1; 1414d4dbff95SChris Mason } 1415d4dbff95SChris Mason } else { 1416d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1417d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1418d4dbff95SChris Mason if (slot == 0) { 1419d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1420d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1421d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1422d4dbff95SChris Mason &disk_key, 14237eccb903SChris Mason bh_blocknr(right_buffer), 1424098f59c2SChris Mason path->slots[1], 1); 1425d4dbff95SChris Mason if (wret) 1426d4dbff95SChris Mason ret = wret; 1427d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1428d4dbff95SChris Mason path->nodes[0] = right_buffer; 1429d4dbff95SChris Mason path->slots[0] = 0; 1430a429e513SChris Mason if (path->slots[1] == 0) { 1431a429e513SChris Mason wret = fixup_low_keys(trans, root, 1432a429e513SChris Mason path, &disk_key, 1); 1433a429e513SChris Mason if (wret) 1434a429e513SChris Mason ret = wret; 1435a429e513SChris Mason } 1436d4dbff95SChris Mason return ret; 1437d4dbff95SChris Mason } 1438d4dbff95SChris Mason mid = slot; 1439d4dbff95SChris Mason double_split = 1; 1440d4dbff95SChris Mason } 1441d4dbff95SChris Mason } 1442d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1443123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1444123abc88SChris Mason leaf_data_end(root, l); 1445d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 14460783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1447d6025579SChris Mason btrfs_memcpy(root, right, 1448d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1449123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1450123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1451123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1452123abc88SChris Mason btrfs_item_end(l->items + mid); 145374123bd7SChris Mason 14540783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1455123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 14560783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 14570783fcfcSChris Mason } 145874123bd7SChris Mason 14597518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1460aa5d6bedSChris Mason ret = 0; 1461e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 14627eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1463aa5d6bedSChris Mason if (wret) 1464aa5d6bedSChris Mason ret = wret; 1465d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1466d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1467eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1468be0e5c09SChris Mason if (mid <= slot) { 1469234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1470eb60ceacSChris Mason path->nodes[0] = right_buffer; 1471be0e5c09SChris Mason path->slots[0] -= mid; 1472be0e5c09SChris Mason path->slots[1] += 1; 1473eb60ceacSChris Mason } else 1474234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1475eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1476098f59c2SChris Mason check_node(root, path, 1); 1477d4dbff95SChris Mason 1478d4dbff95SChris Mason if (!double_split) 1479d4dbff95SChris Mason return ret; 148031f3c99bSChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 148154aa1f4dSChris Mason if (IS_ERR(right_buffer)) 148254aa1f4dSChris Mason return PTR_ERR(right_buffer); 148354aa1f4dSChris Mason 1484d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1485d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 14867eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1487d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 14884d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 1489d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 14903eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 14913eb0314dSChris Mason sizeof(right->header.fsid)); 1492d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1493d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1494d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1495d4dbff95SChris Mason &disk_key, 14967eccb903SChris Mason bh_blocknr(right_buffer), 1497d4dbff95SChris Mason path->slots[1], 1); 1498d4dbff95SChris Mason if (wret) 1499d4dbff95SChris Mason ret = wret; 1500a429e513SChris Mason if (path->slots[1] == 0) { 1501a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1502a429e513SChris Mason if (wret) 1503a429e513SChris Mason ret = wret; 1504a429e513SChris Mason } 1505d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1506d4dbff95SChris Mason path->nodes[0] = right_buffer; 1507d4dbff95SChris Mason path->slots[0] = 0; 1508d4dbff95SChris Mason check_node(root, path, 1); 1509d4dbff95SChris Mason check_leaf(root, path, 0); 1510be0e5c09SChris Mason return ret; 1511be0e5c09SChris Mason } 1512be0e5c09SChris Mason 1513b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1514b18c6685SChris Mason struct btrfs_root *root, 1515b18c6685SChris Mason struct btrfs_path *path, 1516b18c6685SChris Mason u32 new_size) 1517b18c6685SChris Mason { 1518b18c6685SChris Mason int ret = 0; 1519b18c6685SChris Mason int slot; 1520b18c6685SChris Mason int slot_orig; 1521b18c6685SChris Mason struct btrfs_leaf *leaf; 1522b18c6685SChris Mason struct buffer_head *leaf_buf; 1523b18c6685SChris Mason u32 nritems; 1524b18c6685SChris Mason unsigned int data_end; 1525b18c6685SChris Mason unsigned int old_data_start; 1526b18c6685SChris Mason unsigned int old_size; 1527b18c6685SChris Mason unsigned int size_diff; 1528b18c6685SChris Mason int i; 1529b18c6685SChris Mason 1530b18c6685SChris Mason slot_orig = path->slots[0]; 1531b18c6685SChris Mason leaf_buf = path->nodes[0]; 1532b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1533b18c6685SChris Mason 1534b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1535b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1536b18c6685SChris Mason 1537b18c6685SChris Mason slot = path->slots[0]; 1538b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1539b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1540b18c6685SChris Mason BUG_ON(old_size <= new_size); 1541b18c6685SChris Mason size_diff = old_size - new_size; 1542b18c6685SChris Mason 1543b18c6685SChris Mason BUG_ON(slot < 0); 1544b18c6685SChris Mason BUG_ON(slot >= nritems); 1545b18c6685SChris Mason 1546b18c6685SChris Mason /* 1547b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1548b18c6685SChris Mason */ 1549b18c6685SChris Mason /* first correct the data pointers */ 1550b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1551b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1552b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1553b18c6685SChris Mason ioff + size_diff); 1554b18c6685SChris Mason } 1555b18c6685SChris Mason /* shift the data */ 1556b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1557b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1558b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1559b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1560b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1561b18c6685SChris Mason 1562b18c6685SChris Mason ret = 0; 1563b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1564b18c6685SChris Mason BUG(); 1565b18c6685SChris Mason check_leaf(root, path, 0); 1566b18c6685SChris Mason return ret; 1567b18c6685SChris Mason } 1568b18c6685SChris Mason 15696567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 15706567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 15716567e837SChris Mason { 15726567e837SChris Mason int ret = 0; 15736567e837SChris Mason int slot; 15746567e837SChris Mason int slot_orig; 15756567e837SChris Mason struct btrfs_leaf *leaf; 15766567e837SChris Mason struct buffer_head *leaf_buf; 15776567e837SChris Mason u32 nritems; 15786567e837SChris Mason unsigned int data_end; 15796567e837SChris Mason unsigned int old_data; 15806567e837SChris Mason unsigned int old_size; 15816567e837SChris Mason int i; 15826567e837SChris Mason 15836567e837SChris Mason slot_orig = path->slots[0]; 15846567e837SChris Mason leaf_buf = path->nodes[0]; 15856567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 15866567e837SChris Mason 15876567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 15886567e837SChris Mason data_end = leaf_data_end(root, leaf); 15896567e837SChris Mason 15906567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 15916567e837SChris Mason BUG(); 15926567e837SChris Mason slot = path->slots[0]; 15936567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 15946567e837SChris Mason 15956567e837SChris Mason BUG_ON(slot < 0); 15966567e837SChris Mason BUG_ON(slot >= nritems); 15976567e837SChris Mason 15986567e837SChris Mason /* 15996567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 16006567e837SChris Mason */ 16016567e837SChris Mason /* first correct the data pointers */ 16026567e837SChris Mason for (i = slot; i < nritems; i++) { 16036567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 16046567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 16056567e837SChris Mason ioff - data_size); 16066567e837SChris Mason } 16076567e837SChris Mason /* shift the data */ 16086567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 16096567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 16106567e837SChris Mason data_end, old_data - data_end); 16116567e837SChris Mason data_end = old_data; 16126567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 16136567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 16146567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 16156567e837SChris Mason 16166567e837SChris Mason ret = 0; 16176567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 16186567e837SChris Mason BUG(); 16196567e837SChris Mason check_leaf(root, path, 0); 16206567e837SChris Mason return ret; 16216567e837SChris Mason } 16226567e837SChris Mason 162374123bd7SChris Mason /* 162474123bd7SChris Mason * Given a key and some data, insert an item into the tree. 162574123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 162674123bd7SChris Mason */ 1627e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1628e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1629e089f05cSChris Mason *cpu_key, u32 data_size) 1630be0e5c09SChris Mason { 1631aa5d6bedSChris Mason int ret = 0; 1632be0e5c09SChris Mason int slot; 1633eb60ceacSChris Mason int slot_orig; 1634234b63a0SChris Mason struct btrfs_leaf *leaf; 1635e20d96d6SChris Mason struct buffer_head *leaf_buf; 16367518a238SChris Mason u32 nritems; 1637be0e5c09SChris Mason unsigned int data_end; 1638e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1639e2fa7227SChris Mason 1640e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1641be0e5c09SChris Mason 164274123bd7SChris Mason /* create a root if there isn't one */ 16435c680ed6SChris Mason if (!root->node) 1644cfaa7295SChris Mason BUG(); 1645e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1646eb60ceacSChris Mason if (ret == 0) { 1647f0930a37SChris Mason return -EEXIST; 1648aa5d6bedSChris Mason } 1649ed2ff2cbSChris Mason if (ret < 0) 1650ed2ff2cbSChris Mason goto out; 1651be0e5c09SChris Mason 165262e2749eSChris Mason slot_orig = path->slots[0]; 165362e2749eSChris Mason leaf_buf = path->nodes[0]; 1654e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 165574123bd7SChris Mason 16567518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1657123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1658eb60ceacSChris Mason 1659123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1660d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1661be0e5c09SChris Mason BUG(); 1662d4dbff95SChris Mason } 166362e2749eSChris Mason slot = path->slots[0]; 1664eb60ceacSChris Mason BUG_ON(slot < 0); 1665be0e5c09SChris Mason if (slot != nritems) { 1666be0e5c09SChris Mason int i; 16670783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1668be0e5c09SChris Mason 1669be0e5c09SChris Mason /* 1670be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1671be0e5c09SChris Mason */ 1672be0e5c09SChris Mason /* first correct the data pointers */ 16730783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1674123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 16750783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 16760783fcfcSChris Mason ioff - data_size); 16770783fcfcSChris Mason } 1678be0e5c09SChris Mason 1679be0e5c09SChris Mason /* shift the items */ 1680d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1681d6025579SChris Mason leaf->items + slot, 16820783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1683be0e5c09SChris Mason 1684be0e5c09SChris Mason /* shift the data */ 1685d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1686d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1687be0e5c09SChris Mason data_end, old_data - data_end); 1688be0e5c09SChris Mason data_end = old_data; 1689be0e5c09SChris Mason } 169062e2749eSChris Mason /* setup the item for the new data */ 1691d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1692e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 16930783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 16940783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 16957518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1696d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1697aa5d6bedSChris Mason 1698aa5d6bedSChris Mason ret = 0; 16998e19f2cdSChris Mason if (slot == 0) 1700e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1701aa5d6bedSChris Mason 1702123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1703be0e5c09SChris Mason BUG(); 170462e2749eSChris Mason check_leaf(root, path, 0); 1705ed2ff2cbSChris Mason out: 170662e2749eSChris Mason return ret; 170762e2749eSChris Mason } 170862e2749eSChris Mason 170962e2749eSChris Mason /* 171062e2749eSChris Mason * Given a key and some data, insert an item into the tree. 171162e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 171262e2749eSChris Mason */ 1713e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1714e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1715e089f05cSChris Mason data_size) 171662e2749eSChris Mason { 171762e2749eSChris Mason int ret = 0; 17182c90e5d6SChris Mason struct btrfs_path *path; 171962e2749eSChris Mason u8 *ptr; 172062e2749eSChris Mason 17212c90e5d6SChris Mason path = btrfs_alloc_path(); 17222c90e5d6SChris Mason BUG_ON(!path); 17232c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 172462e2749eSChris Mason if (!ret) { 17252c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 17262c90e5d6SChris Mason path->slots[0], u8); 17272c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1728d6025579SChris Mason ptr, data, data_size); 17292c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 173062e2749eSChris Mason } 17312c90e5d6SChris Mason btrfs_free_path(path); 1732aa5d6bedSChris Mason return ret; 1733be0e5c09SChris Mason } 1734be0e5c09SChris Mason 173574123bd7SChris Mason /* 17365de08d7dSChris Mason * delete the pointer from a given node. 173774123bd7SChris Mason * 173874123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 173974123bd7SChris Mason * continuing all the way the root if required. The root is converted into 174074123bd7SChris Mason * a leaf if all the nodes are emptied. 174174123bd7SChris Mason */ 1742e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1743e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1744be0e5c09SChris Mason { 1745234b63a0SChris Mason struct btrfs_node *node; 1746e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 17477518a238SChris Mason u32 nritems; 1748aa5d6bedSChris Mason int ret = 0; 1749bb803951SChris Mason int wret; 1750be0e5c09SChris Mason 1751e20d96d6SChris Mason node = btrfs_buffer_node(parent); 17527518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1753be0e5c09SChris Mason if (slot != nritems -1) { 1754d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1755d6025579SChris Mason node->ptrs + slot + 1, 1756d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1757d6025579SChris Mason (nritems - slot - 1)); 1758be0e5c09SChris Mason } 17597518a238SChris Mason nritems--; 17607518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 17617518a238SChris Mason if (nritems == 0 && parent == root->node) { 1762e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1763e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1764eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1765e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1766bb803951SChris Mason } else if (slot == 0) { 1767e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1768123abc88SChris Mason level + 1); 17690f70abe2SChris Mason if (wret) 17700f70abe2SChris Mason ret = wret; 1771be0e5c09SChris Mason } 1772d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1773aa5d6bedSChris Mason return ret; 1774be0e5c09SChris Mason } 1775be0e5c09SChris Mason 177674123bd7SChris Mason /* 177774123bd7SChris Mason * delete the item at the leaf level in path. If that empties 177874123bd7SChris Mason * the leaf, remove it from the tree 177974123bd7SChris Mason */ 1780e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1781e089f05cSChris Mason struct btrfs_path *path) 1782be0e5c09SChris Mason { 1783be0e5c09SChris Mason int slot; 1784234b63a0SChris Mason struct btrfs_leaf *leaf; 1785e20d96d6SChris Mason struct buffer_head *leaf_buf; 1786be0e5c09SChris Mason int doff; 1787be0e5c09SChris Mason int dsize; 1788aa5d6bedSChris Mason int ret = 0; 1789aa5d6bedSChris Mason int wret; 17907518a238SChris Mason u32 nritems; 1791be0e5c09SChris Mason 1792eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1793e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 17944920c9acSChris Mason slot = path->slots[0]; 17950783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 17960783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 17977518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1798be0e5c09SChris Mason 17997518a238SChris Mason if (slot != nritems - 1) { 1800be0e5c09SChris Mason int i; 1801123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 1802d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1803d6025579SChris Mason data_end + dsize, 1804123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 1805be0e5c09SChris Mason doff - data_end); 18060783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 1807123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 18080783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 18090783fcfcSChris Mason } 1810d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 1811d6025579SChris Mason leaf->items + slot + 1, 18120783fcfcSChris Mason sizeof(struct btrfs_item) * 18137518a238SChris Mason (nritems - slot - 1)); 1814be0e5c09SChris Mason } 18157518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 18167518a238SChris Mason nritems--; 181774123bd7SChris Mason /* delete the leaf if we've emptied it */ 18187518a238SChris Mason if (nritems == 0) { 1819eb60ceacSChris Mason if (leaf_buf == root->node) { 18207518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 18219a8dd150SChris Mason } else { 1822e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1823d6025579SChris Mason wait_on_buffer(leaf_buf); 1824e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 1825aa5d6bedSChris Mason if (wret) 1826aa5d6bedSChris Mason ret = wret; 1827e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 18287eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 18290f70abe2SChris Mason if (wret) 18300f70abe2SChris Mason ret = wret; 18319a8dd150SChris Mason } 1832be0e5c09SChris Mason } else { 18337518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 1834aa5d6bedSChris Mason if (slot == 0) { 1835e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 1836aa5d6bedSChris Mason &leaf->items[0].key, 1); 1837aa5d6bedSChris Mason if (wret) 1838aa5d6bedSChris Mason ret = wret; 1839aa5d6bedSChris Mason } 1840aa5d6bedSChris Mason 184174123bd7SChris Mason /* delete the leaf if it is mostly empty */ 1842123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1843be0e5c09SChris Mason /* push_leaf_left fixes the path. 1844be0e5c09SChris Mason * make sure the path still points to our leaf 1845be0e5c09SChris Mason * for possible call to del_ptr below 1846be0e5c09SChris Mason */ 18474920c9acSChris Mason slot = path->slots[1]; 1848e20d96d6SChris Mason get_bh(leaf_buf); 1849e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 185054aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 1851aa5d6bedSChris Mason ret = wret; 1852f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 18537518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 1854e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 185554aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 1856aa5d6bedSChris Mason ret = wret; 1857aa5d6bedSChris Mason } 18587518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 18597eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 1860e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 1861d6025579SChris Mason wait_on_buffer(leaf_buf); 1862e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 1863aa5d6bedSChris Mason if (wret) 1864aa5d6bedSChris Mason ret = wret; 1865234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1866e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1867e089f05cSChris Mason 1, 1); 18680f70abe2SChris Mason if (wret) 18690f70abe2SChris Mason ret = wret; 18705de08d7dSChris Mason } else { 1871d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1872234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 1873be0e5c09SChris Mason } 1874d5719762SChris Mason } else { 1875d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1876be0e5c09SChris Mason } 18779a8dd150SChris Mason } 1878aa5d6bedSChris Mason return ret; 18799a8dd150SChris Mason } 18809a8dd150SChris Mason 188197571fd0SChris Mason /* 188297571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 18830f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 18840f70abe2SChris Mason * returns < 0 on io errors. 188597571fd0SChris Mason */ 1886234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 1887d97e63b6SChris Mason { 1888d97e63b6SChris Mason int slot; 1889d97e63b6SChris Mason int level = 1; 1890d97e63b6SChris Mason u64 blocknr; 1891e20d96d6SChris Mason struct buffer_head *c; 1892e20d96d6SChris Mason struct btrfs_node *c_node; 1893e20d96d6SChris Mason struct buffer_head *next = NULL; 1894d97e63b6SChris Mason 1895234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 1896d97e63b6SChris Mason if (!path->nodes[level]) 18970f70abe2SChris Mason return 1; 1898d97e63b6SChris Mason slot = path->slots[level] + 1; 1899d97e63b6SChris Mason c = path->nodes[level]; 1900e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 1901e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 1902d97e63b6SChris Mason level++; 1903d97e63b6SChris Mason continue; 1904d97e63b6SChris Mason } 1905e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 1906cfaa7295SChris Mason if (next) 1907234b63a0SChris Mason btrfs_block_release(root, next); 1908d97e63b6SChris Mason next = read_tree_block(root, blocknr); 1909d97e63b6SChris Mason break; 1910d97e63b6SChris Mason } 1911d97e63b6SChris Mason path->slots[level] = slot; 1912d97e63b6SChris Mason while(1) { 1913d97e63b6SChris Mason level--; 1914d97e63b6SChris Mason c = path->nodes[level]; 1915234b63a0SChris Mason btrfs_block_release(root, c); 1916d97e63b6SChris Mason path->nodes[level] = next; 1917d97e63b6SChris Mason path->slots[level] = 0; 1918d97e63b6SChris Mason if (!level) 1919d97e63b6SChris Mason break; 19201d4f8a0cSChris Mason next = read_tree_block(root, 1921e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 1922d97e63b6SChris Mason } 1923d97e63b6SChris Mason return 0; 1924d97e63b6SChris Mason } 1925