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); 462cc58cf2SChris Mason if (path) { 47df24a2b9SChris Mason btrfs_init_path(path); 482cc58cf2SChris Mason path->reada = 1; 492cc58cf2SChris Mason } 50df24a2b9SChris Mason return path; 512c90e5d6SChris Mason } 522c90e5d6SChris Mason 532c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p) 542c90e5d6SChris Mason { 55df24a2b9SChris Mason btrfs_release_path(NULL, p); 562c90e5d6SChris Mason kmem_cache_free(btrfs_path_cachep, p); 572c90e5d6SChris Mason } 582c90e5d6SChris Mason 59234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) 60eb60ceacSChris Mason { 61eb60ceacSChris Mason int i; 62234b63a0SChris Mason for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 63eb60ceacSChris Mason if (!p->nodes[i]) 64eb60ceacSChris Mason break; 65234b63a0SChris Mason btrfs_block_release(root, p->nodes[i]); 66eb60ceacSChris Mason } 67aa5d6bedSChris Mason memset(p, 0, sizeof(*p)); 68eb60ceacSChris Mason } 69eb60ceacSChris Mason 706702ed49SChris Mason static int __btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 716702ed49SChris Mason *root, struct buffer_head *buf, struct buffer_head 726702ed49SChris Mason *parent, int parent_slot, struct buffer_head 736702ed49SChris Mason **cow_ret, u64 search_start, u64 empty_size) 746702ed49SChris Mason { 756702ed49SChris Mason struct buffer_head *cow; 766702ed49SChris Mason struct btrfs_node *cow_node; 776702ed49SChris Mason int ret = 0; 786702ed49SChris Mason int different_trans = 0; 796702ed49SChris Mason 806702ed49SChris Mason WARN_ON(root->ref_cows && trans->transid != root->last_trans); 816702ed49SChris Mason WARN_ON(!buffer_uptodate(buf)); 826702ed49SChris Mason cow = btrfs_alloc_free_block(trans, root, search_start, empty_size); 836702ed49SChris Mason if (IS_ERR(cow)) 846702ed49SChris Mason return PTR_ERR(cow); 856702ed49SChris Mason 866702ed49SChris Mason cow_node = btrfs_buffer_node(cow); 876702ed49SChris Mason if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) 886702ed49SChris Mason WARN_ON(1); 896702ed49SChris Mason 906702ed49SChris Mason memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 916702ed49SChris Mason btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); 926702ed49SChris Mason btrfs_set_header_generation(&cow_node->header, trans->transid); 936702ed49SChris Mason btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); 946702ed49SChris Mason 956702ed49SChris Mason WARN_ON(btrfs_header_generation(btrfs_buffer_header(buf)) > 966702ed49SChris Mason trans->transid); 976702ed49SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) != 986702ed49SChris Mason trans->transid) { 996702ed49SChris Mason different_trans = 1; 1006702ed49SChris Mason ret = btrfs_inc_ref(trans, root, buf); 1016702ed49SChris Mason if (ret) 1026702ed49SChris Mason return ret; 1036702ed49SChris Mason } else { 1046702ed49SChris Mason clean_tree_block(trans, root, buf); 1056702ed49SChris Mason } 1066702ed49SChris Mason 1076702ed49SChris Mason if (buf == root->node) { 1086702ed49SChris Mason root->node = cow; 1096702ed49SChris Mason get_bh(cow); 1106702ed49SChris Mason if (buf != root->commit_root) { 1116702ed49SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 1126702ed49SChris Mason } 1136702ed49SChris Mason btrfs_block_release(root, buf); 1146702ed49SChris Mason } else { 1156702ed49SChris Mason btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 1166702ed49SChris Mason bh_blocknr(cow)); 1176702ed49SChris Mason btrfs_mark_buffer_dirty(parent); 1186702ed49SChris Mason WARN_ON(btrfs_header_generation(btrfs_buffer_header(parent)) != 1196702ed49SChris Mason trans->transid); 1206702ed49SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 1216702ed49SChris Mason } 1226702ed49SChris Mason btrfs_block_release(root, buf); 1236702ed49SChris Mason btrfs_mark_buffer_dirty(cow); 1246702ed49SChris Mason *cow_ret = cow; 1256702ed49SChris Mason return 0; 1266702ed49SChris Mason } 1276702ed49SChris Mason 1286702ed49SChris Mason int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 129e20d96d6SChris Mason *root, struct buffer_head *buf, struct buffer_head 130e20d96d6SChris Mason *parent, int parent_slot, struct buffer_head 131e089f05cSChris Mason **cow_ret) 13202217ed2SChris Mason { 1336702ed49SChris Mason u64 search_start; 134ccd467d6SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 135ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 136ccd467d6SChris Mason root->fs_info->running_transaction->transid); 137ccd467d6SChris Mason WARN_ON(1); 138ccd467d6SChris Mason } 139ccd467d6SChris Mason if (trans->transid != root->fs_info->generation) { 140ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 141ccd467d6SChris Mason root->fs_info->generation); 142ccd467d6SChris Mason WARN_ON(1); 143ccd467d6SChris Mason } 1447f5c1516SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) == 1457f5c1516SChris Mason trans->transid) { 14602217ed2SChris Mason *cow_ret = buf; 14702217ed2SChris Mason return 0; 14802217ed2SChris Mason } 1496702ed49SChris Mason 1506702ed49SChris Mason search_start = bh_blocknr(buf) & ~((u64)65535); 1516702ed49SChris Mason return __btrfs_cow_block(trans, root, buf, parent, 1526702ed49SChris Mason parent_slot, cow_ret, search_start, 0); 1532c90e5d6SChris Mason } 1546702ed49SChris Mason 1556702ed49SChris Mason static int close_blocks(u64 blocknr, u64 other) 1566702ed49SChris Mason { 1576702ed49SChris Mason if (blocknr < other && other - blocknr < 8) 1586702ed49SChris Mason return 1; 1596702ed49SChris Mason if (blocknr > other && blocknr - other < 8) 1606702ed49SChris Mason return 1; 16102217ed2SChris Mason return 0; 16202217ed2SChris Mason } 16302217ed2SChris Mason 1642cc58cf2SChris Mason static int should_defrag_leaf(struct buffer_head *bh) 1652cc58cf2SChris Mason { 1662cc58cf2SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(bh); 1672cc58cf2SChris Mason struct btrfs_disk_key *key; 1682cc58cf2SChris Mason u32 nritems; 1692cc58cf2SChris Mason 1702cc58cf2SChris Mason if (buffer_defrag(bh)) 1712cc58cf2SChris Mason return 1; 1722cc58cf2SChris Mason 1732cc58cf2SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1742cc58cf2SChris Mason if (nritems == 0) 1752cc58cf2SChris Mason return 0; 1762cc58cf2SChris Mason 1772cc58cf2SChris Mason key = &leaf->items[0].key; 1782cc58cf2SChris Mason if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY) 1792cc58cf2SChris Mason return 1; 1802cc58cf2SChris Mason 1812cc58cf2SChris Mason key = &leaf->items[nritems-1].key; 1822cc58cf2SChris Mason if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY) 1832cc58cf2SChris Mason return 1; 1842cc58cf2SChris Mason if (nritems > 4) { 1852cc58cf2SChris Mason key = &leaf->items[nritems/2].key; 1862cc58cf2SChris Mason if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY) 1872cc58cf2SChris Mason return 1; 1882cc58cf2SChris Mason } 1892cc58cf2SChris Mason return 0; 1902cc58cf2SChris Mason } 1912cc58cf2SChris Mason 1926702ed49SChris Mason int btrfs_realloc_node(struct btrfs_trans_handle *trans, 1936702ed49SChris Mason struct btrfs_root *root, struct buffer_head *parent, 194e9d0b13bSChris Mason int cache_only, u64 *last_ret) 1956702ed49SChris Mason { 1966702ed49SChris Mason struct btrfs_node *parent_node; 1976702ed49SChris Mason struct buffer_head *cur_bh; 1986702ed49SChris Mason struct buffer_head *tmp_bh; 1996702ed49SChris Mason u64 blocknr; 200e9d0b13bSChris Mason u64 search_start = *last_ret; 201e9d0b13bSChris Mason u64 last_block = 0; 2026702ed49SChris Mason u64 other; 2036702ed49SChris Mason u32 parent_nritems; 2046702ed49SChris Mason int start_slot; 2056702ed49SChris Mason int end_slot; 2066702ed49SChris Mason int i; 2076702ed49SChris Mason int err = 0; 208f2183bdeSChris Mason int parent_level; 2096702ed49SChris Mason 2106702ed49SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 2116702ed49SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 2126702ed49SChris Mason root->fs_info->running_transaction->transid); 2136702ed49SChris Mason WARN_ON(1); 2146702ed49SChris Mason } 2156702ed49SChris Mason if (trans->transid != root->fs_info->generation) { 2166702ed49SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 2176702ed49SChris Mason root->fs_info->generation); 2186702ed49SChris Mason WARN_ON(1); 2196702ed49SChris Mason } 220*86479a04SChris Mason if (buffer_defrag_done(parent)) 221*86479a04SChris Mason return 0; 222*86479a04SChris Mason 2236702ed49SChris Mason parent_node = btrfs_buffer_node(parent); 2246702ed49SChris Mason parent_nritems = btrfs_header_nritems(&parent_node->header); 225f2183bdeSChris Mason parent_level = btrfs_header_level(&parent_node->header); 2266702ed49SChris Mason 2276702ed49SChris Mason start_slot = 0; 2286702ed49SChris Mason end_slot = parent_nritems; 2296702ed49SChris Mason 2306702ed49SChris Mason if (parent_nritems == 1) 2316702ed49SChris Mason return 0; 2326702ed49SChris Mason 2336702ed49SChris Mason for (i = start_slot; i < end_slot; i++) { 2346702ed49SChris Mason int close = 1; 2356702ed49SChris Mason blocknr = btrfs_node_blockptr(parent_node, i); 236e9d0b13bSChris Mason if (last_block == 0) 237e9d0b13bSChris Mason last_block = blocknr; 2386702ed49SChris Mason if (i > 0) { 2396702ed49SChris Mason other = btrfs_node_blockptr(parent_node, i - 1); 2406702ed49SChris Mason close = close_blocks(blocknr, other); 2416702ed49SChris Mason } 2426702ed49SChris Mason if (close && i < end_slot - 1) { 2436702ed49SChris Mason other = btrfs_node_blockptr(parent_node, i + 1); 2446702ed49SChris Mason close = close_blocks(blocknr, other); 2456702ed49SChris Mason } 246e9d0b13bSChris Mason if (close) { 247e9d0b13bSChris Mason last_block = blocknr; 2486702ed49SChris Mason continue; 249e9d0b13bSChris Mason } 2506702ed49SChris Mason 2516702ed49SChris Mason cur_bh = btrfs_find_tree_block(root, blocknr); 2526702ed49SChris Mason if (!cur_bh || !buffer_uptodate(cur_bh) || 2532cc58cf2SChris Mason buffer_locked(cur_bh) || 2542cc58cf2SChris Mason (parent_level != 1 && !buffer_defrag(cur_bh)) || 2552cc58cf2SChris Mason (parent_level == 1 && !should_defrag_leaf(cur_bh))) { 2566702ed49SChris Mason if (cache_only) { 2576702ed49SChris Mason brelse(cur_bh); 2586702ed49SChris Mason continue; 2596702ed49SChris Mason } 260f2183bdeSChris Mason if (!cur_bh || !buffer_uptodate(cur_bh) || 261f2183bdeSChris Mason buffer_locked(cur_bh)) { 2626702ed49SChris Mason brelse(cur_bh); 2636702ed49SChris Mason cur_bh = read_tree_block(root, blocknr); 2646702ed49SChris Mason } 265f2183bdeSChris Mason } 266e9d0b13bSChris Mason if (search_start == 0) 267e9d0b13bSChris Mason search_start = last_block & ~((u64)65535); 268e9d0b13bSChris Mason 2696702ed49SChris Mason err = __btrfs_cow_block(trans, root, cur_bh, parent, i, 2706702ed49SChris Mason &tmp_bh, search_start, 2716702ed49SChris Mason min(8, end_slot - i)); 272252c38f0SYan if (err) { 273252c38f0SYan brelse(cur_bh); 2746702ed49SChris Mason break; 275252c38f0SYan } 2766702ed49SChris Mason search_start = bh_blocknr(tmp_bh); 277f2183bdeSChris Mason *last_ret = search_start; 278f2183bdeSChris Mason if (parent_level == 1) 279f2183bdeSChris Mason clear_buffer_defrag(tmp_bh); 280*86479a04SChris Mason set_buffer_defrag_done(tmp_bh); 2816702ed49SChris Mason brelse(tmp_bh); 2826702ed49SChris Mason } 2836702ed49SChris Mason return err; 2846702ed49SChris Mason } 2856702ed49SChris Mason 28674123bd7SChris Mason /* 28774123bd7SChris Mason * The leaf data grows from end-to-front in the node. 28874123bd7SChris Mason * this returns the address of the start of the last item, 28974123bd7SChris Mason * which is the stop of the leaf data stack 29074123bd7SChris Mason */ 291123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 292123abc88SChris Mason struct btrfs_leaf *leaf) 293be0e5c09SChris Mason { 2947518a238SChris Mason u32 nr = btrfs_header_nritems(&leaf->header); 295be0e5c09SChris Mason if (nr == 0) 296123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 2970783fcfcSChris Mason return btrfs_item_offset(leaf->items + nr - 1); 298be0e5c09SChris Mason } 299be0e5c09SChris Mason 30074123bd7SChris Mason /* 30174123bd7SChris Mason * compare two keys in a memcmp fashion 30274123bd7SChris Mason */ 3039aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 304be0e5c09SChris Mason { 305e2fa7227SChris Mason struct btrfs_key k1; 306e2fa7227SChris Mason 307e2fa7227SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 308e2fa7227SChris Mason 309e2fa7227SChris Mason if (k1.objectid > k2->objectid) 310be0e5c09SChris Mason return 1; 311e2fa7227SChris Mason if (k1.objectid < k2->objectid) 312be0e5c09SChris Mason return -1; 313f254e52cSChris Mason if (k1.flags > k2->flags) 314f254e52cSChris Mason return 1; 315f254e52cSChris Mason if (k1.flags < k2->flags) 316f254e52cSChris Mason return -1; 31770b2befdSChris Mason if (k1.offset > k2->offset) 31870b2befdSChris Mason return 1; 31970b2befdSChris Mason if (k1.offset < k2->offset) 32070b2befdSChris Mason return -1; 321be0e5c09SChris Mason return 0; 322be0e5c09SChris Mason } 32374123bd7SChris Mason 324123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 325123abc88SChris Mason int level) 326aa5d6bedSChris Mason { 327234b63a0SChris Mason struct btrfs_node *parent = NULL; 328e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 329aa5d6bedSChris Mason int parent_slot; 3308d7be552SChris Mason int slot; 3318d7be552SChris Mason struct btrfs_key cpukey; 3327518a238SChris Mason u32 nritems = btrfs_header_nritems(&node->header); 333aa5d6bedSChris Mason 334aa5d6bedSChris Mason if (path->nodes[level + 1]) 335e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 336a1f39630SAneesh 3378d7be552SChris Mason slot = path->slots[level]; 3382cc58cf2SChris Mason BUG_ON(!buffer_uptodate(path->nodes[level])); 3397518a238SChris Mason BUG_ON(nritems == 0); 3407518a238SChris Mason if (parent) { 341e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 342a1f39630SAneesh 343a1f39630SAneesh parent_slot = path->slots[level + 1]; 344123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 345123abc88SChris Mason BUG_ON(memcmp(parent_key, &node->ptrs[0].key, 346e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 3471d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 3487518a238SChris Mason btrfs_header_blocknr(&node->header)); 349aa5d6bedSChris Mason } 350123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 3518d7be552SChris Mason if (slot != 0) { 3528d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key); 3538d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0); 3548d7be552SChris Mason } 3558d7be552SChris Mason if (slot < nritems - 1) { 3568d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key); 3578d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0); 358aa5d6bedSChris Mason } 359aa5d6bedSChris Mason return 0; 360aa5d6bedSChris Mason } 361aa5d6bedSChris Mason 362123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 363123abc88SChris Mason int level) 364aa5d6bedSChris Mason { 365e20d96d6SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); 366234b63a0SChris Mason struct btrfs_node *parent = NULL; 367aa5d6bedSChris Mason int parent_slot; 3688d7be552SChris Mason int slot = path->slots[0]; 3698d7be552SChris Mason struct btrfs_key cpukey; 3708d7be552SChris Mason 3717518a238SChris Mason u32 nritems = btrfs_header_nritems(&leaf->header); 372aa5d6bedSChris Mason 373aa5d6bedSChris Mason if (path->nodes[level + 1]) 374e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 375a1f39630SAneesh 376123abc88SChris Mason BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 3777518a238SChris Mason 3787518a238SChris Mason if (nritems == 0) 3797518a238SChris Mason return 0; 3807518a238SChris Mason 3817518a238SChris Mason if (parent) { 382e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 383a1f39630SAneesh 384a1f39630SAneesh parent_slot = path->slots[level + 1]; 385123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 3866702ed49SChris Mason 387aa5d6bedSChris Mason BUG_ON(memcmp(parent_key, &leaf->items[0].key, 388e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 3891d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 3907518a238SChris Mason btrfs_header_blocknr(&leaf->header)); 391aa5d6bedSChris Mason } 3928d7be552SChris Mason if (slot != 0) { 3938d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key); 3948d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0); 3958d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot - 1) != 3968d7be552SChris Mason btrfs_item_end(leaf->items + slot)); 397aa5d6bedSChris Mason } 3988d7be552SChris Mason if (slot < nritems - 1) { 3998d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key); 4008d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0); 4018d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot) != 4028d7be552SChris Mason btrfs_item_end(leaf->items + slot + 1)); 403aa5d6bedSChris Mason } 4048d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items) + 4058d7be552SChris Mason btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root)); 406aa5d6bedSChris Mason return 0; 407aa5d6bedSChris Mason } 408aa5d6bedSChris Mason 409123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 410123abc88SChris Mason int level) 411aa5d6bedSChris Mason { 4123eb0314dSChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 4133eb0314dSChris Mason if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, 4143eb0314dSChris Mason sizeof(node->header.fsid))) 4153eb0314dSChris Mason BUG(); 416aa5d6bedSChris Mason if (level == 0) 417123abc88SChris Mason return check_leaf(root, path, level); 418123abc88SChris Mason return check_node(root, path, level); 419aa5d6bedSChris Mason } 420aa5d6bedSChris Mason 42174123bd7SChris Mason /* 42274123bd7SChris Mason * search for key in the array p. items p are item_size apart 42374123bd7SChris Mason * and there are 'max' items in p 42474123bd7SChris Mason * the slot in the array is returned via slot, and it points to 42574123bd7SChris Mason * the place where you would insert key if it is not found in 42674123bd7SChris Mason * the array. 42774123bd7SChris Mason * 42874123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 42974123bd7SChris Mason */ 4309aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, 431be0e5c09SChris Mason int max, int *slot) 432be0e5c09SChris Mason { 433be0e5c09SChris Mason int low = 0; 434be0e5c09SChris Mason int high = max; 435be0e5c09SChris Mason int mid; 436be0e5c09SChris Mason int ret; 437e2fa7227SChris Mason struct btrfs_disk_key *tmp; 438be0e5c09SChris Mason 439be0e5c09SChris Mason while(low < high) { 440be0e5c09SChris Mason mid = (low + high) / 2; 441e2fa7227SChris Mason tmp = (struct btrfs_disk_key *)(p + mid * item_size); 442be0e5c09SChris Mason ret = comp_keys(tmp, key); 443be0e5c09SChris Mason 444be0e5c09SChris Mason if (ret < 0) 445be0e5c09SChris Mason low = mid + 1; 446be0e5c09SChris Mason else if (ret > 0) 447be0e5c09SChris Mason high = mid; 448be0e5c09SChris Mason else { 449be0e5c09SChris Mason *slot = mid; 450be0e5c09SChris Mason return 0; 451be0e5c09SChris Mason } 452be0e5c09SChris Mason } 453be0e5c09SChris Mason *slot = low; 454be0e5c09SChris Mason return 1; 455be0e5c09SChris Mason } 456be0e5c09SChris Mason 45797571fd0SChris Mason /* 45897571fd0SChris Mason * simple bin_search frontend that does the right thing for 45997571fd0SChris Mason * leaves vs nodes 46097571fd0SChris Mason */ 4619aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) 462be0e5c09SChris Mason { 4637518a238SChris Mason if (btrfs_is_leaf(c)) { 464234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 4650783fcfcSChris Mason return generic_bin_search((void *)l->items, 4660783fcfcSChris Mason sizeof(struct btrfs_item), 4677518a238SChris Mason key, btrfs_header_nritems(&c->header), 4687518a238SChris Mason slot); 469be0e5c09SChris Mason } else { 470123abc88SChris Mason return generic_bin_search((void *)c->ptrs, 471123abc88SChris Mason sizeof(struct btrfs_key_ptr), 4727518a238SChris Mason key, btrfs_header_nritems(&c->header), 4737518a238SChris Mason slot); 474be0e5c09SChris Mason } 475be0e5c09SChris Mason return -1; 476be0e5c09SChris Mason } 477be0e5c09SChris Mason 478e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root, 479e20d96d6SChris Mason struct buffer_head *parent_buf, 480bb803951SChris Mason int slot) 481bb803951SChris Mason { 482e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(parent_buf); 483bb803951SChris Mason if (slot < 0) 484bb803951SChris Mason return NULL; 4857518a238SChris Mason if (slot >= btrfs_header_nritems(&node->header)) 486bb803951SChris Mason return NULL; 4871d4f8a0cSChris Mason return read_tree_block(root, btrfs_node_blockptr(node, slot)); 488bb803951SChris Mason } 489bb803951SChris Mason 490e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 491e089f05cSChris Mason *root, struct btrfs_path *path, int level) 492bb803951SChris Mason { 493e20d96d6SChris Mason struct buffer_head *right_buf; 494e20d96d6SChris Mason struct buffer_head *mid_buf; 495e20d96d6SChris Mason struct buffer_head *left_buf; 496e20d96d6SChris Mason struct buffer_head *parent_buf = NULL; 497234b63a0SChris Mason struct btrfs_node *right = NULL; 498234b63a0SChris Mason struct btrfs_node *mid; 499234b63a0SChris Mason struct btrfs_node *left = NULL; 500234b63a0SChris Mason struct btrfs_node *parent = NULL; 501bb803951SChris Mason int ret = 0; 502bb803951SChris Mason int wret; 503bb803951SChris Mason int pslot; 504bb803951SChris Mason int orig_slot = path->slots[level]; 50554aa1f4dSChris Mason int err_on_enospc = 0; 50679f95c82SChris Mason u64 orig_ptr; 507bb803951SChris Mason 508bb803951SChris Mason if (level == 0) 509bb803951SChris Mason return 0; 510bb803951SChris Mason 511bb803951SChris Mason mid_buf = path->nodes[level]; 512e20d96d6SChris Mason mid = btrfs_buffer_node(mid_buf); 5131d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 51479f95c82SChris Mason 515234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 516bb803951SChris Mason parent_buf = path->nodes[level + 1]; 517bb803951SChris Mason pslot = path->slots[level + 1]; 518bb803951SChris Mason 51940689478SChris Mason /* 52040689478SChris Mason * deal with the case where there is only one pointer in the root 52140689478SChris Mason * by promoting the node below to a root 52240689478SChris Mason */ 523bb803951SChris Mason if (!parent_buf) { 524e20d96d6SChris Mason struct buffer_head *child; 5257eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 526bb803951SChris Mason 5277518a238SChris Mason if (btrfs_header_nritems(&mid->header) != 1) 528bb803951SChris Mason return 0; 529bb803951SChris Mason 530bb803951SChris Mason /* promote the child to a root */ 531bb803951SChris Mason child = read_node_slot(root, mid_buf, 0); 532bb803951SChris Mason BUG_ON(!child); 533bb803951SChris Mason root->node = child; 534bb803951SChris Mason path->nodes[level] = NULL; 535d6025579SChris Mason clean_tree_block(trans, root, mid_buf); 536d6025579SChris Mason wait_on_buffer(mid_buf); 537bb803951SChris Mason /* once for the path */ 538234b63a0SChris Mason btrfs_block_release(root, mid_buf); 539bb803951SChris Mason /* once for the root ptr */ 540234b63a0SChris Mason btrfs_block_release(root, mid_buf); 541e089f05cSChris Mason return btrfs_free_extent(trans, root, blocknr, 1, 1); 542bb803951SChris Mason } 543e20d96d6SChris Mason parent = btrfs_buffer_node(parent_buf); 544bb803951SChris Mason 545123abc88SChris Mason if (btrfs_header_nritems(&mid->header) > 546123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 547bb803951SChris Mason return 0; 548bb803951SChris Mason 54954aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 55054aa1f4dSChris Mason err_on_enospc = 1; 55154aa1f4dSChris Mason 552bb803951SChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 553bb803951SChris Mason if (left_buf) { 55454aa1f4dSChris Mason wret = btrfs_cow_block(trans, root, left_buf, 55554aa1f4dSChris Mason parent_buf, pslot - 1, &left_buf); 55654aa1f4dSChris Mason if (wret) { 55754aa1f4dSChris Mason ret = wret; 55854aa1f4dSChris Mason goto enospc; 55954aa1f4dSChris Mason } 5602cc58cf2SChris Mason } 5612cc58cf2SChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 5622cc58cf2SChris Mason if (right_buf) { 5632cc58cf2SChris Mason wret = btrfs_cow_block(trans, root, right_buf, 5642cc58cf2SChris Mason parent_buf, pslot + 1, &right_buf); 5652cc58cf2SChris Mason if (wret) { 5662cc58cf2SChris Mason ret = wret; 5672cc58cf2SChris Mason goto enospc; 5682cc58cf2SChris Mason } 5692cc58cf2SChris Mason } 5702cc58cf2SChris Mason 5712cc58cf2SChris Mason /* first, try to make some room in the middle buffer */ 5722cc58cf2SChris Mason if (left_buf) { 573e20d96d6SChris Mason left = btrfs_buffer_node(left_buf); 5747518a238SChris Mason orig_slot += btrfs_header_nritems(&left->header); 575e089f05cSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 57679f95c82SChris Mason if (wret < 0) 57779f95c82SChris Mason ret = wret; 57854aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 57954aa1f4dSChris Mason err_on_enospc = 1; 580bb803951SChris Mason } 58179f95c82SChris Mason 58279f95c82SChris Mason /* 58379f95c82SChris Mason * then try to empty the right most buffer into the middle 58479f95c82SChris Mason */ 585bb803951SChris Mason if (right_buf) { 586e20d96d6SChris Mason right = btrfs_buffer_node(right_buf); 587e089f05cSChris Mason wret = push_node_left(trans, root, mid_buf, right_buf); 58854aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 58979f95c82SChris Mason ret = wret; 5907518a238SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 5917eccb903SChris Mason u64 blocknr = bh_blocknr(right_buf); 592e089f05cSChris Mason clean_tree_block(trans, root, right_buf); 593d6025579SChris Mason wait_on_buffer(right_buf); 594d6025579SChris Mason btrfs_block_release(root, right_buf); 595bb803951SChris Mason right_buf = NULL; 596bb803951SChris Mason right = NULL; 597e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 598e089f05cSChris Mason 1); 599bb803951SChris Mason if (wret) 600bb803951SChris Mason ret = wret; 601e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 602bb803951SChris Mason if (wret) 603bb803951SChris Mason ret = wret; 604bb803951SChris Mason } else { 605d6025579SChris Mason btrfs_memcpy(root, parent, 606d6025579SChris Mason &parent->ptrs[pslot + 1].key, 607123abc88SChris Mason &right->ptrs[0].key, 608e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 609d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 610bb803951SChris Mason } 611bb803951SChris Mason } 6127518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 1) { 61379f95c82SChris Mason /* 61479f95c82SChris Mason * we're not allowed to leave a node with one item in the 61579f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 61679f95c82SChris Mason * could try to delete the only pointer in this node. 61779f95c82SChris Mason * So, pull some keys from the left. 61879f95c82SChris Mason * There has to be a left pointer at this point because 61979f95c82SChris Mason * otherwise we would have pulled some pointers from the 62079f95c82SChris Mason * right 62179f95c82SChris Mason */ 62279f95c82SChris Mason BUG_ON(!left_buf); 623e089f05cSChris Mason wret = balance_node_right(trans, root, mid_buf, left_buf); 62454aa1f4dSChris Mason if (wret < 0) { 62579f95c82SChris Mason ret = wret; 62654aa1f4dSChris Mason goto enospc; 62754aa1f4dSChris Mason } 62879f95c82SChris Mason BUG_ON(wret == 1); 62979f95c82SChris Mason } 6307518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 0) { 63179f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 6327eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 633e089f05cSChris Mason clean_tree_block(trans, root, mid_buf); 634d6025579SChris Mason wait_on_buffer(mid_buf); 635d6025579SChris Mason btrfs_block_release(root, mid_buf); 636bb803951SChris Mason mid_buf = NULL; 637bb803951SChris Mason mid = NULL; 638e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 639bb803951SChris Mason if (wret) 640bb803951SChris Mason ret = wret; 641e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 642bb803951SChris Mason if (wret) 643bb803951SChris Mason ret = wret; 64479f95c82SChris Mason } else { 64579f95c82SChris Mason /* update the parent key to reflect our changes */ 646d6025579SChris Mason btrfs_memcpy(root, parent, 647d6025579SChris Mason &parent->ptrs[pslot].key, &mid->ptrs[0].key, 648e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 649d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 65079f95c82SChris Mason } 651bb803951SChris Mason 65279f95c82SChris Mason /* update the path */ 653bb803951SChris Mason if (left_buf) { 6547518a238SChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 655e20d96d6SChris Mason get_bh(left_buf); 656bb803951SChris Mason path->nodes[level] = left_buf; 657bb803951SChris Mason path->slots[level + 1] -= 1; 658bb803951SChris Mason path->slots[level] = orig_slot; 659bb803951SChris Mason if (mid_buf) 660234b63a0SChris Mason btrfs_block_release(root, mid_buf); 661bb803951SChris Mason } else { 6627518a238SChris Mason orig_slot -= btrfs_header_nritems(&left->header); 663bb803951SChris Mason path->slots[level] = orig_slot; 664bb803951SChris Mason } 665bb803951SChris Mason } 66679f95c82SChris Mason /* double check we haven't messed things up */ 667123abc88SChris Mason check_block(root, path, level); 668e20d96d6SChris Mason if (orig_ptr != 669e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 6701d4f8a0cSChris Mason path->slots[level])) 67179f95c82SChris Mason BUG(); 67254aa1f4dSChris Mason enospc: 673bb803951SChris Mason if (right_buf) 674234b63a0SChris Mason btrfs_block_release(root, right_buf); 675bb803951SChris Mason if (left_buf) 676234b63a0SChris Mason btrfs_block_release(root, left_buf); 677bb803951SChris Mason return ret; 678bb803951SChris Mason } 679bb803951SChris Mason 680e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 681e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 682e66f709bSChris Mason struct btrfs_root *root, 683e66f709bSChris Mason struct btrfs_path *path, int level) 684e66f709bSChris Mason { 685e66f709bSChris Mason struct buffer_head *right_buf; 686e66f709bSChris Mason struct buffer_head *mid_buf; 687e66f709bSChris Mason struct buffer_head *left_buf; 688e66f709bSChris Mason struct buffer_head *parent_buf = NULL; 689e66f709bSChris Mason struct btrfs_node *right = NULL; 690e66f709bSChris Mason struct btrfs_node *mid; 691e66f709bSChris Mason struct btrfs_node *left = NULL; 692e66f709bSChris Mason struct btrfs_node *parent = NULL; 693e66f709bSChris Mason int ret = 0; 694e66f709bSChris Mason int wret; 695e66f709bSChris Mason int pslot; 696e66f709bSChris Mason int orig_slot = path->slots[level]; 697e66f709bSChris Mason u64 orig_ptr; 698e66f709bSChris Mason 699e66f709bSChris Mason if (level == 0) 700e66f709bSChris Mason return 1; 701e66f709bSChris Mason 702e66f709bSChris Mason mid_buf = path->nodes[level]; 703e66f709bSChris Mason mid = btrfs_buffer_node(mid_buf); 704e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 705e66f709bSChris Mason 706e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 707e66f709bSChris Mason parent_buf = path->nodes[level + 1]; 708e66f709bSChris Mason pslot = path->slots[level + 1]; 709e66f709bSChris Mason 710e66f709bSChris Mason if (!parent_buf) 711e66f709bSChris Mason return 1; 712e66f709bSChris Mason parent = btrfs_buffer_node(parent_buf); 713e66f709bSChris Mason 714e66f709bSChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 715e66f709bSChris Mason 716e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 717e66f709bSChris Mason if (left_buf) { 718e66f709bSChris Mason u32 left_nr; 719e66f709bSChris Mason left = btrfs_buffer_node(left_buf); 720e66f709bSChris Mason left_nr = btrfs_header_nritems(&left->header); 72133ade1f8SChris Mason if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 72233ade1f8SChris Mason wret = 1; 72333ade1f8SChris Mason } else { 72454aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, left_buf, parent_buf, 72533ade1f8SChris Mason pslot - 1, &left_buf); 72654aa1f4dSChris Mason if (ret) 72754aa1f4dSChris Mason wret = 1; 72854aa1f4dSChris Mason else { 72933ade1f8SChris Mason left = btrfs_buffer_node(left_buf); 73054aa1f4dSChris Mason wret = push_node_left(trans, root, 73154aa1f4dSChris Mason left_buf, mid_buf); 73254aa1f4dSChris Mason } 73333ade1f8SChris Mason } 734e66f709bSChris Mason if (wret < 0) 735e66f709bSChris Mason ret = wret; 736e66f709bSChris Mason if (wret == 0) { 737e66f709bSChris Mason orig_slot += left_nr; 738e66f709bSChris Mason btrfs_memcpy(root, parent, 739e66f709bSChris Mason &parent->ptrs[pslot].key, 740e66f709bSChris Mason &mid->ptrs[0].key, 741e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 742e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 743e66f709bSChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 744e66f709bSChris Mason path->nodes[level] = left_buf; 745e66f709bSChris Mason path->slots[level + 1] -= 1; 746e66f709bSChris Mason path->slots[level] = orig_slot; 747e66f709bSChris Mason btrfs_block_release(root, mid_buf); 748e66f709bSChris Mason } else { 749e66f709bSChris Mason orig_slot -= 750e66f709bSChris Mason btrfs_header_nritems(&left->header); 751e66f709bSChris Mason path->slots[level] = orig_slot; 752e66f709bSChris Mason btrfs_block_release(root, left_buf); 753e66f709bSChris Mason } 754e66f709bSChris Mason check_node(root, path, level); 755e66f709bSChris Mason return 0; 756e66f709bSChris Mason } 757e66f709bSChris Mason btrfs_block_release(root, left_buf); 758e66f709bSChris Mason } 759e66f709bSChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 760e66f709bSChris Mason 761e66f709bSChris Mason /* 762e66f709bSChris Mason * then try to empty the right most buffer into the middle 763e66f709bSChris Mason */ 764e66f709bSChris Mason if (right_buf) { 76533ade1f8SChris Mason u32 right_nr; 766e66f709bSChris Mason right = btrfs_buffer_node(right_buf); 76733ade1f8SChris Mason right_nr = btrfs_header_nritems(&right->header); 76833ade1f8SChris Mason if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 76933ade1f8SChris Mason wret = 1; 77033ade1f8SChris Mason } else { 77154aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, 77254aa1f4dSChris Mason parent_buf, pslot + 1, 77354aa1f4dSChris Mason &right_buf); 77454aa1f4dSChris Mason if (ret) 77554aa1f4dSChris Mason wret = 1; 77654aa1f4dSChris Mason else { 77733ade1f8SChris Mason right = btrfs_buffer_node(right_buf); 77833ade1f8SChris Mason wret = balance_node_right(trans, root, 77933ade1f8SChris Mason right_buf, mid_buf); 78033ade1f8SChris Mason } 78154aa1f4dSChris Mason } 782e66f709bSChris Mason if (wret < 0) 783e66f709bSChris Mason ret = wret; 784e66f709bSChris Mason if (wret == 0) { 785e66f709bSChris Mason btrfs_memcpy(root, parent, 786e66f709bSChris Mason &parent->ptrs[pslot + 1].key, 787e66f709bSChris Mason &right->ptrs[0].key, 788e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 789e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 790e66f709bSChris Mason if (btrfs_header_nritems(&mid->header) <= orig_slot) { 791e66f709bSChris Mason path->nodes[level] = right_buf; 792e66f709bSChris Mason path->slots[level + 1] += 1; 793e66f709bSChris Mason path->slots[level] = orig_slot - 794e66f709bSChris Mason btrfs_header_nritems(&mid->header); 795e66f709bSChris Mason btrfs_block_release(root, mid_buf); 796e66f709bSChris Mason } else { 797e66f709bSChris Mason btrfs_block_release(root, right_buf); 798e66f709bSChris Mason } 799e66f709bSChris Mason check_node(root, path, level); 800e66f709bSChris Mason return 0; 801e66f709bSChris Mason } 802e66f709bSChris Mason btrfs_block_release(root, right_buf); 803e66f709bSChris Mason } 804e66f709bSChris Mason check_node(root, path, level); 805e66f709bSChris Mason return 1; 806e66f709bSChris Mason } 807e66f709bSChris Mason 80874123bd7SChris Mason /* 8093c69faecSChris Mason * readahead one full node of leaves 8103c69faecSChris Mason */ 8113c69faecSChris Mason static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, 8126702ed49SChris Mason int level, int slot) 8133c69faecSChris Mason { 8143c69faecSChris Mason struct btrfs_node *node; 8153c69faecSChris Mason int i; 8163c69faecSChris Mason u32 nritems; 8173c69faecSChris Mason u64 item_objectid; 8183c69faecSChris Mason u64 blocknr; 8193c69faecSChris Mason u64 search; 8203c69faecSChris Mason u64 cluster_start; 8213c69faecSChris Mason int ret; 8223c69faecSChris Mason int nread = 0; 8233c69faecSChris Mason int direction = path->reada; 8243c69faecSChris Mason struct radix_tree_root found; 8253c69faecSChris Mason unsigned long gang[8]; 8263c69faecSChris Mason struct buffer_head *bh; 8273c69faecSChris Mason 8286702ed49SChris Mason if (level == 0) 8293c69faecSChris Mason return; 8303c69faecSChris Mason 8316702ed49SChris Mason if (!path->nodes[level]) 8326702ed49SChris Mason return; 8336702ed49SChris Mason 8346702ed49SChris Mason node = btrfs_buffer_node(path->nodes[level]); 8353c69faecSChris Mason search = btrfs_node_blockptr(node, slot); 8363c69faecSChris Mason bh = btrfs_find_tree_block(root, search); 8373c69faecSChris Mason if (bh) { 8383c69faecSChris Mason brelse(bh); 8393c69faecSChris Mason return; 8403c69faecSChris Mason } 8413c69faecSChris Mason 8423c69faecSChris Mason init_bit_radix(&found); 8433c69faecSChris Mason nritems = btrfs_header_nritems(&node->header); 8443c69faecSChris Mason for (i = slot; i < nritems; i++) { 8453c69faecSChris Mason item_objectid = btrfs_disk_key_objectid(&node->ptrs[i].key); 8463c69faecSChris Mason blocknr = btrfs_node_blockptr(node, i); 8473c69faecSChris Mason set_radix_bit(&found, blocknr); 8483c69faecSChris Mason } 8493c69faecSChris Mason if (direction > 0) { 8503c69faecSChris Mason cluster_start = search - 4; 8513c69faecSChris Mason if (cluster_start > search) 8523c69faecSChris Mason cluster_start = 0; 8533c69faecSChris Mason } else 8543c69faecSChris Mason cluster_start = search + 4; 8553c69faecSChris Mason while(1) { 8563c69faecSChris Mason ret = find_first_radix_bit(&found, gang, 0, ARRAY_SIZE(gang)); 8573c69faecSChris Mason if (!ret) 8583c69faecSChris Mason break; 8593c69faecSChris Mason for (i = 0; i < ret; i++) { 8603c69faecSChris Mason blocknr = gang[i]; 8613c69faecSChris Mason clear_radix_bit(&found, blocknr); 8622cc58cf2SChris Mason if (path->reada == 1 && nread > 16) 8633c69faecSChris Mason continue; 864f2183bdeSChris Mason if (close_blocks(cluster_start, blocknr)) { 8653c69faecSChris Mason readahead_tree_block(root, blocknr); 8663c69faecSChris Mason nread++; 8673c69faecSChris Mason cluster_start = blocknr; 8683c69faecSChris Mason } 8693c69faecSChris Mason } 8703c69faecSChris Mason } 8713c69faecSChris Mason } 8723c69faecSChris Mason /* 87374123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 87474123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 87574123bd7SChris Mason * level of the path (level 0) 87674123bd7SChris Mason * 87774123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 878aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 879aa5d6bedSChris Mason * search a negative error number is returned. 88097571fd0SChris Mason * 88197571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 88297571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 88397571fd0SChris Mason * possible) 88474123bd7SChris Mason */ 885e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 886e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 887e089f05cSChris Mason ins_len, int cow) 888be0e5c09SChris Mason { 889e20d96d6SChris Mason struct buffer_head *b; 890234b63a0SChris Mason struct btrfs_node *c; 8913c69faecSChris Mason u64 blocknr; 892be0e5c09SChris Mason int slot; 893be0e5c09SChris Mason int ret; 894be0e5c09SChris Mason int level; 8953c69faecSChris Mason int should_reada = p->reada; 8969f3a7427SChris Mason u8 lowest_level = 0; 8979f3a7427SChris Mason 8986702ed49SChris Mason lowest_level = p->lowest_level; 8996702ed49SChris Mason WARN_ON(lowest_level && ins_len); 90022b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 90122b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 902bb803951SChris Mason again: 903bb803951SChris Mason b = root->node; 904e20d96d6SChris Mason get_bh(b); 905eb60ceacSChris Mason while (b) { 906e20d96d6SChris Mason c = btrfs_buffer_node(b); 907e20d96d6SChris Mason level = btrfs_header_level(&c->header); 90802217ed2SChris Mason if (cow) { 90902217ed2SChris Mason int wret; 910e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 911e20d96d6SChris Mason p->nodes[level + 1], 912e20d96d6SChris Mason p->slots[level + 1], 913252c38f0SYan &b); 91454aa1f4dSChris Mason if (wret) { 915252c38f0SYan btrfs_block_release(root, b); 91654aa1f4dSChris Mason return wret; 91754aa1f4dSChris Mason } 9182c90e5d6SChris Mason c = btrfs_buffer_node(b); 91902217ed2SChris Mason } 92002217ed2SChris Mason BUG_ON(!cow && ins_len); 9212c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 9222c90e5d6SChris Mason WARN_ON(1); 9232c90e5d6SChris Mason level = btrfs_header_level(&c->header); 924eb60ceacSChris Mason p->nodes[level] = b; 925123abc88SChris Mason ret = check_block(root, p, level); 926aa5d6bedSChris Mason if (ret) 927aa5d6bedSChris Mason return -1; 928be0e5c09SChris Mason ret = bin_search(c, key, &slot); 9297518a238SChris Mason if (!btrfs_is_leaf(c)) { 930be0e5c09SChris Mason if (ret && slot > 0) 931be0e5c09SChris Mason slot -= 1; 932be0e5c09SChris Mason p->slots[level] = slot; 933d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 934d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 935e089f05cSChris Mason int sret = split_node(trans, root, p, level); 9365c680ed6SChris Mason BUG_ON(sret > 0); 9375c680ed6SChris Mason if (sret) 9385c680ed6SChris Mason return sret; 9395c680ed6SChris Mason b = p->nodes[level]; 940e20d96d6SChris Mason c = btrfs_buffer_node(b); 9415c680ed6SChris Mason slot = p->slots[level]; 942bb803951SChris Mason } else if (ins_len < 0) { 943e089f05cSChris Mason int sret = balance_level(trans, root, p, 944e089f05cSChris Mason level); 945bb803951SChris Mason if (sret) 946bb803951SChris Mason return sret; 947bb803951SChris Mason b = p->nodes[level]; 948bb803951SChris Mason if (!b) 949bb803951SChris Mason goto again; 950e20d96d6SChris Mason c = btrfs_buffer_node(b); 951bb803951SChris Mason slot = p->slots[level]; 9527518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 9535c680ed6SChris Mason } 9549f3a7427SChris Mason /* this is only true while dropping a snapshot */ 9559f3a7427SChris Mason if (level == lowest_level) 9569f3a7427SChris Mason break; 9573c69faecSChris Mason blocknr = btrfs_node_blockptr(c, slot); 9586702ed49SChris Mason if (should_reada) 9596702ed49SChris Mason reada_for_search(root, p, level, slot); 9601d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 9613c69faecSChris Mason 962be0e5c09SChris Mason } else { 963234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 964be0e5c09SChris Mason p->slots[level] = slot; 965123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 9660783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 967d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 968d4dbff95SChris Mason p, ins_len); 9695c680ed6SChris Mason BUG_ON(sret > 0); 9705c680ed6SChris Mason if (sret) 9715c680ed6SChris Mason return sret; 9725c680ed6SChris Mason } 973be0e5c09SChris Mason return ret; 974be0e5c09SChris Mason } 975be0e5c09SChris Mason } 976aa5d6bedSChris Mason return 1; 977be0e5c09SChris Mason } 978be0e5c09SChris Mason 97974123bd7SChris Mason /* 98074123bd7SChris Mason * adjust the pointers going up the tree, starting at level 98174123bd7SChris Mason * making sure the right key of each node is points to 'key'. 98274123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 98374123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 98474123bd7SChris Mason * higher levels 985aa5d6bedSChris Mason * 986aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 987aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 98874123bd7SChris Mason */ 989e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 990e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 991e089f05cSChris Mason *key, int level) 992be0e5c09SChris Mason { 993be0e5c09SChris Mason int i; 994aa5d6bedSChris Mason int ret = 0; 995234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 996234b63a0SChris Mason struct btrfs_node *t; 997be0e5c09SChris Mason int tslot = path->slots[i]; 998eb60ceacSChris Mason if (!path->nodes[i]) 999be0e5c09SChris Mason break; 1000e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 1001d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 1002d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 1003be0e5c09SChris Mason if (tslot != 0) 1004be0e5c09SChris Mason break; 1005be0e5c09SChris Mason } 1006aa5d6bedSChris Mason return ret; 1007be0e5c09SChris Mason } 1008be0e5c09SChris Mason 100974123bd7SChris Mason /* 101074123bd7SChris Mason * try to push data from one node into the next node left in the 101179f95c82SChris Mason * tree. 1012aa5d6bedSChris Mason * 1013aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 1014aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 101574123bd7SChris Mason */ 1016e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 1017e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 1018e20d96d6SChris Mason buffer_head *src_buf) 1019be0e5c09SChris Mason { 1020e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 1021e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 1022be0e5c09SChris Mason int push_items = 0; 1023bb803951SChris Mason int src_nritems; 1024bb803951SChris Mason int dst_nritems; 1025aa5d6bedSChris Mason int ret = 0; 1026be0e5c09SChris Mason 10277518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 10287518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 1029123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 103054aa1f4dSChris Mason 1031eb60ceacSChris Mason if (push_items <= 0) { 1032be0e5c09SChris Mason return 1; 1033eb60ceacSChris Mason } 1034be0e5c09SChris Mason 1035be0e5c09SChris Mason if (src_nritems < push_items) 1036be0e5c09SChris Mason push_items = src_nritems; 103779f95c82SChris Mason 1038d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 1039123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 1040bb803951SChris Mason if (push_items < src_nritems) { 1041d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 1042e2fa7227SChris Mason (src_nritems - push_items) * 1043123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 1044bb803951SChris Mason } 10457518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 10467518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 1047d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 1048d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 1049bb803951SChris Mason return ret; 1050be0e5c09SChris Mason } 1051be0e5c09SChris Mason 105297571fd0SChris Mason /* 105379f95c82SChris Mason * try to push data from one node into the next node right in the 105479f95c82SChris Mason * tree. 105579f95c82SChris Mason * 105679f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 105779f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 105879f95c82SChris Mason * 105979f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 106079f95c82SChris Mason */ 1061e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 1062e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 1063e20d96d6SChris Mason struct buffer_head *src_buf) 106479f95c82SChris Mason { 1065e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 1066e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 106779f95c82SChris Mason int push_items = 0; 106879f95c82SChris Mason int max_push; 106979f95c82SChris Mason int src_nritems; 107079f95c82SChris Mason int dst_nritems; 107179f95c82SChris Mason int ret = 0; 107279f95c82SChris Mason 10737518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 10747518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 1075123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 107679f95c82SChris Mason if (push_items <= 0) { 107779f95c82SChris Mason return 1; 107879f95c82SChris Mason } 107979f95c82SChris Mason 108079f95c82SChris Mason max_push = src_nritems / 2 + 1; 108179f95c82SChris Mason /* don't try to empty the node */ 1082252c38f0SYan if (max_push >= src_nritems) 108379f95c82SChris Mason return 1; 1084252c38f0SYan 108579f95c82SChris Mason if (max_push < push_items) 108679f95c82SChris Mason push_items = max_push; 108779f95c82SChris Mason 1088d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 1089123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 1090d6025579SChris Mason 1091d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 1092d6025579SChris Mason src->ptrs + src_nritems - push_items, 1093123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 109479f95c82SChris Mason 10957518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 10967518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 109779f95c82SChris Mason 1098d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 1099d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 110079f95c82SChris Mason return ret; 110179f95c82SChris Mason } 110279f95c82SChris Mason 110379f95c82SChris Mason /* 110497571fd0SChris Mason * helper function to insert a new root level in the tree. 110597571fd0SChris Mason * A new node is allocated, and a single item is inserted to 110697571fd0SChris Mason * point to the existing root 1107aa5d6bedSChris Mason * 1108aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 110997571fd0SChris Mason */ 1110e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 1111e089f05cSChris Mason *root, struct btrfs_path *path, int level) 111274123bd7SChris Mason { 1113e20d96d6SChris Mason struct buffer_head *t; 1114234b63a0SChris Mason struct btrfs_node *lower; 1115234b63a0SChris Mason struct btrfs_node *c; 1116e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 11175c680ed6SChris Mason 11185c680ed6SChris Mason BUG_ON(path->nodes[level]); 11195c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 11205c680ed6SChris Mason 11216702ed49SChris Mason t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr, 0); 112254aa1f4dSChris Mason if (IS_ERR(t)) 112354aa1f4dSChris Mason return PTR_ERR(t); 1124e20d96d6SChris Mason c = btrfs_buffer_node(t); 1125123abc88SChris Mason memset(c, 0, root->blocksize); 11267518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 11277518a238SChris Mason btrfs_set_header_level(&c->header, level); 11287eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 11297f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 11304d775673SChris Mason btrfs_set_header_owner(&c->header, root->root_key.objectid); 1131e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 11323eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 11333eb0314dSChris Mason sizeof(c->header.fsid)); 11347518a238SChris Mason if (btrfs_is_leaf(lower)) 1135234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 113674123bd7SChris Mason else 1137123abc88SChris Mason lower_key = &lower->ptrs[0].key; 1138d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 1139d6025579SChris Mason sizeof(struct btrfs_disk_key)); 11407eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 1141d5719762SChris Mason 1142d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1143d5719762SChris Mason 1144cfaa7295SChris Mason /* the super has an extra ref to root->node */ 1145234b63a0SChris Mason btrfs_block_release(root, root->node); 114674123bd7SChris Mason root->node = t; 1147e20d96d6SChris Mason get_bh(t); 114874123bd7SChris Mason path->nodes[level] = t; 114974123bd7SChris Mason path->slots[level] = 0; 115074123bd7SChris Mason return 0; 115174123bd7SChris Mason } 11525c680ed6SChris Mason 11535c680ed6SChris Mason /* 11545c680ed6SChris Mason * worker function to insert a single pointer in a node. 11555c680ed6SChris Mason * the node should have enough room for the pointer already 115697571fd0SChris Mason * 11575c680ed6SChris Mason * slot and level indicate where you want the key to go, and 11585c680ed6SChris Mason * blocknr is the block the key points to. 1159aa5d6bedSChris Mason * 1160aa5d6bedSChris Mason * returns zero on success and < 0 on any error 11615c680ed6SChris Mason */ 1162e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 1163e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 1164e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 11655c680ed6SChris Mason { 1166234b63a0SChris Mason struct btrfs_node *lower; 11675c680ed6SChris Mason int nritems; 11685c680ed6SChris Mason 11695c680ed6SChris Mason BUG_ON(!path->nodes[level]); 1170e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 11717518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 117274123bd7SChris Mason if (slot > nritems) 117374123bd7SChris Mason BUG(); 1174123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 117574123bd7SChris Mason BUG(); 117674123bd7SChris Mason if (slot != nritems) { 1177d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 1178d6025579SChris Mason lower->ptrs + slot, 1179123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 118074123bd7SChris Mason } 1181d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 1182d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 11831d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 11847518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 1185d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 1186098f59c2SChris Mason check_node(root, path, level); 118774123bd7SChris Mason return 0; 118874123bd7SChris Mason } 118974123bd7SChris Mason 119097571fd0SChris Mason /* 119197571fd0SChris Mason * split the node at the specified level in path in two. 119297571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 119397571fd0SChris Mason * 119497571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 119597571fd0SChris Mason * left and right, if either one works, it returns right away. 1196aa5d6bedSChris Mason * 1197aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 119897571fd0SChris Mason */ 1199e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 1200e089f05cSChris Mason *root, struct btrfs_path *path, int level) 1201be0e5c09SChris Mason { 1202e20d96d6SChris Mason struct buffer_head *t; 1203234b63a0SChris Mason struct btrfs_node *c; 1204e20d96d6SChris Mason struct buffer_head *split_buffer; 1205234b63a0SChris Mason struct btrfs_node *split; 1206be0e5c09SChris Mason int mid; 12075c680ed6SChris Mason int ret; 1208aa5d6bedSChris Mason int wret; 12097518a238SChris Mason u32 c_nritems; 1210be0e5c09SChris Mason 12115c680ed6SChris Mason t = path->nodes[level]; 1212e20d96d6SChris Mason c = btrfs_buffer_node(t); 12135c680ed6SChris Mason if (t == root->node) { 12145c680ed6SChris Mason /* trying to split the root, lets make a new one */ 1215e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 12165c680ed6SChris Mason if (ret) 12175c680ed6SChris Mason return ret; 1218e66f709bSChris Mason } else { 1219e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 1220e66f709bSChris Mason t = path->nodes[level]; 1221e66f709bSChris Mason c = btrfs_buffer_node(t); 1222e66f709bSChris Mason if (!ret && 1223e66f709bSChris Mason btrfs_header_nritems(&c->header) < 1224e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 1225e66f709bSChris Mason return 0; 122654aa1f4dSChris Mason if (ret < 0) 122754aa1f4dSChris Mason return ret; 12285c680ed6SChris Mason } 1229e66f709bSChris Mason 12307518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 12316702ed49SChris Mason split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr, 0); 123254aa1f4dSChris Mason if (IS_ERR(split_buffer)) 123354aa1f4dSChris Mason return PTR_ERR(split_buffer); 123454aa1f4dSChris Mason 1235e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 12367518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 12379a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 12387eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 12397f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 12404d775673SChris Mason btrfs_set_header_owner(&split->header, root->root_key.objectid); 12413eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 12423eb0314dSChris Mason sizeof(split->header.fsid)); 12437518a238SChris Mason mid = (c_nritems + 1) / 2; 1244d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 1245123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 12467518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 12477518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 1248aa5d6bedSChris Mason ret = 0; 1249aa5d6bedSChris Mason 1250d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1251d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 1252e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 12537eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 1254123abc88SChris Mason level + 1); 1255aa5d6bedSChris Mason if (wret) 1256aa5d6bedSChris Mason ret = wret; 1257aa5d6bedSChris Mason 12585de08d7dSChris Mason if (path->slots[level] >= mid) { 12595c680ed6SChris Mason path->slots[level] -= mid; 1260234b63a0SChris Mason btrfs_block_release(root, t); 12615c680ed6SChris Mason path->nodes[level] = split_buffer; 12625c680ed6SChris Mason path->slots[level + 1] += 1; 1263eb60ceacSChris Mason } else { 1264234b63a0SChris Mason btrfs_block_release(root, split_buffer); 1265be0e5c09SChris Mason } 1266aa5d6bedSChris Mason return ret; 1267be0e5c09SChris Mason } 1268be0e5c09SChris Mason 126974123bd7SChris Mason /* 127074123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 127174123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 127274123bd7SChris Mason * space used both by the item structs and the item data 127374123bd7SChris Mason */ 1274234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 1275be0e5c09SChris Mason { 1276be0e5c09SChris Mason int data_len; 1277d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 1278d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 1279be0e5c09SChris Mason 1280be0e5c09SChris Mason if (!nr) 1281be0e5c09SChris Mason return 0; 12820783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 12830783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 12840783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 1285d4dbff95SChris Mason WARN_ON(data_len < 0); 1286be0e5c09SChris Mason return data_len; 1287be0e5c09SChris Mason } 1288be0e5c09SChris Mason 128974123bd7SChris Mason /* 1290d4dbff95SChris Mason * The space between the end of the leaf items and 1291d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 1292d4dbff95SChris Mason * the leaf has left for both items and data 1293d4dbff95SChris Mason */ 1294d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 1295d4dbff95SChris Mason { 1296d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 1297d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 1298d4dbff95SChris Mason } 1299d4dbff95SChris Mason 1300d4dbff95SChris Mason /* 130100ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 130200ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 1303aa5d6bedSChris Mason * 1304aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 1305aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 130600ec4c51SChris Mason */ 1307e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 1308e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 130900ec4c51SChris Mason { 1310e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 1311e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 1312234b63a0SChris Mason struct btrfs_leaf *right; 1313e20d96d6SChris Mason struct buffer_head *right_buf; 1314e20d96d6SChris Mason struct buffer_head *upper; 1315e20d96d6SChris Mason struct btrfs_node *upper_node; 131600ec4c51SChris Mason int slot; 131700ec4c51SChris Mason int i; 131800ec4c51SChris Mason int free_space; 131900ec4c51SChris Mason int push_space = 0; 132000ec4c51SChris Mason int push_items = 0; 13210783fcfcSChris Mason struct btrfs_item *item; 13227518a238SChris Mason u32 left_nritems; 13237518a238SChris Mason u32 right_nritems; 132454aa1f4dSChris Mason int ret; 132500ec4c51SChris Mason 132600ec4c51SChris Mason slot = path->slots[1]; 132700ec4c51SChris Mason if (!path->nodes[1]) { 132800ec4c51SChris Mason return 1; 132900ec4c51SChris Mason } 133000ec4c51SChris Mason upper = path->nodes[1]; 1331e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1332e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 133300ec4c51SChris Mason return 1; 133400ec4c51SChris Mason } 1335e20d96d6SChris Mason right_buf = read_tree_block(root, 1336e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 1337e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1338123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 13390783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1340234b63a0SChris Mason btrfs_block_release(root, right_buf); 134100ec4c51SChris Mason return 1; 134200ec4c51SChris Mason } 134302217ed2SChris Mason /* cow and double check */ 134454aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, upper, 134554aa1f4dSChris Mason slot + 1, &right_buf); 134654aa1f4dSChris Mason if (ret) { 134754aa1f4dSChris Mason btrfs_block_release(root, right_buf); 134854aa1f4dSChris Mason return 1; 134954aa1f4dSChris Mason } 1350e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1351123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 13520783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1353234b63a0SChris Mason btrfs_block_release(root, right_buf); 135402217ed2SChris Mason return 1; 135502217ed2SChris Mason } 135602217ed2SChris Mason 13577518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1358a429e513SChris Mason if (left_nritems == 0) { 1359a429e513SChris Mason btrfs_block_release(root, right_buf); 1360a429e513SChris Mason return 1; 1361a429e513SChris Mason } 1362a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 136300ec4c51SChris Mason item = left->items + i; 136400ec4c51SChris Mason if (path->slots[0] == i) 136500ec4c51SChris Mason push_space += data_size + sizeof(*item); 13660783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 13670783fcfcSChris Mason free_space) 136800ec4c51SChris Mason break; 136900ec4c51SChris Mason push_items++; 13700783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 137100ec4c51SChris Mason } 137200ec4c51SChris Mason if (push_items == 0) { 1373234b63a0SChris Mason btrfs_block_release(root, right_buf); 137400ec4c51SChris Mason return 1; 137500ec4c51SChris Mason } 1376a429e513SChris Mason if (push_items == left_nritems) 1377a429e513SChris Mason WARN_ON(1); 13787518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 137900ec4c51SChris Mason /* push left to right */ 13800783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1381123abc88SChris Mason push_space -= leaf_data_end(root, left); 138200ec4c51SChris Mason /* make room in the right data area */ 1383d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1384d6025579SChris Mason leaf_data_end(root, right) - push_space, 1385d6025579SChris Mason btrfs_leaf_data(right) + 1386d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1387d6025579SChris Mason leaf_data_end(root, right)); 138800ec4c51SChris Mason /* copy from the left data area */ 1389d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1390d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1391d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1392d6025579SChris Mason push_space); 1393d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 13940783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 139500ec4c51SChris Mason /* copy the items from left to right */ 1396d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1397d6025579SChris Mason left_nritems - push_items, 13980783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 139900ec4c51SChris Mason 140000ec4c51SChris Mason /* update the item pointers */ 14017518a238SChris Mason right_nritems += push_items; 14027518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1403123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 14047518a238SChris Mason for (i = 0; i < right_nritems; i++) { 14050783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 14060783fcfcSChris Mason btrfs_item_size(right->items + i)); 14070783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 140800ec4c51SChris Mason } 14097518a238SChris Mason left_nritems -= push_items; 14107518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 141100ec4c51SChris Mason 1412d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1413d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1414a429e513SChris Mason 1415d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1416e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1417d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 141802217ed2SChris Mason 141900ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 14207518a238SChris Mason if (path->slots[0] >= left_nritems) { 14217518a238SChris Mason path->slots[0] -= left_nritems; 1422234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 142300ec4c51SChris Mason path->nodes[0] = right_buf; 142400ec4c51SChris Mason path->slots[1] += 1; 142500ec4c51SChris Mason } else { 1426234b63a0SChris Mason btrfs_block_release(root, right_buf); 142700ec4c51SChris Mason } 1428098f59c2SChris Mason if (path->nodes[1]) 1429098f59c2SChris Mason check_node(root, path, 1); 143000ec4c51SChris Mason return 0; 143100ec4c51SChris Mason } 143200ec4c51SChris Mason /* 143374123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 143474123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 143574123bd7SChris Mason */ 1436e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1437e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1438be0e5c09SChris Mason { 1439e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1440e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1441e20d96d6SChris Mason struct buffer_head *t; 1442234b63a0SChris Mason struct btrfs_leaf *left; 1443be0e5c09SChris Mason int slot; 1444be0e5c09SChris Mason int i; 1445be0e5c09SChris Mason int free_space; 1446be0e5c09SChris Mason int push_space = 0; 1447be0e5c09SChris Mason int push_items = 0; 14480783fcfcSChris Mason struct btrfs_item *item; 14497518a238SChris Mason u32 old_left_nritems; 1450aa5d6bedSChris Mason int ret = 0; 1451aa5d6bedSChris Mason int wret; 1452be0e5c09SChris Mason 1453be0e5c09SChris Mason slot = path->slots[1]; 1454be0e5c09SChris Mason if (slot == 0) { 1455be0e5c09SChris Mason return 1; 1456be0e5c09SChris Mason } 1457be0e5c09SChris Mason if (!path->nodes[1]) { 1458be0e5c09SChris Mason return 1; 1459be0e5c09SChris Mason } 1460e20d96d6SChris Mason t = read_tree_block(root, 1461e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1462e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1463123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 14640783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1465234b63a0SChris Mason btrfs_block_release(root, t); 1466be0e5c09SChris Mason return 1; 1467be0e5c09SChris Mason } 146802217ed2SChris Mason 146902217ed2SChris Mason /* cow and double check */ 147054aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 147154aa1f4dSChris Mason if (ret) { 147254aa1f4dSChris Mason /* we hit -ENOSPC, but it isn't fatal here */ 1473252c38f0SYan btrfs_block_release(root, t); 147454aa1f4dSChris Mason return 1; 147554aa1f4dSChris Mason } 1476e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1477123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 14780783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1479234b63a0SChris Mason btrfs_block_release(root, t); 148002217ed2SChris Mason return 1; 148102217ed2SChris Mason } 148202217ed2SChris Mason 1483a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1484a429e513SChris Mason btrfs_block_release(root, t); 1485a429e513SChris Mason return 1; 1486a429e513SChris Mason } 1487a429e513SChris Mason 1488a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1489be0e5c09SChris Mason item = right->items + i; 1490be0e5c09SChris Mason if (path->slots[0] == i) 1491be0e5c09SChris Mason push_space += data_size + sizeof(*item); 14920783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 14930783fcfcSChris Mason free_space) 1494be0e5c09SChris Mason break; 1495be0e5c09SChris Mason push_items++; 14960783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1497be0e5c09SChris Mason } 1498be0e5c09SChris Mason if (push_items == 0) { 1499234b63a0SChris Mason btrfs_block_release(root, t); 1500be0e5c09SChris Mason return 1; 1501be0e5c09SChris Mason } 1502a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1503a429e513SChris Mason WARN_ON(1); 1504be0e5c09SChris Mason /* push data from right to left */ 1505d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1506d6025579SChris Mason btrfs_header_nritems(&left->header), 15070783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1508123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 15090783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1510d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1511d6025579SChris Mason leaf_data_end(root, left) - push_space, 1512123abc88SChris Mason btrfs_leaf_data(right) + 1513123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1514be0e5c09SChris Mason push_space); 15157518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1516eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1517eb60ceacSChris Mason 1518be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1519123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1520123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1521123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 15220783fcfcSChris Mason btrfs_item_offset(left->items + 15230783fcfcSChris Mason old_left_nritems - 1))); 1524be0e5c09SChris Mason } 15257518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1526be0e5c09SChris Mason 1527be0e5c09SChris Mason /* fixup right node */ 15280783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1529123abc88SChris Mason leaf_data_end(root, right); 1530d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1531d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1532d6025579SChris Mason btrfs_leaf_data(right) + 1533123abc88SChris Mason leaf_data_end(root, right), push_space); 1534d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 15357518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 15360783fcfcSChris Mason sizeof(struct btrfs_item)); 15377518a238SChris Mason btrfs_set_header_nritems(&right->header, 15387518a238SChris Mason btrfs_header_nritems(&right->header) - 15397518a238SChris Mason push_items); 1540123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1541eb60ceacSChris Mason 15427518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 15430783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 15440783fcfcSChris Mason btrfs_item_size(right->items + i)); 15450783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1546be0e5c09SChris Mason } 1547eb60ceacSChris Mason 1548d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1549d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1550098f59c2SChris Mason 1551e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1552aa5d6bedSChris Mason if (wret) 1553aa5d6bedSChris Mason ret = wret; 1554be0e5c09SChris Mason 1555be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1556be0e5c09SChris Mason if (path->slots[0] < push_items) { 1557be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1558234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1559eb60ceacSChris Mason path->nodes[0] = t; 1560be0e5c09SChris Mason path->slots[1] -= 1; 1561be0e5c09SChris Mason } else { 1562234b63a0SChris Mason btrfs_block_release(root, t); 1563be0e5c09SChris Mason path->slots[0] -= push_items; 1564be0e5c09SChris Mason } 1565eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1566098f59c2SChris Mason if (path->nodes[1]) 1567098f59c2SChris Mason check_node(root, path, 1); 1568aa5d6bedSChris Mason return ret; 1569be0e5c09SChris Mason } 1570be0e5c09SChris Mason 157174123bd7SChris Mason /* 157274123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 157374123bd7SChris Mason * available for the resulting leaf level of the path. 1574aa5d6bedSChris Mason * 1575aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 157674123bd7SChris Mason */ 1577e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1578d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1579d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1580be0e5c09SChris Mason { 1581e20d96d6SChris Mason struct buffer_head *l_buf; 1582234b63a0SChris Mason struct btrfs_leaf *l; 15837518a238SChris Mason u32 nritems; 1584eb60ceacSChris Mason int mid; 1585eb60ceacSChris Mason int slot; 1586234b63a0SChris Mason struct btrfs_leaf *right; 1587e20d96d6SChris Mason struct buffer_head *right_buffer; 15880783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1589be0e5c09SChris Mason int data_copy_size; 1590be0e5c09SChris Mason int rt_data_off; 1591be0e5c09SChris Mason int i; 1592d4dbff95SChris Mason int ret = 0; 1593aa5d6bedSChris Mason int wret; 1594d4dbff95SChris Mason int double_split = 0; 1595d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1596be0e5c09SChris Mason 159740689478SChris Mason /* first try to make some room by pushing left and right */ 1598e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1599eaee50e8SChris Mason if (wret < 0) 1600eaee50e8SChris Mason return wret; 1601eaee50e8SChris Mason if (wret) { 1602e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1603eaee50e8SChris Mason if (wret < 0) 1604eaee50e8SChris Mason return wret; 1605eaee50e8SChris Mason } 1606eb60ceacSChris Mason l_buf = path->nodes[0]; 1607e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1608aa5d6bedSChris Mason 1609aa5d6bedSChris Mason /* did the pushes work? */ 1610123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1611123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1612be0e5c09SChris Mason return 0; 1613aa5d6bedSChris Mason 16145c680ed6SChris Mason if (!path->nodes[1]) { 1615e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 16165c680ed6SChris Mason if (ret) 16175c680ed6SChris Mason return ret; 16185c680ed6SChris Mason } 1619eb60ceacSChris Mason slot = path->slots[0]; 16207518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1621eb60ceacSChris Mason mid = (nritems + 1)/ 2; 162254aa1f4dSChris Mason 16236702ed49SChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0); 162454aa1f4dSChris Mason if (IS_ERR(right_buffer)) 162554aa1f4dSChris Mason return PTR_ERR(right_buffer); 162654aa1f4dSChris Mason 1627e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1628123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 16297eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 16307f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 16314d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 16327518a238SChris Mason btrfs_set_header_level(&right->header, 0); 16333eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 16343eb0314dSChris Mason sizeof(right->header.fsid)); 1635d4dbff95SChris Mason if (mid <= slot) { 1636d4dbff95SChris Mason if (nritems == 1 || 1637d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1638d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1639d4dbff95SChris Mason if (slot >= nritems) { 1640d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1641d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1642d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1643d4dbff95SChris Mason &disk_key, 16447eccb903SChris Mason bh_blocknr(right_buffer), 1645d4dbff95SChris Mason path->slots[1] + 1, 1); 1646d4dbff95SChris Mason if (wret) 1647d4dbff95SChris Mason ret = wret; 1648d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1649d4dbff95SChris Mason path->nodes[0] = right_buffer; 1650d4dbff95SChris Mason path->slots[0] = 0; 1651d4dbff95SChris Mason path->slots[1] += 1; 1652d4dbff95SChris Mason return ret; 1653d4dbff95SChris Mason } 1654d4dbff95SChris Mason mid = slot; 1655d4dbff95SChris Mason double_split = 1; 1656d4dbff95SChris Mason } 1657d4dbff95SChris Mason } else { 1658d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1659d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1660d4dbff95SChris Mason if (slot == 0) { 1661d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1662d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1663d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1664d4dbff95SChris Mason &disk_key, 16657eccb903SChris Mason bh_blocknr(right_buffer), 1666098f59c2SChris Mason path->slots[1], 1); 1667d4dbff95SChris Mason if (wret) 1668d4dbff95SChris Mason ret = wret; 1669d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1670d4dbff95SChris Mason path->nodes[0] = right_buffer; 1671d4dbff95SChris Mason path->slots[0] = 0; 1672a429e513SChris Mason if (path->slots[1] == 0) { 1673a429e513SChris Mason wret = fixup_low_keys(trans, root, 1674a429e513SChris Mason path, &disk_key, 1); 1675a429e513SChris Mason if (wret) 1676a429e513SChris Mason ret = wret; 1677a429e513SChris Mason } 1678d4dbff95SChris Mason return ret; 1679d4dbff95SChris Mason } 1680d4dbff95SChris Mason mid = slot; 1681d4dbff95SChris Mason double_split = 1; 1682d4dbff95SChris Mason } 1683d4dbff95SChris Mason } 1684d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1685123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1686123abc88SChris Mason leaf_data_end(root, l); 1687d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 16880783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1689d6025579SChris Mason btrfs_memcpy(root, right, 1690d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1691123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1692123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1693123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1694123abc88SChris Mason btrfs_item_end(l->items + mid); 169574123bd7SChris Mason 16960783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1697123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 16980783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 16990783fcfcSChris Mason } 170074123bd7SChris Mason 17017518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1702aa5d6bedSChris Mason ret = 0; 1703e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 17047eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1705aa5d6bedSChris Mason if (wret) 1706aa5d6bedSChris Mason ret = wret; 1707d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1708d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1709eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1710be0e5c09SChris Mason if (mid <= slot) { 1711234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1712eb60ceacSChris Mason path->nodes[0] = right_buffer; 1713be0e5c09SChris Mason path->slots[0] -= mid; 1714be0e5c09SChris Mason path->slots[1] += 1; 1715eb60ceacSChris Mason } else 1716234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1717eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1718098f59c2SChris Mason check_node(root, path, 1); 1719d4dbff95SChris Mason 1720d4dbff95SChris Mason if (!double_split) 1721d4dbff95SChris Mason return ret; 17226702ed49SChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0); 172354aa1f4dSChris Mason if (IS_ERR(right_buffer)) 172454aa1f4dSChris Mason return PTR_ERR(right_buffer); 172554aa1f4dSChris Mason 1726d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1727d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 17287eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1729d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 17304d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 1731d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 17323eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 17333eb0314dSChris Mason sizeof(right->header.fsid)); 1734d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1735d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1736d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1737d4dbff95SChris Mason &disk_key, 17387eccb903SChris Mason bh_blocknr(right_buffer), 1739d4dbff95SChris Mason path->slots[1], 1); 1740d4dbff95SChris Mason if (wret) 1741d4dbff95SChris Mason ret = wret; 1742a429e513SChris Mason if (path->slots[1] == 0) { 1743a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1744a429e513SChris Mason if (wret) 1745a429e513SChris Mason ret = wret; 1746a429e513SChris Mason } 1747d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1748d4dbff95SChris Mason path->nodes[0] = right_buffer; 1749d4dbff95SChris Mason path->slots[0] = 0; 1750d4dbff95SChris Mason check_node(root, path, 1); 1751d4dbff95SChris Mason check_leaf(root, path, 0); 1752be0e5c09SChris Mason return ret; 1753be0e5c09SChris Mason } 1754be0e5c09SChris Mason 1755b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1756b18c6685SChris Mason struct btrfs_root *root, 1757b18c6685SChris Mason struct btrfs_path *path, 1758b18c6685SChris Mason u32 new_size) 1759b18c6685SChris Mason { 1760b18c6685SChris Mason int ret = 0; 1761b18c6685SChris Mason int slot; 1762b18c6685SChris Mason int slot_orig; 1763b18c6685SChris Mason struct btrfs_leaf *leaf; 1764b18c6685SChris Mason struct buffer_head *leaf_buf; 1765b18c6685SChris Mason u32 nritems; 1766b18c6685SChris Mason unsigned int data_end; 1767b18c6685SChris Mason unsigned int old_data_start; 1768b18c6685SChris Mason unsigned int old_size; 1769b18c6685SChris Mason unsigned int size_diff; 1770b18c6685SChris Mason int i; 1771b18c6685SChris Mason 1772b18c6685SChris Mason slot_orig = path->slots[0]; 1773b18c6685SChris Mason leaf_buf = path->nodes[0]; 1774b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1775b18c6685SChris Mason 1776b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1777b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1778b18c6685SChris Mason 1779b18c6685SChris Mason slot = path->slots[0]; 1780b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1781b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1782b18c6685SChris Mason BUG_ON(old_size <= new_size); 1783b18c6685SChris Mason size_diff = old_size - new_size; 1784b18c6685SChris Mason 1785b18c6685SChris Mason BUG_ON(slot < 0); 1786b18c6685SChris Mason BUG_ON(slot >= nritems); 1787b18c6685SChris Mason 1788b18c6685SChris Mason /* 1789b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1790b18c6685SChris Mason */ 1791b18c6685SChris Mason /* first correct the data pointers */ 1792b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1793b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1794b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1795b18c6685SChris Mason ioff + size_diff); 1796b18c6685SChris Mason } 1797b18c6685SChris Mason /* shift the data */ 1798b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1799b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1800b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1801b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1802b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1803b18c6685SChris Mason 1804b18c6685SChris Mason ret = 0; 1805b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1806b18c6685SChris Mason BUG(); 1807b18c6685SChris Mason check_leaf(root, path, 0); 1808b18c6685SChris Mason return ret; 1809b18c6685SChris Mason } 1810b18c6685SChris Mason 18116567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 18126567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 18136567e837SChris Mason { 18146567e837SChris Mason int ret = 0; 18156567e837SChris Mason int slot; 18166567e837SChris Mason int slot_orig; 18176567e837SChris Mason struct btrfs_leaf *leaf; 18186567e837SChris Mason struct buffer_head *leaf_buf; 18196567e837SChris Mason u32 nritems; 18206567e837SChris Mason unsigned int data_end; 18216567e837SChris Mason unsigned int old_data; 18226567e837SChris Mason unsigned int old_size; 18236567e837SChris Mason int i; 18246567e837SChris Mason 18256567e837SChris Mason slot_orig = path->slots[0]; 18266567e837SChris Mason leaf_buf = path->nodes[0]; 18276567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 18286567e837SChris Mason 18296567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 18306567e837SChris Mason data_end = leaf_data_end(root, leaf); 18316567e837SChris Mason 18326567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 18336567e837SChris Mason BUG(); 18346567e837SChris Mason slot = path->slots[0]; 18356567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 18366567e837SChris Mason 18376567e837SChris Mason BUG_ON(slot < 0); 18386567e837SChris Mason BUG_ON(slot >= nritems); 18396567e837SChris Mason 18406567e837SChris Mason /* 18416567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 18426567e837SChris Mason */ 18436567e837SChris Mason /* first correct the data pointers */ 18446567e837SChris Mason for (i = slot; i < nritems; i++) { 18456567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 18466567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 18476567e837SChris Mason ioff - data_size); 18486567e837SChris Mason } 18496567e837SChris Mason /* shift the data */ 18506567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 18516567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 18526567e837SChris Mason data_end, old_data - data_end); 18536567e837SChris Mason data_end = old_data; 18546567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 18556567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 18566567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 18576567e837SChris Mason 18586567e837SChris Mason ret = 0; 18596567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 18606567e837SChris Mason BUG(); 18616567e837SChris Mason check_leaf(root, path, 0); 18626567e837SChris Mason return ret; 18636567e837SChris Mason } 18646567e837SChris Mason 186574123bd7SChris Mason /* 186674123bd7SChris Mason * Given a key and some data, insert an item into the tree. 186774123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 186874123bd7SChris Mason */ 1869e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1870e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1871e089f05cSChris Mason *cpu_key, u32 data_size) 1872be0e5c09SChris Mason { 1873aa5d6bedSChris Mason int ret = 0; 1874be0e5c09SChris Mason int slot; 1875eb60ceacSChris Mason int slot_orig; 1876234b63a0SChris Mason struct btrfs_leaf *leaf; 1877e20d96d6SChris Mason struct buffer_head *leaf_buf; 18787518a238SChris Mason u32 nritems; 1879be0e5c09SChris Mason unsigned int data_end; 1880e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1881e2fa7227SChris Mason 1882e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1883be0e5c09SChris Mason 188474123bd7SChris Mason /* create a root if there isn't one */ 18855c680ed6SChris Mason if (!root->node) 1886cfaa7295SChris Mason BUG(); 1887e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1888eb60ceacSChris Mason if (ret == 0) { 1889f0930a37SChris Mason return -EEXIST; 1890aa5d6bedSChris Mason } 1891ed2ff2cbSChris Mason if (ret < 0) 1892ed2ff2cbSChris Mason goto out; 1893be0e5c09SChris Mason 189462e2749eSChris Mason slot_orig = path->slots[0]; 189562e2749eSChris Mason leaf_buf = path->nodes[0]; 1896e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 189774123bd7SChris Mason 18987518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1899123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1900eb60ceacSChris Mason 1901123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1902d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1903be0e5c09SChris Mason BUG(); 1904d4dbff95SChris Mason } 190562e2749eSChris Mason slot = path->slots[0]; 1906eb60ceacSChris Mason BUG_ON(slot < 0); 1907be0e5c09SChris Mason if (slot != nritems) { 1908be0e5c09SChris Mason int i; 19090783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1910be0e5c09SChris Mason 1911be0e5c09SChris Mason /* 1912be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1913be0e5c09SChris Mason */ 1914be0e5c09SChris Mason /* first correct the data pointers */ 19150783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1916123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 19170783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 19180783fcfcSChris Mason ioff - data_size); 19190783fcfcSChris Mason } 1920be0e5c09SChris Mason 1921be0e5c09SChris Mason /* shift the items */ 1922d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1923d6025579SChris Mason leaf->items + slot, 19240783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1925be0e5c09SChris Mason 1926be0e5c09SChris Mason /* shift the data */ 1927d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1928d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1929be0e5c09SChris Mason data_end, old_data - data_end); 1930be0e5c09SChris Mason data_end = old_data; 1931be0e5c09SChris Mason } 193262e2749eSChris Mason /* setup the item for the new data */ 1933d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1934e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 19350783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 19360783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 19377518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1938d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1939aa5d6bedSChris Mason 1940aa5d6bedSChris Mason ret = 0; 19418e19f2cdSChris Mason if (slot == 0) 1942e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1943aa5d6bedSChris Mason 1944123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1945be0e5c09SChris Mason BUG(); 194662e2749eSChris Mason check_leaf(root, path, 0); 1947ed2ff2cbSChris Mason out: 194862e2749eSChris Mason return ret; 194962e2749eSChris Mason } 195062e2749eSChris Mason 195162e2749eSChris Mason /* 195262e2749eSChris Mason * Given a key and some data, insert an item into the tree. 195362e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 195462e2749eSChris Mason */ 1955e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1956e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1957e089f05cSChris Mason data_size) 195862e2749eSChris Mason { 195962e2749eSChris Mason int ret = 0; 19602c90e5d6SChris Mason struct btrfs_path *path; 196162e2749eSChris Mason u8 *ptr; 196262e2749eSChris Mason 19632c90e5d6SChris Mason path = btrfs_alloc_path(); 19642c90e5d6SChris Mason BUG_ON(!path); 19652c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 196662e2749eSChris Mason if (!ret) { 19672c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 19682c90e5d6SChris Mason path->slots[0], u8); 19692c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1970d6025579SChris Mason ptr, data, data_size); 19712c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 197262e2749eSChris Mason } 19732c90e5d6SChris Mason btrfs_free_path(path); 1974aa5d6bedSChris Mason return ret; 1975be0e5c09SChris Mason } 1976be0e5c09SChris Mason 197774123bd7SChris Mason /* 19785de08d7dSChris Mason * delete the pointer from a given node. 197974123bd7SChris Mason * 198074123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 198174123bd7SChris Mason * continuing all the way the root if required. The root is converted into 198274123bd7SChris Mason * a leaf if all the nodes are emptied. 198374123bd7SChris Mason */ 1984e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1985e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1986be0e5c09SChris Mason { 1987234b63a0SChris Mason struct btrfs_node *node; 1988e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 19897518a238SChris Mason u32 nritems; 1990aa5d6bedSChris Mason int ret = 0; 1991bb803951SChris Mason int wret; 1992be0e5c09SChris Mason 1993e20d96d6SChris Mason node = btrfs_buffer_node(parent); 19947518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1995be0e5c09SChris Mason if (slot != nritems -1) { 1996d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1997d6025579SChris Mason node->ptrs + slot + 1, 1998d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1999d6025579SChris Mason (nritems - slot - 1)); 2000be0e5c09SChris Mason } 20017518a238SChris Mason nritems--; 20027518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 20037518a238SChris Mason if (nritems == 0 && parent == root->node) { 2004e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 2005e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 2006eb60ceacSChris Mason /* just turn the root into a leaf and break */ 2007e20d96d6SChris Mason btrfs_set_header_level(header, 0); 2008bb803951SChris Mason } else if (slot == 0) { 2009e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 2010123abc88SChris Mason level + 1); 20110f70abe2SChris Mason if (wret) 20120f70abe2SChris Mason ret = wret; 2013be0e5c09SChris Mason } 2014d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 2015aa5d6bedSChris Mason return ret; 2016be0e5c09SChris Mason } 2017be0e5c09SChris Mason 201874123bd7SChris Mason /* 201974123bd7SChris Mason * delete the item at the leaf level in path. If that empties 202074123bd7SChris Mason * the leaf, remove it from the tree 202174123bd7SChris Mason */ 2022e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 2023e089f05cSChris Mason struct btrfs_path *path) 2024be0e5c09SChris Mason { 2025be0e5c09SChris Mason int slot; 2026234b63a0SChris Mason struct btrfs_leaf *leaf; 2027e20d96d6SChris Mason struct buffer_head *leaf_buf; 2028be0e5c09SChris Mason int doff; 2029be0e5c09SChris Mason int dsize; 2030aa5d6bedSChris Mason int ret = 0; 2031aa5d6bedSChris Mason int wret; 20327518a238SChris Mason u32 nritems; 2033be0e5c09SChris Mason 2034eb60ceacSChris Mason leaf_buf = path->nodes[0]; 2035e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 20364920c9acSChris Mason slot = path->slots[0]; 20370783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 20380783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 20397518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 2040be0e5c09SChris Mason 20417518a238SChris Mason if (slot != nritems - 1) { 2042be0e5c09SChris Mason int i; 2043123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 2044d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 2045d6025579SChris Mason data_end + dsize, 2046123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 2047be0e5c09SChris Mason doff - data_end); 20480783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 2049123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 20500783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 20510783fcfcSChris Mason } 2052d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 2053d6025579SChris Mason leaf->items + slot + 1, 20540783fcfcSChris Mason sizeof(struct btrfs_item) * 20557518a238SChris Mason (nritems - slot - 1)); 2056be0e5c09SChris Mason } 20577518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 20587518a238SChris Mason nritems--; 205974123bd7SChris Mason /* delete the leaf if we've emptied it */ 20607518a238SChris Mason if (nritems == 0) { 2061eb60ceacSChris Mason if (leaf_buf == root->node) { 20627518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 20639a8dd150SChris Mason } else { 2064e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 2065d6025579SChris Mason wait_on_buffer(leaf_buf); 2066e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 2067aa5d6bedSChris Mason if (wret) 2068aa5d6bedSChris Mason ret = wret; 2069e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 20707eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 20710f70abe2SChris Mason if (wret) 20720f70abe2SChris Mason ret = wret; 20739a8dd150SChris Mason } 2074be0e5c09SChris Mason } else { 20757518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 2076aa5d6bedSChris Mason if (slot == 0) { 2077e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 2078aa5d6bedSChris Mason &leaf->items[0].key, 1); 2079aa5d6bedSChris Mason if (wret) 2080aa5d6bedSChris Mason ret = wret; 2081aa5d6bedSChris Mason } 2082aa5d6bedSChris Mason 208374123bd7SChris Mason /* delete the leaf if it is mostly empty */ 2084123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 2085be0e5c09SChris Mason /* push_leaf_left fixes the path. 2086be0e5c09SChris Mason * make sure the path still points to our leaf 2087be0e5c09SChris Mason * for possible call to del_ptr below 2088be0e5c09SChris Mason */ 20894920c9acSChris Mason slot = path->slots[1]; 2090e20d96d6SChris Mason get_bh(leaf_buf); 2091e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 209254aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 2093aa5d6bedSChris Mason ret = wret; 2094f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 20957518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 2096e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 209754aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 2098aa5d6bedSChris Mason ret = wret; 2099aa5d6bedSChris Mason } 21007518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 21017eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 2102e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 2103d6025579SChris Mason wait_on_buffer(leaf_buf); 2104e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 2105aa5d6bedSChris Mason if (wret) 2106aa5d6bedSChris Mason ret = wret; 2107234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 2108e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 2109e089f05cSChris Mason 1, 1); 21100f70abe2SChris Mason if (wret) 21110f70abe2SChris Mason ret = wret; 21125de08d7dSChris Mason } else { 2113d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 2114234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 2115be0e5c09SChris Mason } 2116d5719762SChris Mason } else { 2117d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 2118be0e5c09SChris Mason } 21199a8dd150SChris Mason } 2120aa5d6bedSChris Mason return ret; 21219a8dd150SChris Mason } 21229a8dd150SChris Mason 212397571fd0SChris Mason /* 212497571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 21250f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 21260f70abe2SChris Mason * returns < 0 on io errors. 212797571fd0SChris Mason */ 2128234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 2129d97e63b6SChris Mason { 2130d97e63b6SChris Mason int slot; 2131d97e63b6SChris Mason int level = 1; 2132d97e63b6SChris Mason u64 blocknr; 2133e20d96d6SChris Mason struct buffer_head *c; 2134e20d96d6SChris Mason struct btrfs_node *c_node; 2135e20d96d6SChris Mason struct buffer_head *next = NULL; 2136d97e63b6SChris Mason 2137234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 2138d97e63b6SChris Mason if (!path->nodes[level]) 21390f70abe2SChris Mason return 1; 2140d97e63b6SChris Mason slot = path->slots[level] + 1; 2141d97e63b6SChris Mason c = path->nodes[level]; 2142e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 2143e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 2144d97e63b6SChris Mason level++; 2145d97e63b6SChris Mason continue; 2146d97e63b6SChris Mason } 2147e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 2148cfaa7295SChris Mason if (next) 2149234b63a0SChris Mason btrfs_block_release(root, next); 21506702ed49SChris Mason if (path->reada) 21516702ed49SChris Mason reada_for_search(root, path, level, slot); 2152d97e63b6SChris Mason next = read_tree_block(root, blocknr); 2153d97e63b6SChris Mason break; 2154d97e63b6SChris Mason } 2155d97e63b6SChris Mason path->slots[level] = slot; 2156d97e63b6SChris Mason while(1) { 2157d97e63b6SChris Mason level--; 2158d97e63b6SChris Mason c = path->nodes[level]; 2159234b63a0SChris Mason btrfs_block_release(root, c); 2160d97e63b6SChris Mason path->nodes[level] = next; 2161d97e63b6SChris Mason path->slots[level] = 0; 2162d97e63b6SChris Mason if (!level) 2163d97e63b6SChris Mason break; 21646702ed49SChris Mason if (path->reada) 216532020611SYan reada_for_search(root, path, level, 0); 21661d4f8a0cSChris Mason next = read_tree_block(root, 2167e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 2168d97e63b6SChris Mason } 2169d97e63b6SChris Mason return 0; 2170d97e63b6SChris Mason } 2171