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 19a6b6e75eSChris Mason #include <linux/sched.h> 20eb60ceacSChris Mason #include "ctree.h" 21eb60ceacSChris Mason #include "disk-io.h" 227f5c1516SChris Mason #include "transaction.h" 235f39d397SChris Mason #include "print-tree.h" 249a8dd150SChris Mason 25e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 26e089f05cSChris Mason *root, struct btrfs_path *path, int level); 27e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 28d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 29cc0c5538SChris Mason struct btrfs_path *path, int data_size, int extend); 305f39d397SChris Mason static int push_node_left(struct btrfs_trans_handle *trans, 315f39d397SChris Mason struct btrfs_root *root, struct extent_buffer *dst, 325f39d397SChris Mason struct extent_buffer *src); 335f39d397SChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, 345f39d397SChris Mason struct btrfs_root *root, 355f39d397SChris Mason struct extent_buffer *dst_buf, 365f39d397SChris Mason struct extent_buffer *src_buf); 37e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 38e089f05cSChris Mason struct btrfs_path *path, int level, int slot); 39d97e63b6SChris Mason 40df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p) 41df24a2b9SChris Mason { 42df24a2b9SChris Mason memset(p, 0, sizeof(*p)); 43df24a2b9SChris Mason } 44df24a2b9SChris Mason 452c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void) 462c90e5d6SChris Mason { 47df24a2b9SChris Mason struct btrfs_path *path; 48df24a2b9SChris Mason path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); 492cc58cf2SChris Mason if (path) { 50df24a2b9SChris Mason btrfs_init_path(path); 512cc58cf2SChris Mason path->reada = 1; 522cc58cf2SChris Mason } 53df24a2b9SChris Mason return path; 542c90e5d6SChris Mason } 552c90e5d6SChris Mason 562c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p) 572c90e5d6SChris Mason { 58df24a2b9SChris Mason btrfs_release_path(NULL, p); 592c90e5d6SChris Mason kmem_cache_free(btrfs_path_cachep, p); 602c90e5d6SChris Mason } 612c90e5d6SChris Mason 62234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) 63eb60ceacSChris Mason { 64eb60ceacSChris Mason int i; 65234b63a0SChris Mason for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 66eb60ceacSChris Mason if (!p->nodes[i]) 67eb60ceacSChris Mason break; 685f39d397SChris Mason free_extent_buffer(p->nodes[i]); 69eb60ceacSChris Mason } 70aa5d6bedSChris Mason memset(p, 0, sizeof(*p)); 71eb60ceacSChris Mason } 72eb60ceacSChris Mason 735f39d397SChris Mason static int __btrfs_cow_block(struct btrfs_trans_handle *trans, 745f39d397SChris Mason struct btrfs_root *root, 755f39d397SChris Mason struct extent_buffer *buf, 765f39d397SChris Mason struct extent_buffer *parent, int parent_slot, 775f39d397SChris Mason struct extent_buffer **cow_ret, 785f39d397SChris Mason u64 search_start, u64 empty_size) 796702ed49SChris Mason { 80*7bb86316SChris Mason u64 root_gen; 815f39d397SChris Mason struct extent_buffer *cow; 82*7bb86316SChris Mason u32 nritems; 836702ed49SChris Mason int ret = 0; 846702ed49SChris Mason int different_trans = 0; 85*7bb86316SChris Mason int level; 86*7bb86316SChris Mason struct btrfs_key first_key; 876702ed49SChris Mason 88*7bb86316SChris Mason if (root->ref_cows) { 89*7bb86316SChris Mason root_gen = trans->transid; 90*7bb86316SChris Mason } else { 91*7bb86316SChris Mason root_gen = 0; 92*7bb86316SChris Mason } 93*7bb86316SChris Mason 94*7bb86316SChris Mason WARN_ON(root->ref_cows && trans->transid != 95*7bb86316SChris Mason root->fs_info->running_transaction->transid); 966702ed49SChris Mason WARN_ON(root->ref_cows && trans->transid != root->last_trans); 975f39d397SChris Mason 98*7bb86316SChris Mason level = btrfs_header_level(buf); 99*7bb86316SChris Mason nritems = btrfs_header_nritems(buf); 100*7bb86316SChris Mason if (nritems) { 101*7bb86316SChris Mason if (level == 0) 102*7bb86316SChris Mason btrfs_item_key_to_cpu(buf, &first_key, 0); 103*7bb86316SChris Mason else 104*7bb86316SChris Mason btrfs_node_key_to_cpu(buf, &first_key, 0); 105*7bb86316SChris Mason } else { 106*7bb86316SChris Mason first_key.objectid = 0; 107*7bb86316SChris Mason } 108*7bb86316SChris Mason cow = __btrfs_alloc_free_block(trans, root, buf->len, 109*7bb86316SChris Mason root->root_key.objectid, 110*7bb86316SChris Mason root_gen, first_key.objectid, level, 111db94535dSChris Mason search_start, empty_size); 1126702ed49SChris Mason if (IS_ERR(cow)) 1136702ed49SChris Mason return PTR_ERR(cow); 1146702ed49SChris Mason 1155f39d397SChris Mason copy_extent_buffer(cow, buf, 0, 0, cow->len); 116db94535dSChris Mason btrfs_set_header_bytenr(cow, cow->start); 1175f39d397SChris Mason btrfs_set_header_generation(cow, trans->transid); 1185f39d397SChris Mason btrfs_set_header_owner(cow, root->root_key.objectid); 1196702ed49SChris Mason 1205f39d397SChris Mason WARN_ON(btrfs_header_generation(buf) > trans->transid); 1215f39d397SChris Mason if (btrfs_header_generation(buf) != trans->transid) { 1226702ed49SChris Mason different_trans = 1; 1236702ed49SChris Mason ret = btrfs_inc_ref(trans, root, buf); 1246702ed49SChris Mason if (ret) 1256702ed49SChris Mason return ret; 1266702ed49SChris Mason } else { 1276702ed49SChris Mason clean_tree_block(trans, root, buf); 1286702ed49SChris Mason } 1296702ed49SChris Mason 1306702ed49SChris Mason if (buf == root->node) { 131*7bb86316SChris Mason root_gen = btrfs_header_generation(buf); 1326702ed49SChris Mason root->node = cow; 1335f39d397SChris Mason extent_buffer_get(cow); 1346702ed49SChris Mason if (buf != root->commit_root) { 135db94535dSChris Mason btrfs_free_extent(trans, root, buf->start, 136*7bb86316SChris Mason buf->len, root->root_key.objectid, 137*7bb86316SChris Mason root_gen, 0, 0, 1); 1386702ed49SChris Mason } 1395f39d397SChris Mason free_extent_buffer(buf); 1406702ed49SChris Mason } else { 141*7bb86316SChris Mason root_gen = btrfs_header_generation(parent); 1425f39d397SChris Mason btrfs_set_node_blockptr(parent, parent_slot, 143db94535dSChris Mason cow->start); 14474493f7aSChris Mason WARN_ON(trans->transid == 0); 14574493f7aSChris Mason btrfs_set_node_ptr_generation(parent, parent_slot, 14674493f7aSChris Mason trans->transid); 1476702ed49SChris Mason btrfs_mark_buffer_dirty(parent); 1485f39d397SChris Mason WARN_ON(btrfs_header_generation(parent) != trans->transid); 149*7bb86316SChris Mason btrfs_free_extent(trans, root, buf->start, buf->len, 150*7bb86316SChris Mason btrfs_header_owner(parent), root_gen, 151*7bb86316SChris Mason 0, 0, 1); 1526702ed49SChris Mason } 1535f39d397SChris Mason free_extent_buffer(buf); 1546702ed49SChris Mason btrfs_mark_buffer_dirty(cow); 1556702ed49SChris Mason *cow_ret = cow; 1566702ed49SChris Mason return 0; 1576702ed49SChris Mason } 1586702ed49SChris Mason 1595f39d397SChris Mason int btrfs_cow_block(struct btrfs_trans_handle *trans, 1605f39d397SChris Mason struct btrfs_root *root, struct extent_buffer *buf, 1615f39d397SChris Mason struct extent_buffer *parent, int parent_slot, 1625f39d397SChris Mason struct extent_buffer **cow_ret) 16302217ed2SChris Mason { 1646702ed49SChris Mason u64 search_start; 165f510cfecSChris Mason int ret; 166ccd467d6SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 167ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 168ccd467d6SChris Mason root->fs_info->running_transaction->transid); 169ccd467d6SChris Mason WARN_ON(1); 170ccd467d6SChris Mason } 171ccd467d6SChris Mason if (trans->transid != root->fs_info->generation) { 172ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 173ccd467d6SChris Mason root->fs_info->generation); 174ccd467d6SChris Mason WARN_ON(1); 175ccd467d6SChris Mason } 1765f39d397SChris Mason if (btrfs_header_generation(buf) == trans->transid) { 17702217ed2SChris Mason *cow_ret = buf; 17802217ed2SChris Mason return 0; 17902217ed2SChris Mason } 1806702ed49SChris Mason 181db94535dSChris Mason search_start = buf->start & ~((u64)BTRFS_BLOCK_GROUP_SIZE - 1); 182f510cfecSChris Mason ret = __btrfs_cow_block(trans, root, buf, parent, 1836702ed49SChris Mason parent_slot, cow_ret, search_start, 0); 184f510cfecSChris Mason return ret; 1852c90e5d6SChris Mason } 1866702ed49SChris Mason 1876b80053dSChris Mason static int close_blocks(u64 blocknr, u64 other, u32 blocksize) 1886702ed49SChris Mason { 1896b80053dSChris Mason if (blocknr < other && other - (blocknr + blocksize) < 32768) 1906702ed49SChris Mason return 1; 1916b80053dSChris Mason if (blocknr > other && blocknr - (other + blocksize) < 32768) 1926702ed49SChris Mason return 1; 19302217ed2SChris Mason return 0; 19402217ed2SChris Mason } 19502217ed2SChris Mason 196081e9573SChris Mason /* 197081e9573SChris Mason * compare two keys in a memcmp fashion 198081e9573SChris Mason */ 199081e9573SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 200081e9573SChris Mason { 201081e9573SChris Mason struct btrfs_key k1; 202081e9573SChris Mason 203081e9573SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 204081e9573SChris Mason 205081e9573SChris Mason if (k1.objectid > k2->objectid) 206081e9573SChris Mason return 1; 207081e9573SChris Mason if (k1.objectid < k2->objectid) 208081e9573SChris Mason return -1; 209081e9573SChris Mason if (k1.type > k2->type) 210081e9573SChris Mason return 1; 211081e9573SChris Mason if (k1.type < k2->type) 212081e9573SChris Mason return -1; 213081e9573SChris Mason if (k1.offset > k2->offset) 214081e9573SChris Mason return 1; 215081e9573SChris Mason if (k1.offset < k2->offset) 216081e9573SChris Mason return -1; 217081e9573SChris Mason return 0; 218081e9573SChris Mason } 219081e9573SChris Mason 220081e9573SChris Mason 2216702ed49SChris Mason int btrfs_realloc_node(struct btrfs_trans_handle *trans, 2225f39d397SChris Mason struct btrfs_root *root, struct extent_buffer *parent, 223a6b6e75eSChris Mason int start_slot, int cache_only, u64 *last_ret, 224a6b6e75eSChris Mason struct btrfs_key *progress) 2256702ed49SChris Mason { 2266b80053dSChris Mason struct extent_buffer *cur; 2276b80053dSChris Mason struct extent_buffer *tmp; 2286702ed49SChris Mason u64 blocknr; 229e9d0b13bSChris Mason u64 search_start = *last_ret; 230e9d0b13bSChris Mason u64 last_block = 0; 2316702ed49SChris Mason u64 other; 2326702ed49SChris Mason u32 parent_nritems; 2336702ed49SChris Mason int end_slot; 2346702ed49SChris Mason int i; 2356702ed49SChris Mason int err = 0; 236f2183bdeSChris Mason int parent_level; 2376b80053dSChris Mason int uptodate; 2386b80053dSChris Mason u32 blocksize; 239081e9573SChris Mason int progress_passed = 0; 240081e9573SChris Mason struct btrfs_disk_key disk_key; 2416702ed49SChris Mason 2425708b959SChris Mason parent_level = btrfs_header_level(parent); 2435708b959SChris Mason if (cache_only && parent_level != 1) 2445708b959SChris Mason return 0; 2455708b959SChris Mason 2466702ed49SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 2476702ed49SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 2486702ed49SChris Mason root->fs_info->running_transaction->transid); 2496702ed49SChris Mason WARN_ON(1); 2506702ed49SChris Mason } 2516702ed49SChris Mason if (trans->transid != root->fs_info->generation) { 2526702ed49SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 2536702ed49SChris Mason root->fs_info->generation); 2546702ed49SChris Mason WARN_ON(1); 2556702ed49SChris Mason } 25686479a04SChris Mason 2576b80053dSChris Mason parent_nritems = btrfs_header_nritems(parent); 2586b80053dSChris Mason blocksize = btrfs_level_size(root, parent_level - 1); 2596702ed49SChris Mason end_slot = parent_nritems; 2606702ed49SChris Mason 2616702ed49SChris Mason if (parent_nritems == 1) 2626702ed49SChris Mason return 0; 2636702ed49SChris Mason 2646702ed49SChris Mason for (i = start_slot; i < end_slot; i++) { 2656702ed49SChris Mason int close = 1; 266a6b6e75eSChris Mason 2675708b959SChris Mason if (!parent->map_token) { 2685708b959SChris Mason map_extent_buffer(parent, 2695708b959SChris Mason btrfs_node_key_ptr_offset(i), 2705708b959SChris Mason sizeof(struct btrfs_key_ptr), 2715708b959SChris Mason &parent->map_token, &parent->kaddr, 2725708b959SChris Mason &parent->map_start, &parent->map_len, 2735708b959SChris Mason KM_USER1); 2745708b959SChris Mason } 275081e9573SChris Mason btrfs_node_key(parent, &disk_key, i); 276081e9573SChris Mason if (!progress_passed && comp_keys(&disk_key, progress) < 0) 277081e9573SChris Mason continue; 278081e9573SChris Mason 279081e9573SChris Mason progress_passed = 1; 2806b80053dSChris Mason blocknr = btrfs_node_blockptr(parent, i); 281e9d0b13bSChris Mason if (last_block == 0) 282e9d0b13bSChris Mason last_block = blocknr; 2835708b959SChris Mason 2846702ed49SChris Mason if (i > 0) { 2856b80053dSChris Mason other = btrfs_node_blockptr(parent, i - 1); 2866b80053dSChris Mason close = close_blocks(blocknr, other, blocksize); 2876702ed49SChris Mason } 2885708b959SChris Mason if (close && i < end_slot - 2) { 2896b80053dSChris Mason other = btrfs_node_blockptr(parent, i + 1); 2906b80053dSChris Mason close = close_blocks(blocknr, other, blocksize); 2916702ed49SChris Mason } 292e9d0b13bSChris Mason if (close) { 293e9d0b13bSChris Mason last_block = blocknr; 2946702ed49SChris Mason continue; 295e9d0b13bSChris Mason } 2965708b959SChris Mason if (parent->map_token) { 2975708b959SChris Mason unmap_extent_buffer(parent, parent->map_token, 2985708b959SChris Mason KM_USER1); 2995708b959SChris Mason parent->map_token = NULL; 3005708b959SChris Mason } 3016702ed49SChris Mason 3026b80053dSChris Mason cur = btrfs_find_tree_block(root, blocknr, blocksize); 3036b80053dSChris Mason if (cur) 3046b80053dSChris Mason uptodate = btrfs_buffer_uptodate(cur); 3056b80053dSChris Mason else 3066b80053dSChris Mason uptodate = 0; 3075708b959SChris Mason if (!cur || !uptodate) { 3086702ed49SChris Mason if (cache_only) { 3096b80053dSChris Mason free_extent_buffer(cur); 3106702ed49SChris Mason continue; 3116702ed49SChris Mason } 3126b80053dSChris Mason if (!cur) { 3136b80053dSChris Mason cur = read_tree_block(root, blocknr, 3146b80053dSChris Mason blocksize); 3156b80053dSChris Mason } else if (!uptodate) { 3166b80053dSChris Mason btrfs_read_buffer(cur); 3176702ed49SChris Mason } 318f2183bdeSChris Mason } 319e9d0b13bSChris Mason if (search_start == 0) 3206b80053dSChris Mason search_start = last_block; 321e9d0b13bSChris Mason 3226b80053dSChris Mason err = __btrfs_cow_block(trans, root, cur, parent, i, 3236b80053dSChris Mason &tmp, search_start, 3246b80053dSChris Mason min(16 * blocksize, 3256b80053dSChris Mason (end_slot - i) * blocksize)); 326252c38f0SYan if (err) { 3276b80053dSChris Mason free_extent_buffer(cur); 3286702ed49SChris Mason break; 329252c38f0SYan } 3306b80053dSChris Mason search_start = tmp->start; 3315708b959SChris Mason last_block = tmp->start; 332f2183bdeSChris Mason *last_ret = search_start; 333f2183bdeSChris Mason if (parent_level == 1) 3346b80053dSChris Mason btrfs_clear_buffer_defrag(tmp); 3356b80053dSChris Mason free_extent_buffer(tmp); 3366702ed49SChris Mason } 3375708b959SChris Mason if (parent->map_token) { 3385708b959SChris Mason unmap_extent_buffer(parent, parent->map_token, 3395708b959SChris Mason KM_USER1); 3405708b959SChris Mason parent->map_token = NULL; 3415708b959SChris Mason } 3426702ed49SChris Mason return err; 3436702ed49SChris Mason } 3446702ed49SChris Mason 34574123bd7SChris Mason /* 34674123bd7SChris Mason * The leaf data grows from end-to-front in the node. 34774123bd7SChris Mason * this returns the address of the start of the last item, 34874123bd7SChris Mason * which is the stop of the leaf data stack 34974123bd7SChris Mason */ 350123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 3515f39d397SChris Mason struct extent_buffer *leaf) 352be0e5c09SChris Mason { 3535f39d397SChris Mason u32 nr = btrfs_header_nritems(leaf); 354be0e5c09SChris Mason if (nr == 0) 355123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 3565f39d397SChris Mason return btrfs_item_offset_nr(leaf, nr - 1); 357be0e5c09SChris Mason } 358be0e5c09SChris Mason 359123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 360123abc88SChris Mason int level) 361aa5d6bedSChris Mason { 3625f39d397SChris Mason struct extent_buffer *parent = NULL; 3635f39d397SChris Mason struct extent_buffer *node = path->nodes[level]; 3645f39d397SChris Mason struct btrfs_disk_key parent_key; 3655f39d397SChris Mason struct btrfs_disk_key node_key; 366aa5d6bedSChris Mason int parent_slot; 3678d7be552SChris Mason int slot; 3688d7be552SChris Mason struct btrfs_key cpukey; 3695f39d397SChris Mason u32 nritems = btrfs_header_nritems(node); 370aa5d6bedSChris Mason 371aa5d6bedSChris Mason if (path->nodes[level + 1]) 3725f39d397SChris Mason parent = path->nodes[level + 1]; 373a1f39630SAneesh 3748d7be552SChris Mason slot = path->slots[level]; 3757518a238SChris Mason BUG_ON(nritems == 0); 3767518a238SChris Mason if (parent) { 377a1f39630SAneesh parent_slot = path->slots[level + 1]; 3785f39d397SChris Mason btrfs_node_key(parent, &parent_key, parent_slot); 3795f39d397SChris Mason btrfs_node_key(node, &node_key, 0); 3805f39d397SChris Mason BUG_ON(memcmp(&parent_key, &node_key, 381e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 3821d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 383db94535dSChris Mason btrfs_header_bytenr(node)); 384aa5d6bedSChris Mason } 385123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 3868d7be552SChris Mason if (slot != 0) { 3875f39d397SChris Mason btrfs_node_key_to_cpu(node, &cpukey, slot - 1); 3885f39d397SChris Mason btrfs_node_key(node, &node_key, slot); 3895f39d397SChris Mason BUG_ON(comp_keys(&node_key, &cpukey) <= 0); 3908d7be552SChris Mason } 3918d7be552SChris Mason if (slot < nritems - 1) { 3925f39d397SChris Mason btrfs_node_key_to_cpu(node, &cpukey, slot + 1); 3935f39d397SChris Mason btrfs_node_key(node, &node_key, slot); 3945f39d397SChris Mason BUG_ON(comp_keys(&node_key, &cpukey) >= 0); 395aa5d6bedSChris Mason } 396aa5d6bedSChris Mason return 0; 397aa5d6bedSChris Mason } 398aa5d6bedSChris Mason 399123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 400123abc88SChris Mason int level) 401aa5d6bedSChris Mason { 4025f39d397SChris Mason struct extent_buffer *leaf = path->nodes[level]; 4035f39d397SChris Mason struct extent_buffer *parent = NULL; 404aa5d6bedSChris Mason int parent_slot; 4058d7be552SChris Mason struct btrfs_key cpukey; 4065f39d397SChris Mason struct btrfs_disk_key parent_key; 4075f39d397SChris Mason struct btrfs_disk_key leaf_key; 4085f39d397SChris Mason int slot = path->slots[0]; 4098d7be552SChris Mason 4105f39d397SChris Mason u32 nritems = btrfs_header_nritems(leaf); 411aa5d6bedSChris Mason 412aa5d6bedSChris Mason if (path->nodes[level + 1]) 4135f39d397SChris Mason parent = path->nodes[level + 1]; 4147518a238SChris Mason 4157518a238SChris Mason if (nritems == 0) 4167518a238SChris Mason return 0; 4177518a238SChris Mason 4187518a238SChris Mason if (parent) { 419a1f39630SAneesh parent_slot = path->slots[level + 1]; 4205f39d397SChris Mason btrfs_node_key(parent, &parent_key, parent_slot); 4215f39d397SChris Mason btrfs_item_key(leaf, &leaf_key, 0); 4226702ed49SChris Mason 4235f39d397SChris Mason BUG_ON(memcmp(&parent_key, &leaf_key, 424e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 4251d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 426db94535dSChris Mason btrfs_header_bytenr(leaf)); 427aa5d6bedSChris Mason } 4285f39d397SChris Mason #if 0 4295f39d397SChris Mason for (i = 0; nritems > 1 && i < nritems - 2; i++) { 4305f39d397SChris Mason btrfs_item_key_to_cpu(leaf, &cpukey, i + 1); 4315f39d397SChris Mason btrfs_item_key(leaf, &leaf_key, i); 4325f39d397SChris Mason if (comp_keys(&leaf_key, &cpukey) >= 0) { 4335f39d397SChris Mason btrfs_print_leaf(root, leaf); 4345f39d397SChris Mason printk("slot %d offset bad key\n", i); 4355f39d397SChris Mason BUG_ON(1); 4365f39d397SChris Mason } 4375f39d397SChris Mason if (btrfs_item_offset_nr(leaf, i) != 4385f39d397SChris Mason btrfs_item_end_nr(leaf, i + 1)) { 4395f39d397SChris Mason btrfs_print_leaf(root, leaf); 4405f39d397SChris Mason printk("slot %d offset bad\n", i); 4415f39d397SChris Mason BUG_ON(1); 4425f39d397SChris Mason } 4435f39d397SChris Mason if (i == 0) { 4445f39d397SChris Mason if (btrfs_item_offset_nr(leaf, i) + 4455f39d397SChris Mason btrfs_item_size_nr(leaf, i) != 4465f39d397SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 4475f39d397SChris Mason btrfs_print_leaf(root, leaf); 4485f39d397SChris Mason printk("slot %d first offset bad\n", i); 4495f39d397SChris Mason BUG_ON(1); 4505f39d397SChris Mason } 4515f39d397SChris Mason } 4525f39d397SChris Mason } 4535f39d397SChris Mason if (nritems > 0) { 4545f39d397SChris Mason if (btrfs_item_size_nr(leaf, nritems - 1) > 4096) { 4555f39d397SChris Mason btrfs_print_leaf(root, leaf); 4565f39d397SChris Mason printk("slot %d bad size \n", nritems - 1); 4575f39d397SChris Mason BUG_ON(1); 4585f39d397SChris Mason } 4595f39d397SChris Mason } 4605f39d397SChris Mason #endif 4615f39d397SChris Mason if (slot != 0 && slot < nritems - 1) { 4625f39d397SChris Mason btrfs_item_key(leaf, &leaf_key, slot); 4635f39d397SChris Mason btrfs_item_key_to_cpu(leaf, &cpukey, slot - 1); 4645f39d397SChris Mason if (comp_keys(&leaf_key, &cpukey) <= 0) { 4655f39d397SChris Mason btrfs_print_leaf(root, leaf); 4665f39d397SChris Mason printk("slot %d offset bad key\n", slot); 4675f39d397SChris Mason BUG_ON(1); 4685f39d397SChris Mason } 4695f39d397SChris Mason if (btrfs_item_offset_nr(leaf, slot - 1) != 4705f39d397SChris Mason btrfs_item_end_nr(leaf, slot)) { 4715f39d397SChris Mason btrfs_print_leaf(root, leaf); 4725f39d397SChris Mason printk("slot %d offset bad\n", slot); 4735f39d397SChris Mason BUG_ON(1); 4745f39d397SChris Mason } 475aa5d6bedSChris Mason } 4768d7be552SChris Mason if (slot < nritems - 1) { 4775f39d397SChris Mason btrfs_item_key(leaf, &leaf_key, slot); 4785f39d397SChris Mason btrfs_item_key_to_cpu(leaf, &cpukey, slot + 1); 4795f39d397SChris Mason BUG_ON(comp_keys(&leaf_key, &cpukey) >= 0); 4805f39d397SChris Mason if (btrfs_item_offset_nr(leaf, slot) != 4815f39d397SChris Mason btrfs_item_end_nr(leaf, slot + 1)) { 4825f39d397SChris Mason btrfs_print_leaf(root, leaf); 4835f39d397SChris Mason printk("slot %d offset bad\n", slot); 4845f39d397SChris Mason BUG_ON(1); 485aa5d6bedSChris Mason } 4865f39d397SChris Mason } 4875f39d397SChris Mason BUG_ON(btrfs_item_offset_nr(leaf, 0) + 4885f39d397SChris Mason btrfs_item_size_nr(leaf, 0) != BTRFS_LEAF_DATA_SIZE(root)); 489aa5d6bedSChris Mason return 0; 490aa5d6bedSChris Mason } 491aa5d6bedSChris Mason 492123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 493123abc88SChris Mason int level) 494aa5d6bedSChris Mason { 495810191ffSChris Mason return 0; 496db94535dSChris Mason #if 0 4975f39d397SChris Mason struct extent_buffer *buf = path->nodes[level]; 4985f39d397SChris Mason 499479965d6SChris Mason if (memcmp_extent_buffer(buf, root->fs_info->fsid, 500479965d6SChris Mason (unsigned long)btrfs_header_fsid(buf), 501479965d6SChris Mason BTRFS_FSID_SIZE)) { 5025f39d397SChris Mason printk("warning bad block %Lu\n", buf->start); 503db94535dSChris Mason return 1; 5045f39d397SChris Mason } 505db94535dSChris Mason #endif 506aa5d6bedSChris Mason if (level == 0) 507123abc88SChris Mason return check_leaf(root, path, level); 508123abc88SChris Mason return check_node(root, path, level); 509aa5d6bedSChris Mason } 510aa5d6bedSChris Mason 51174123bd7SChris Mason /* 5125f39d397SChris Mason * search for key in the extent_buffer. The items start at offset p, 5135f39d397SChris Mason * and they are item_size apart. There are 'max' items in p. 5145f39d397SChris Mason * 51574123bd7SChris Mason * the slot in the array is returned via slot, and it points to 51674123bd7SChris Mason * the place where you would insert key if it is not found in 51774123bd7SChris Mason * the array. 51874123bd7SChris Mason * 51974123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 52074123bd7SChris Mason */ 5215f39d397SChris Mason static int generic_bin_search(struct extent_buffer *eb, unsigned long p, 5225f39d397SChris Mason int item_size, struct btrfs_key *key, 523be0e5c09SChris Mason int max, int *slot) 524be0e5c09SChris Mason { 525be0e5c09SChris Mason int low = 0; 526be0e5c09SChris Mason int high = max; 527be0e5c09SChris Mason int mid; 528be0e5c09SChris Mason int ret; 529479965d6SChris Mason struct btrfs_disk_key *tmp = NULL; 5305f39d397SChris Mason struct btrfs_disk_key unaligned; 5315f39d397SChris Mason unsigned long offset; 5325f39d397SChris Mason char *map_token = NULL; 5335f39d397SChris Mason char *kaddr = NULL; 5345f39d397SChris Mason unsigned long map_start = 0; 5355f39d397SChris Mason unsigned long map_len = 0; 536479965d6SChris Mason int err; 537be0e5c09SChris Mason 538be0e5c09SChris Mason while(low < high) { 539be0e5c09SChris Mason mid = (low + high) / 2; 5405f39d397SChris Mason offset = p + mid * item_size; 5415f39d397SChris Mason 5425f39d397SChris Mason if (!map_token || offset < map_start || 5435f39d397SChris Mason (offset + sizeof(struct btrfs_disk_key)) > 5445f39d397SChris Mason map_start + map_len) { 545479965d6SChris Mason if (map_token) { 5465f39d397SChris Mason unmap_extent_buffer(eb, map_token, KM_USER0); 547479965d6SChris Mason map_token = NULL; 548479965d6SChris Mason } 549479965d6SChris Mason err = map_extent_buffer(eb, offset, 550479965d6SChris Mason sizeof(struct btrfs_disk_key), 551479965d6SChris Mason &map_token, &kaddr, 5525f39d397SChris Mason &map_start, &map_len, KM_USER0); 5535f39d397SChris Mason 554479965d6SChris Mason if (!err) { 555479965d6SChris Mason tmp = (struct btrfs_disk_key *)(kaddr + offset - 556479965d6SChris Mason map_start); 557479965d6SChris Mason } else { 5585f39d397SChris Mason read_extent_buffer(eb, &unaligned, 5595f39d397SChris Mason offset, sizeof(unaligned)); 5605f39d397SChris Mason tmp = &unaligned; 561479965d6SChris Mason } 562479965d6SChris Mason 5635f39d397SChris Mason } else { 5645f39d397SChris Mason tmp = (struct btrfs_disk_key *)(kaddr + offset - 5655f39d397SChris Mason map_start); 5665f39d397SChris Mason } 567be0e5c09SChris Mason ret = comp_keys(tmp, key); 568be0e5c09SChris Mason 569be0e5c09SChris Mason if (ret < 0) 570be0e5c09SChris Mason low = mid + 1; 571be0e5c09SChris Mason else if (ret > 0) 572be0e5c09SChris Mason high = mid; 573be0e5c09SChris Mason else { 574be0e5c09SChris Mason *slot = mid; 575479965d6SChris Mason if (map_token) 5765f39d397SChris Mason unmap_extent_buffer(eb, map_token, KM_USER0); 577be0e5c09SChris Mason return 0; 578be0e5c09SChris Mason } 579be0e5c09SChris Mason } 580be0e5c09SChris Mason *slot = low; 5815f39d397SChris Mason if (map_token) 5825f39d397SChris Mason unmap_extent_buffer(eb, map_token, KM_USER0); 583be0e5c09SChris Mason return 1; 584be0e5c09SChris Mason } 585be0e5c09SChris Mason 58697571fd0SChris Mason /* 58797571fd0SChris Mason * simple bin_search frontend that does the right thing for 58897571fd0SChris Mason * leaves vs nodes 58997571fd0SChris Mason */ 5905f39d397SChris Mason static int bin_search(struct extent_buffer *eb, struct btrfs_key *key, 5915f39d397SChris Mason int level, int *slot) 592be0e5c09SChris Mason { 5935f39d397SChris Mason if (level == 0) { 5945f39d397SChris Mason return generic_bin_search(eb, 5955f39d397SChris Mason offsetof(struct btrfs_leaf, items), 5960783fcfcSChris Mason sizeof(struct btrfs_item), 5975f39d397SChris Mason key, btrfs_header_nritems(eb), 5987518a238SChris Mason slot); 599be0e5c09SChris Mason } else { 6005f39d397SChris Mason return generic_bin_search(eb, 6015f39d397SChris Mason offsetof(struct btrfs_node, ptrs), 602123abc88SChris Mason sizeof(struct btrfs_key_ptr), 6035f39d397SChris Mason key, btrfs_header_nritems(eb), 6047518a238SChris Mason slot); 605be0e5c09SChris Mason } 606be0e5c09SChris Mason return -1; 607be0e5c09SChris Mason } 608be0e5c09SChris Mason 6095f39d397SChris Mason static struct extent_buffer *read_node_slot(struct btrfs_root *root, 6105f39d397SChris Mason struct extent_buffer *parent, int slot) 611bb803951SChris Mason { 612bb803951SChris Mason if (slot < 0) 613bb803951SChris Mason return NULL; 6145f39d397SChris Mason if (slot >= btrfs_header_nritems(parent)) 615bb803951SChris Mason return NULL; 616db94535dSChris Mason return read_tree_block(root, btrfs_node_blockptr(parent, slot), 617db94535dSChris Mason btrfs_level_size(root, btrfs_header_level(parent) - 1)); 618bb803951SChris Mason } 619bb803951SChris Mason 620e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 621e089f05cSChris Mason *root, struct btrfs_path *path, int level) 622bb803951SChris Mason { 6235f39d397SChris Mason struct extent_buffer *right = NULL; 6245f39d397SChris Mason struct extent_buffer *mid; 6255f39d397SChris Mason struct extent_buffer *left = NULL; 6265f39d397SChris Mason struct extent_buffer *parent = NULL; 627bb803951SChris Mason int ret = 0; 628bb803951SChris Mason int wret; 629bb803951SChris Mason int pslot; 630bb803951SChris Mason int orig_slot = path->slots[level]; 63154aa1f4dSChris Mason int err_on_enospc = 0; 63279f95c82SChris Mason u64 orig_ptr; 633bb803951SChris Mason 634bb803951SChris Mason if (level == 0) 635bb803951SChris Mason return 0; 636bb803951SChris Mason 6375f39d397SChris Mason mid = path->nodes[level]; 638*7bb86316SChris Mason WARN_ON(btrfs_header_generation(mid) != trans->transid); 639*7bb86316SChris Mason 6401d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 64179f95c82SChris Mason 642234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 6435f39d397SChris Mason parent = path->nodes[level + 1]; 644bb803951SChris Mason pslot = path->slots[level + 1]; 645bb803951SChris Mason 64640689478SChris Mason /* 64740689478SChris Mason * deal with the case where there is only one pointer in the root 64840689478SChris Mason * by promoting the node below to a root 64940689478SChris Mason */ 6505f39d397SChris Mason if (!parent) { 6515f39d397SChris Mason struct extent_buffer *child; 652bb803951SChris Mason 6535f39d397SChris Mason if (btrfs_header_nritems(mid) != 1) 654bb803951SChris Mason return 0; 655bb803951SChris Mason 656bb803951SChris Mason /* promote the child to a root */ 6575f39d397SChris Mason child = read_node_slot(root, mid, 0); 658bb803951SChris Mason BUG_ON(!child); 659bb803951SChris Mason root->node = child; 660bb803951SChris Mason path->nodes[level] = NULL; 6615f39d397SChris Mason clean_tree_block(trans, root, mid); 6625f39d397SChris Mason wait_on_tree_block_writeback(root, mid); 663bb803951SChris Mason /* once for the path */ 6645f39d397SChris Mason free_extent_buffer(mid); 665*7bb86316SChris Mason ret = btrfs_free_extent(trans, root, mid->start, mid->len, 666*7bb86316SChris Mason root->root_key.objectid, 667*7bb86316SChris Mason btrfs_header_generation(mid), 0, 0, 1); 668bb803951SChris Mason /* once for the root ptr */ 6695f39d397SChris Mason free_extent_buffer(mid); 670db94535dSChris Mason return ret; 671bb803951SChris Mason } 6725f39d397SChris Mason if (btrfs_header_nritems(mid) > 673123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 674bb803951SChris Mason return 0; 675bb803951SChris Mason 6765f39d397SChris Mason if (btrfs_header_nritems(mid) < 2) 67754aa1f4dSChris Mason err_on_enospc = 1; 67854aa1f4dSChris Mason 6795f39d397SChris Mason left = read_node_slot(root, parent, pslot - 1); 6805f39d397SChris Mason if (left) { 6815f39d397SChris Mason wret = btrfs_cow_block(trans, root, left, 6825f39d397SChris Mason parent, pslot - 1, &left); 68354aa1f4dSChris Mason if (wret) { 68454aa1f4dSChris Mason ret = wret; 68554aa1f4dSChris Mason goto enospc; 68654aa1f4dSChris Mason } 6872cc58cf2SChris Mason } 6885f39d397SChris Mason right = read_node_slot(root, parent, pslot + 1); 6895f39d397SChris Mason if (right) { 6905f39d397SChris Mason wret = btrfs_cow_block(trans, root, right, 6915f39d397SChris Mason parent, pslot + 1, &right); 6922cc58cf2SChris Mason if (wret) { 6932cc58cf2SChris Mason ret = wret; 6942cc58cf2SChris Mason goto enospc; 6952cc58cf2SChris Mason } 6962cc58cf2SChris Mason } 6972cc58cf2SChris Mason 6982cc58cf2SChris Mason /* first, try to make some room in the middle buffer */ 6995f39d397SChris Mason if (left) { 7005f39d397SChris Mason orig_slot += btrfs_header_nritems(left); 7015f39d397SChris Mason wret = push_node_left(trans, root, left, mid); 70279f95c82SChris Mason if (wret < 0) 70379f95c82SChris Mason ret = wret; 7045f39d397SChris Mason if (btrfs_header_nritems(mid) < 2) 70554aa1f4dSChris Mason err_on_enospc = 1; 706bb803951SChris Mason } 70779f95c82SChris Mason 70879f95c82SChris Mason /* 70979f95c82SChris Mason * then try to empty the right most buffer into the middle 71079f95c82SChris Mason */ 7115f39d397SChris Mason if (right) { 7125f39d397SChris Mason wret = push_node_left(trans, root, mid, right); 71354aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 71479f95c82SChris Mason ret = wret; 7155f39d397SChris Mason if (btrfs_header_nritems(right) == 0) { 716db94535dSChris Mason u64 bytenr = right->start; 717*7bb86316SChris Mason u64 generation = btrfs_header_generation(parent); 718db94535dSChris Mason u32 blocksize = right->len; 719db94535dSChris Mason 7205f39d397SChris Mason clean_tree_block(trans, root, right); 7215f39d397SChris Mason wait_on_tree_block_writeback(root, right); 7225f39d397SChris Mason free_extent_buffer(right); 723bb803951SChris Mason right = NULL; 724e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 725e089f05cSChris Mason 1); 726bb803951SChris Mason if (wret) 727bb803951SChris Mason ret = wret; 728db94535dSChris Mason wret = btrfs_free_extent(trans, root, bytenr, 729*7bb86316SChris Mason blocksize, 730*7bb86316SChris Mason btrfs_header_owner(parent), 731*7bb86316SChris Mason generation, 0, 0, 1); 732bb803951SChris Mason if (wret) 733bb803951SChris Mason ret = wret; 734bb803951SChris Mason } else { 7355f39d397SChris Mason struct btrfs_disk_key right_key; 7365f39d397SChris Mason btrfs_node_key(right, &right_key, 0); 7375f39d397SChris Mason btrfs_set_node_key(parent, &right_key, pslot + 1); 7385f39d397SChris Mason btrfs_mark_buffer_dirty(parent); 739bb803951SChris Mason } 740bb803951SChris Mason } 7415f39d397SChris Mason if (btrfs_header_nritems(mid) == 1) { 74279f95c82SChris Mason /* 74379f95c82SChris Mason * we're not allowed to leave a node with one item in the 74479f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 74579f95c82SChris Mason * could try to delete the only pointer in this node. 74679f95c82SChris Mason * So, pull some keys from the left. 74779f95c82SChris Mason * There has to be a left pointer at this point because 74879f95c82SChris Mason * otherwise we would have pulled some pointers from the 74979f95c82SChris Mason * right 75079f95c82SChris Mason */ 7515f39d397SChris Mason BUG_ON(!left); 7525f39d397SChris Mason wret = balance_node_right(trans, root, mid, left); 75354aa1f4dSChris Mason if (wret < 0) { 75479f95c82SChris Mason ret = wret; 75554aa1f4dSChris Mason goto enospc; 75654aa1f4dSChris Mason } 75779f95c82SChris Mason BUG_ON(wret == 1); 75879f95c82SChris Mason } 7595f39d397SChris Mason if (btrfs_header_nritems(mid) == 0) { 76079f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 761*7bb86316SChris Mason u64 root_gen = btrfs_header_generation(parent); 762db94535dSChris Mason u64 bytenr = mid->start; 763db94535dSChris Mason u32 blocksize = mid->len; 7645f39d397SChris Mason clean_tree_block(trans, root, mid); 7655f39d397SChris Mason wait_on_tree_block_writeback(root, mid); 7665f39d397SChris Mason free_extent_buffer(mid); 767bb803951SChris Mason mid = NULL; 768e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 769bb803951SChris Mason if (wret) 770bb803951SChris Mason ret = wret; 771*7bb86316SChris Mason wret = btrfs_free_extent(trans, root, bytenr, blocksize, 772*7bb86316SChris Mason btrfs_header_owner(parent), 773*7bb86316SChris Mason root_gen, 0, 0, 1); 774bb803951SChris Mason if (wret) 775bb803951SChris Mason ret = wret; 77679f95c82SChris Mason } else { 77779f95c82SChris Mason /* update the parent key to reflect our changes */ 7785f39d397SChris Mason struct btrfs_disk_key mid_key; 7795f39d397SChris Mason btrfs_node_key(mid, &mid_key, 0); 7805f39d397SChris Mason btrfs_set_node_key(parent, &mid_key, pslot); 7815f39d397SChris Mason btrfs_mark_buffer_dirty(parent); 78279f95c82SChris Mason } 783bb803951SChris Mason 78479f95c82SChris Mason /* update the path */ 7855f39d397SChris Mason if (left) { 7865f39d397SChris Mason if (btrfs_header_nritems(left) > orig_slot) { 7875f39d397SChris Mason extent_buffer_get(left); 7885f39d397SChris Mason path->nodes[level] = left; 789bb803951SChris Mason path->slots[level + 1] -= 1; 790bb803951SChris Mason path->slots[level] = orig_slot; 7915f39d397SChris Mason if (mid) 7925f39d397SChris Mason free_extent_buffer(mid); 793bb803951SChris Mason } else { 7945f39d397SChris Mason orig_slot -= btrfs_header_nritems(left); 795bb803951SChris Mason path->slots[level] = orig_slot; 796bb803951SChris Mason } 797bb803951SChris Mason } 79879f95c82SChris Mason /* double check we haven't messed things up */ 799123abc88SChris Mason check_block(root, path, level); 800e20d96d6SChris Mason if (orig_ptr != 8015f39d397SChris Mason btrfs_node_blockptr(path->nodes[level], path->slots[level])) 80279f95c82SChris Mason BUG(); 80354aa1f4dSChris Mason enospc: 8045f39d397SChris Mason if (right) 8055f39d397SChris Mason free_extent_buffer(right); 8065f39d397SChris Mason if (left) 8075f39d397SChris Mason free_extent_buffer(left); 808bb803951SChris Mason return ret; 809bb803951SChris Mason } 810bb803951SChris Mason 811e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 812e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 813e66f709bSChris Mason struct btrfs_root *root, 814e66f709bSChris Mason struct btrfs_path *path, int level) 815e66f709bSChris Mason { 8165f39d397SChris Mason struct extent_buffer *right = NULL; 8175f39d397SChris Mason struct extent_buffer *mid; 8185f39d397SChris Mason struct extent_buffer *left = NULL; 8195f39d397SChris Mason struct extent_buffer *parent = NULL; 820e66f709bSChris Mason int ret = 0; 821e66f709bSChris Mason int wret; 822e66f709bSChris Mason int pslot; 823e66f709bSChris Mason int orig_slot = path->slots[level]; 824e66f709bSChris Mason u64 orig_ptr; 825e66f709bSChris Mason 826e66f709bSChris Mason if (level == 0) 827e66f709bSChris Mason return 1; 828e66f709bSChris Mason 8295f39d397SChris Mason mid = path->nodes[level]; 830*7bb86316SChris Mason WARN_ON(btrfs_header_generation(mid) != trans->transid); 831e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 832e66f709bSChris Mason 833e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 8345f39d397SChris Mason parent = path->nodes[level + 1]; 835e66f709bSChris Mason pslot = path->slots[level + 1]; 836e66f709bSChris Mason 8375f39d397SChris Mason if (!parent) 838e66f709bSChris Mason return 1; 839e66f709bSChris Mason 8405f39d397SChris Mason left = read_node_slot(root, parent, pslot - 1); 841e66f709bSChris Mason 842e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 8435f39d397SChris Mason if (left) { 844e66f709bSChris Mason u32 left_nr; 8455f39d397SChris Mason left_nr = btrfs_header_nritems(left); 84633ade1f8SChris Mason if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 84733ade1f8SChris Mason wret = 1; 84833ade1f8SChris Mason } else { 8495f39d397SChris Mason ret = btrfs_cow_block(trans, root, left, parent, 8505f39d397SChris Mason pslot - 1, &left); 85154aa1f4dSChris Mason if (ret) 85254aa1f4dSChris Mason wret = 1; 85354aa1f4dSChris Mason else { 85454aa1f4dSChris Mason wret = push_node_left(trans, root, 8555f39d397SChris Mason left, mid); 85654aa1f4dSChris Mason } 85733ade1f8SChris Mason } 858e66f709bSChris Mason if (wret < 0) 859e66f709bSChris Mason ret = wret; 860e66f709bSChris Mason if (wret == 0) { 8615f39d397SChris Mason struct btrfs_disk_key disk_key; 862e66f709bSChris Mason orig_slot += left_nr; 8635f39d397SChris Mason btrfs_node_key(mid, &disk_key, 0); 8645f39d397SChris Mason btrfs_set_node_key(parent, &disk_key, pslot); 8655f39d397SChris Mason btrfs_mark_buffer_dirty(parent); 8665f39d397SChris Mason if (btrfs_header_nritems(left) > orig_slot) { 8675f39d397SChris Mason path->nodes[level] = left; 868e66f709bSChris Mason path->slots[level + 1] -= 1; 869e66f709bSChris Mason path->slots[level] = orig_slot; 8705f39d397SChris Mason free_extent_buffer(mid); 871e66f709bSChris Mason } else { 872e66f709bSChris Mason orig_slot -= 8735f39d397SChris Mason btrfs_header_nritems(left); 874e66f709bSChris Mason path->slots[level] = orig_slot; 8755f39d397SChris Mason free_extent_buffer(left); 876e66f709bSChris Mason } 877e66f709bSChris Mason return 0; 878e66f709bSChris Mason } 8795f39d397SChris Mason free_extent_buffer(left); 880e66f709bSChris Mason } 8815f39d397SChris Mason right= read_node_slot(root, parent, pslot + 1); 882e66f709bSChris Mason 883e66f709bSChris Mason /* 884e66f709bSChris Mason * then try to empty the right most buffer into the middle 885e66f709bSChris Mason */ 8865f39d397SChris Mason if (right) { 88733ade1f8SChris Mason u32 right_nr; 8885f39d397SChris Mason right_nr = btrfs_header_nritems(right); 88933ade1f8SChris Mason if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 89033ade1f8SChris Mason wret = 1; 89133ade1f8SChris Mason } else { 8925f39d397SChris Mason ret = btrfs_cow_block(trans, root, right, 8935f39d397SChris Mason parent, pslot + 1, 8945f39d397SChris Mason &right); 89554aa1f4dSChris Mason if (ret) 89654aa1f4dSChris Mason wret = 1; 89754aa1f4dSChris Mason else { 89833ade1f8SChris Mason wret = balance_node_right(trans, root, 8995f39d397SChris Mason right, mid); 90033ade1f8SChris Mason } 90154aa1f4dSChris Mason } 902e66f709bSChris Mason if (wret < 0) 903e66f709bSChris Mason ret = wret; 904e66f709bSChris Mason if (wret == 0) { 9055f39d397SChris Mason struct btrfs_disk_key disk_key; 9065f39d397SChris Mason 9075f39d397SChris Mason btrfs_node_key(right, &disk_key, 0); 9085f39d397SChris Mason btrfs_set_node_key(parent, &disk_key, pslot + 1); 9095f39d397SChris Mason btrfs_mark_buffer_dirty(parent); 9105f39d397SChris Mason 9115f39d397SChris Mason if (btrfs_header_nritems(mid) <= orig_slot) { 9125f39d397SChris Mason path->nodes[level] = right; 913e66f709bSChris Mason path->slots[level + 1] += 1; 914e66f709bSChris Mason path->slots[level] = orig_slot - 9155f39d397SChris Mason btrfs_header_nritems(mid); 9165f39d397SChris Mason free_extent_buffer(mid); 917e66f709bSChris Mason } else { 9185f39d397SChris Mason free_extent_buffer(right); 919e66f709bSChris Mason } 920e66f709bSChris Mason return 0; 921e66f709bSChris Mason } 9225f39d397SChris Mason free_extent_buffer(right); 923e66f709bSChris Mason } 924e66f709bSChris Mason return 1; 925e66f709bSChris Mason } 926e66f709bSChris Mason 92774123bd7SChris Mason /* 9283c69faecSChris Mason * readahead one full node of leaves 9293c69faecSChris Mason */ 9303c69faecSChris Mason static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, 9316702ed49SChris Mason int level, int slot) 9323c69faecSChris Mason { 9335f39d397SChris Mason struct extent_buffer *node; 9343c69faecSChris Mason u32 nritems; 9353c69faecSChris Mason u64 search; 9366b80053dSChris Mason u64 lowest_read; 9376b80053dSChris Mason u64 highest_read; 9386b80053dSChris Mason u64 nread = 0; 9393c69faecSChris Mason int direction = path->reada; 9405f39d397SChris Mason struct extent_buffer *eb; 9416b80053dSChris Mason u32 nr; 9426b80053dSChris Mason u32 blocksize; 9436b80053dSChris Mason u32 nscan = 0; 944db94535dSChris Mason 945a6b6e75eSChris Mason if (level != 1) 9463c69faecSChris Mason return; 9473c69faecSChris Mason 9486702ed49SChris Mason if (!path->nodes[level]) 9496702ed49SChris Mason return; 9506702ed49SChris Mason 9515f39d397SChris Mason node = path->nodes[level]; 9523c69faecSChris Mason search = btrfs_node_blockptr(node, slot); 9536b80053dSChris Mason blocksize = btrfs_level_size(root, level - 1); 9546b80053dSChris Mason eb = btrfs_find_tree_block(root, search, blocksize); 9555f39d397SChris Mason if (eb) { 9565f39d397SChris Mason free_extent_buffer(eb); 9573c69faecSChris Mason return; 9583c69faecSChris Mason } 9593c69faecSChris Mason 9606b80053dSChris Mason highest_read = search; 9616b80053dSChris Mason lowest_read = search; 9626b80053dSChris Mason 9635f39d397SChris Mason nritems = btrfs_header_nritems(node); 9646b80053dSChris Mason nr = slot; 9653c69faecSChris Mason while(1) { 9666b80053dSChris Mason if (direction < 0) { 9676b80053dSChris Mason if (nr == 0) 9683c69faecSChris Mason break; 9696b80053dSChris Mason nr--; 9706b80053dSChris Mason } else if (direction > 0) { 9716b80053dSChris Mason nr++; 9726b80053dSChris Mason if (nr >= nritems) 9736b80053dSChris Mason break; 9743c69faecSChris Mason } 9756b80053dSChris Mason search = btrfs_node_blockptr(node, nr); 9766b80053dSChris Mason if ((search >= lowest_read && search <= highest_read) || 9776b80053dSChris Mason (search < lowest_read && lowest_read - search <= 32768) || 9786b80053dSChris Mason (search > highest_read && search - highest_read <= 32768)) { 9796b80053dSChris Mason readahead_tree_block(root, search, blocksize); 9806b80053dSChris Mason nread += blocksize; 9813c69faecSChris Mason } 9826b80053dSChris Mason nscan++; 9836b80053dSChris Mason if (path->reada < 2 && (nread > (256 * 1024) || nscan > 32)) 9846b80053dSChris Mason break; 9856b80053dSChris Mason if(nread > (1024 * 1024) || nscan > 128) 9866b80053dSChris Mason break; 9876b80053dSChris Mason 9886b80053dSChris Mason if (search < lowest_read) 9896b80053dSChris Mason lowest_read = search; 9906b80053dSChris Mason if (search > highest_read) 9916b80053dSChris Mason highest_read = search; 9923c69faecSChris Mason } 9933c69faecSChris Mason } 9943c69faecSChris Mason /* 99574123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 99674123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 99774123bd7SChris Mason * level of the path (level 0) 99874123bd7SChris Mason * 99974123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 1000aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 1001aa5d6bedSChris Mason * search a negative error number is returned. 100297571fd0SChris Mason * 100397571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 100497571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 100597571fd0SChris Mason * possible) 100674123bd7SChris Mason */ 1007e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 1008e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 1009e089f05cSChris Mason ins_len, int cow) 1010be0e5c09SChris Mason { 10115f39d397SChris Mason struct extent_buffer *b; 1012db94535dSChris Mason u64 bytenr; 101374493f7aSChris Mason u64 ptr_gen; 1014be0e5c09SChris Mason int slot; 1015be0e5c09SChris Mason int ret; 1016be0e5c09SChris Mason int level; 10173c69faecSChris Mason int should_reada = p->reada; 10189f3a7427SChris Mason u8 lowest_level = 0; 10199f3a7427SChris Mason 10206702ed49SChris Mason lowest_level = p->lowest_level; 10216702ed49SChris Mason WARN_ON(lowest_level && ins_len); 102222b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 102322b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 1024bb803951SChris Mason again: 1025bb803951SChris Mason b = root->node; 10265f39d397SChris Mason extent_buffer_get(b); 1027eb60ceacSChris Mason while (b) { 10285f39d397SChris Mason level = btrfs_header_level(b); 102902217ed2SChris Mason if (cow) { 103002217ed2SChris Mason int wret; 1031e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 1032e20d96d6SChris Mason p->nodes[level + 1], 1033e20d96d6SChris Mason p->slots[level + 1], 1034252c38f0SYan &b); 103554aa1f4dSChris Mason if (wret) { 10365f39d397SChris Mason free_extent_buffer(b); 103754aa1f4dSChris Mason return wret; 103854aa1f4dSChris Mason } 103902217ed2SChris Mason } 104002217ed2SChris Mason BUG_ON(!cow && ins_len); 10415f39d397SChris Mason if (level != btrfs_header_level(b)) 10422c90e5d6SChris Mason WARN_ON(1); 10435f39d397SChris Mason level = btrfs_header_level(b); 1044eb60ceacSChris Mason p->nodes[level] = b; 1045123abc88SChris Mason ret = check_block(root, p, level); 1046aa5d6bedSChris Mason if (ret) 1047aa5d6bedSChris Mason return -1; 10485f39d397SChris Mason ret = bin_search(b, key, level, &slot); 10495f39d397SChris Mason if (level != 0) { 1050be0e5c09SChris Mason if (ret && slot > 0) 1051be0e5c09SChris Mason slot -= 1; 1052be0e5c09SChris Mason p->slots[level] = slot; 10535f39d397SChris Mason if (ins_len > 0 && btrfs_header_nritems(b) >= 1054d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 1055e089f05cSChris Mason int sret = split_node(trans, root, p, level); 10565c680ed6SChris Mason BUG_ON(sret > 0); 10575c680ed6SChris Mason if (sret) 10585c680ed6SChris Mason return sret; 10595c680ed6SChris Mason b = p->nodes[level]; 10605c680ed6SChris Mason slot = p->slots[level]; 1061bb803951SChris Mason } else if (ins_len < 0) { 1062e089f05cSChris Mason int sret = balance_level(trans, root, p, 1063e089f05cSChris Mason level); 1064bb803951SChris Mason if (sret) 1065bb803951SChris Mason return sret; 1066bb803951SChris Mason b = p->nodes[level]; 1067f510cfecSChris Mason if (!b) { 1068f510cfecSChris Mason btrfs_release_path(NULL, p); 1069bb803951SChris Mason goto again; 1070f510cfecSChris Mason } 1071bb803951SChris Mason slot = p->slots[level]; 10725f39d397SChris Mason BUG_ON(btrfs_header_nritems(b) == 1); 10735c680ed6SChris Mason } 10749f3a7427SChris Mason /* this is only true while dropping a snapshot */ 10759f3a7427SChris Mason if (level == lowest_level) 10769f3a7427SChris Mason break; 1077db94535dSChris Mason bytenr = btrfs_node_blockptr(b, slot); 107874493f7aSChris Mason ptr_gen = btrfs_node_ptr_generation(b, slot); 10796702ed49SChris Mason if (should_reada) 10806702ed49SChris Mason reada_for_search(root, p, level, slot); 1081db94535dSChris Mason b = read_tree_block(root, bytenr, 1082db94535dSChris Mason btrfs_level_size(root, level - 1)); 108374493f7aSChris Mason if (ptr_gen != btrfs_header_generation(b)) { 108474493f7aSChris Mason printk("block %llu bad gen wanted %llu " 108574493f7aSChris Mason "found %llu\n", 108674493f7aSChris Mason (unsigned long long)b->start, 108774493f7aSChris Mason (unsigned long long)ptr_gen, 108874493f7aSChris Mason (unsigned long long)btrfs_header_generation(b)); 108974493f7aSChris Mason } 1090be0e5c09SChris Mason } else { 1091be0e5c09SChris Mason p->slots[level] = slot; 10925f39d397SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, b) < 10930783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 1094d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 1095cc0c5538SChris Mason p, ins_len, ret == 0); 10965c680ed6SChris Mason BUG_ON(sret > 0); 10975c680ed6SChris Mason if (sret) 10985c680ed6SChris Mason return sret; 10995c680ed6SChris Mason } 1100be0e5c09SChris Mason return ret; 1101be0e5c09SChris Mason } 1102be0e5c09SChris Mason } 1103aa5d6bedSChris Mason return 1; 1104be0e5c09SChris Mason } 1105be0e5c09SChris Mason 110674123bd7SChris Mason /* 110774123bd7SChris Mason * adjust the pointers going up the tree, starting at level 110874123bd7SChris Mason * making sure the right key of each node is points to 'key'. 110974123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 111074123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 111174123bd7SChris Mason * higher levels 1112aa5d6bedSChris Mason * 1113aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 1114aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 111574123bd7SChris Mason */ 11165f39d397SChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, 11175f39d397SChris Mason struct btrfs_root *root, struct btrfs_path *path, 11185f39d397SChris Mason struct btrfs_disk_key *key, int level) 1119be0e5c09SChris Mason { 1120be0e5c09SChris Mason int i; 1121aa5d6bedSChris Mason int ret = 0; 11225f39d397SChris Mason struct extent_buffer *t; 11235f39d397SChris Mason 1124234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 1125be0e5c09SChris Mason int tslot = path->slots[i]; 1126eb60ceacSChris Mason if (!path->nodes[i]) 1127be0e5c09SChris Mason break; 11285f39d397SChris Mason t = path->nodes[i]; 11295f39d397SChris Mason btrfs_set_node_key(t, key, tslot); 1130d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 1131be0e5c09SChris Mason if (tslot != 0) 1132be0e5c09SChris Mason break; 1133be0e5c09SChris Mason } 1134aa5d6bedSChris Mason return ret; 1135be0e5c09SChris Mason } 1136be0e5c09SChris Mason 113774123bd7SChris Mason /* 113874123bd7SChris Mason * try to push data from one node into the next node left in the 113979f95c82SChris Mason * tree. 1140aa5d6bedSChris Mason * 1141aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 1142aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 114374123bd7SChris Mason */ 1144e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 11455f39d397SChris Mason *root, struct extent_buffer *dst, 11465f39d397SChris Mason struct extent_buffer *src) 1147be0e5c09SChris Mason { 1148be0e5c09SChris Mason int push_items = 0; 1149bb803951SChris Mason int src_nritems; 1150bb803951SChris Mason int dst_nritems; 1151aa5d6bedSChris Mason int ret = 0; 1152be0e5c09SChris Mason 11535f39d397SChris Mason src_nritems = btrfs_header_nritems(src); 11545f39d397SChris Mason dst_nritems = btrfs_header_nritems(dst); 1155123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 1156*7bb86316SChris Mason WARN_ON(btrfs_header_generation(src) != trans->transid); 1157*7bb86316SChris Mason WARN_ON(btrfs_header_generation(dst) != trans->transid); 115854aa1f4dSChris Mason 1159eb60ceacSChris Mason if (push_items <= 0) { 1160be0e5c09SChris Mason return 1; 1161eb60ceacSChris Mason } 1162be0e5c09SChris Mason 1163be0e5c09SChris Mason if (src_nritems < push_items) 1164be0e5c09SChris Mason push_items = src_nritems; 116579f95c82SChris Mason 11665f39d397SChris Mason copy_extent_buffer(dst, src, 11675f39d397SChris Mason btrfs_node_key_ptr_offset(dst_nritems), 11685f39d397SChris Mason btrfs_node_key_ptr_offset(0), 1169123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 11705f39d397SChris Mason 1171bb803951SChris Mason if (push_items < src_nritems) { 11725f39d397SChris Mason memmove_extent_buffer(src, btrfs_node_key_ptr_offset(0), 11735f39d397SChris Mason btrfs_node_key_ptr_offset(push_items), 1174e2fa7227SChris Mason (src_nritems - push_items) * 1175123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 1176bb803951SChris Mason } 11775f39d397SChris Mason btrfs_set_header_nritems(src, src_nritems - push_items); 11785f39d397SChris Mason btrfs_set_header_nritems(dst, dst_nritems + push_items); 11795f39d397SChris Mason btrfs_mark_buffer_dirty(src); 11805f39d397SChris Mason btrfs_mark_buffer_dirty(dst); 1181bb803951SChris Mason return ret; 1182be0e5c09SChris Mason } 1183be0e5c09SChris Mason 118497571fd0SChris Mason /* 118579f95c82SChris Mason * try to push data from one node into the next node right in the 118679f95c82SChris Mason * tree. 118779f95c82SChris Mason * 118879f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 118979f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 119079f95c82SChris Mason * 119179f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 119279f95c82SChris Mason */ 11935f39d397SChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, 11945f39d397SChris Mason struct btrfs_root *root, 11955f39d397SChris Mason struct extent_buffer *dst, 11965f39d397SChris Mason struct extent_buffer *src) 119779f95c82SChris Mason { 119879f95c82SChris Mason int push_items = 0; 119979f95c82SChris Mason int max_push; 120079f95c82SChris Mason int src_nritems; 120179f95c82SChris Mason int dst_nritems; 120279f95c82SChris Mason int ret = 0; 120379f95c82SChris Mason 1204*7bb86316SChris Mason WARN_ON(btrfs_header_generation(src) != trans->transid); 1205*7bb86316SChris Mason WARN_ON(btrfs_header_generation(dst) != trans->transid); 1206*7bb86316SChris Mason 12075f39d397SChris Mason src_nritems = btrfs_header_nritems(src); 12085f39d397SChris Mason dst_nritems = btrfs_header_nritems(dst); 1209123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 12105f39d397SChris Mason if (push_items <= 0) 121179f95c82SChris Mason return 1; 121279f95c82SChris Mason 121379f95c82SChris Mason max_push = src_nritems / 2 + 1; 121479f95c82SChris Mason /* don't try to empty the node */ 1215252c38f0SYan if (max_push >= src_nritems) 121679f95c82SChris Mason return 1; 1217252c38f0SYan 121879f95c82SChris Mason if (max_push < push_items) 121979f95c82SChris Mason push_items = max_push; 122079f95c82SChris Mason 12215f39d397SChris Mason memmove_extent_buffer(dst, btrfs_node_key_ptr_offset(push_items), 12225f39d397SChris Mason btrfs_node_key_ptr_offset(0), 12235f39d397SChris Mason (dst_nritems) * 12245f39d397SChris Mason sizeof(struct btrfs_key_ptr)); 1225d6025579SChris Mason 12265f39d397SChris Mason copy_extent_buffer(dst, src, 12275f39d397SChris Mason btrfs_node_key_ptr_offset(0), 12285f39d397SChris Mason btrfs_node_key_ptr_offset(src_nritems - push_items), 1229123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 123079f95c82SChris Mason 12315f39d397SChris Mason btrfs_set_header_nritems(src, src_nritems - push_items); 12325f39d397SChris Mason btrfs_set_header_nritems(dst, dst_nritems + push_items); 123379f95c82SChris Mason 12345f39d397SChris Mason btrfs_mark_buffer_dirty(src); 12355f39d397SChris Mason btrfs_mark_buffer_dirty(dst); 123679f95c82SChris Mason return ret; 123779f95c82SChris Mason } 123879f95c82SChris Mason 123979f95c82SChris Mason /* 124097571fd0SChris Mason * helper function to insert a new root level in the tree. 124197571fd0SChris Mason * A new node is allocated, and a single item is inserted to 124297571fd0SChris Mason * point to the existing root 1243aa5d6bedSChris Mason * 1244aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 124597571fd0SChris Mason */ 12465f39d397SChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, 12475f39d397SChris Mason struct btrfs_root *root, 12485f39d397SChris Mason struct btrfs_path *path, int level) 124974123bd7SChris Mason { 1250*7bb86316SChris Mason u64 root_gen; 1251*7bb86316SChris Mason u64 lower_gen; 12525f39d397SChris Mason struct extent_buffer *lower; 12535f39d397SChris Mason struct extent_buffer *c; 12545f39d397SChris Mason struct btrfs_disk_key lower_key; 12555c680ed6SChris Mason 12565c680ed6SChris Mason BUG_ON(path->nodes[level]); 12575c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 12585c680ed6SChris Mason 1259*7bb86316SChris Mason if (root->ref_cows) 1260*7bb86316SChris Mason root_gen = trans->transid; 1261*7bb86316SChris Mason else 1262*7bb86316SChris Mason root_gen = 0; 1263*7bb86316SChris Mason 1264*7bb86316SChris Mason lower = path->nodes[level-1]; 1265*7bb86316SChris Mason if (level == 1) 1266*7bb86316SChris Mason btrfs_item_key(lower, &lower_key, 0); 1267*7bb86316SChris Mason else 1268*7bb86316SChris Mason btrfs_node_key(lower, &lower_key, 0); 1269*7bb86316SChris Mason 1270*7bb86316SChris Mason c = __btrfs_alloc_free_block(trans, root, root->nodesize, 1271*7bb86316SChris Mason root->root_key.objectid, 1272*7bb86316SChris Mason root_gen, lower_key.objectid, level, 1273db94535dSChris Mason root->node->start, 0); 12745f39d397SChris Mason if (IS_ERR(c)) 12755f39d397SChris Mason return PTR_ERR(c); 12765f39d397SChris Mason memset_extent_buffer(c, 0, 0, root->nodesize); 12775f39d397SChris Mason btrfs_set_header_nritems(c, 1); 12785f39d397SChris Mason btrfs_set_header_level(c, level); 1279db94535dSChris Mason btrfs_set_header_bytenr(c, c->start); 12805f39d397SChris Mason btrfs_set_header_generation(c, trans->transid); 12815f39d397SChris Mason btrfs_set_header_owner(c, root->root_key.objectid); 1282d5719762SChris Mason 12835f39d397SChris Mason write_extent_buffer(c, root->fs_info->fsid, 12845f39d397SChris Mason (unsigned long)btrfs_header_fsid(c), 12855f39d397SChris Mason BTRFS_FSID_SIZE); 12865f39d397SChris Mason btrfs_set_node_key(c, &lower_key, 0); 1287db94535dSChris Mason btrfs_set_node_blockptr(c, 0, lower->start); 1288*7bb86316SChris Mason lower_gen = btrfs_header_generation(lower); 1289*7bb86316SChris Mason WARN_ON(lower_gen == 0); 1290*7bb86316SChris Mason 1291*7bb86316SChris Mason btrfs_set_node_ptr_generation(c, 0, lower_gen); 12925f39d397SChris Mason 12935f39d397SChris Mason btrfs_mark_buffer_dirty(c); 1294d5719762SChris Mason 1295cfaa7295SChris Mason /* the super has an extra ref to root->node */ 12965f39d397SChris Mason free_extent_buffer(root->node); 12975f39d397SChris Mason root->node = c; 12985f39d397SChris Mason extent_buffer_get(c); 12995f39d397SChris Mason path->nodes[level] = c; 130074123bd7SChris Mason path->slots[level] = 0; 1301*7bb86316SChris Mason 1302*7bb86316SChris Mason if (root->ref_cows && lower_gen != trans->transid) { 1303*7bb86316SChris Mason struct btrfs_path *back_path = btrfs_alloc_path(); 1304*7bb86316SChris Mason int ret; 1305*7bb86316SChris Mason ret = btrfs_insert_extent_backref(trans, 1306*7bb86316SChris Mason root->fs_info->extent_root, 1307*7bb86316SChris Mason path, lower->start, 1308*7bb86316SChris Mason root->root_key.objectid, 1309*7bb86316SChris Mason trans->transid, 0, 0); 1310*7bb86316SChris Mason BUG_ON(ret); 1311*7bb86316SChris Mason btrfs_free_path(back_path); 1312*7bb86316SChris Mason } 131374123bd7SChris Mason return 0; 131474123bd7SChris Mason } 13155c680ed6SChris Mason 13165c680ed6SChris Mason /* 13175c680ed6SChris Mason * worker function to insert a single pointer in a node. 13185c680ed6SChris Mason * the node should have enough room for the pointer already 131997571fd0SChris Mason * 13205c680ed6SChris Mason * slot and level indicate where you want the key to go, and 13215c680ed6SChris Mason * blocknr is the block the key points to. 1322aa5d6bedSChris Mason * 1323aa5d6bedSChris Mason * returns zero on success and < 0 on any error 13245c680ed6SChris Mason */ 1325e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 1326e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 1327db94535dSChris Mason *key, u64 bytenr, int slot, int level) 13285c680ed6SChris Mason { 13295f39d397SChris Mason struct extent_buffer *lower; 13305c680ed6SChris Mason int nritems; 13315c680ed6SChris Mason 13325c680ed6SChris Mason BUG_ON(!path->nodes[level]); 13335f39d397SChris Mason lower = path->nodes[level]; 13345f39d397SChris Mason nritems = btrfs_header_nritems(lower); 133574123bd7SChris Mason if (slot > nritems) 133674123bd7SChris Mason BUG(); 1337123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 133874123bd7SChris Mason BUG(); 133974123bd7SChris Mason if (slot != nritems) { 13405f39d397SChris Mason memmove_extent_buffer(lower, 13415f39d397SChris Mason btrfs_node_key_ptr_offset(slot + 1), 13425f39d397SChris Mason btrfs_node_key_ptr_offset(slot), 1343123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 134474123bd7SChris Mason } 13455f39d397SChris Mason btrfs_set_node_key(lower, key, slot); 1346db94535dSChris Mason btrfs_set_node_blockptr(lower, slot, bytenr); 134774493f7aSChris Mason WARN_ON(trans->transid == 0); 134874493f7aSChris Mason btrfs_set_node_ptr_generation(lower, slot, trans->transid); 13495f39d397SChris Mason btrfs_set_header_nritems(lower, nritems + 1); 13505f39d397SChris Mason btrfs_mark_buffer_dirty(lower); 135174123bd7SChris Mason return 0; 135274123bd7SChris Mason } 135374123bd7SChris Mason 135497571fd0SChris Mason /* 135597571fd0SChris Mason * split the node at the specified level in path in two. 135697571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 135797571fd0SChris Mason * 135897571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 135997571fd0SChris Mason * left and right, if either one works, it returns right away. 1360aa5d6bedSChris Mason * 1361aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 136297571fd0SChris Mason */ 1363e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 1364e089f05cSChris Mason *root, struct btrfs_path *path, int level) 1365be0e5c09SChris Mason { 1366*7bb86316SChris Mason u64 root_gen; 13675f39d397SChris Mason struct extent_buffer *c; 13685f39d397SChris Mason struct extent_buffer *split; 13695f39d397SChris Mason struct btrfs_disk_key disk_key; 1370be0e5c09SChris Mason int mid; 13715c680ed6SChris Mason int ret; 1372aa5d6bedSChris Mason int wret; 13737518a238SChris Mason u32 c_nritems; 1374be0e5c09SChris Mason 13755f39d397SChris Mason c = path->nodes[level]; 1376*7bb86316SChris Mason WARN_ON(btrfs_header_generation(c) != trans->transid); 13775f39d397SChris Mason if (c == root->node) { 13785c680ed6SChris Mason /* trying to split the root, lets make a new one */ 1379e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 13805c680ed6SChris Mason if (ret) 13815c680ed6SChris Mason return ret; 1382e66f709bSChris Mason } else { 1383e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 13845f39d397SChris Mason c = path->nodes[level]; 13855f39d397SChris Mason if (!ret && btrfs_header_nritems(c) < 1386e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 1387e66f709bSChris Mason return 0; 138854aa1f4dSChris Mason if (ret < 0) 138954aa1f4dSChris Mason return ret; 13905c680ed6SChris Mason } 1391e66f709bSChris Mason 13925f39d397SChris Mason c_nritems = btrfs_header_nritems(c); 1393*7bb86316SChris Mason if (root->ref_cows) 1394*7bb86316SChris Mason root_gen = trans->transid; 1395*7bb86316SChris Mason else 1396*7bb86316SChris Mason root_gen = 0; 1397*7bb86316SChris Mason 1398*7bb86316SChris Mason btrfs_node_key(c, &disk_key, 0); 1399*7bb86316SChris Mason split = __btrfs_alloc_free_block(trans, root, root->nodesize, 1400*7bb86316SChris Mason root->root_key.objectid, 1401*7bb86316SChris Mason root_gen, 1402*7bb86316SChris Mason btrfs_disk_key_objectid(&disk_key), 1403*7bb86316SChris Mason level, c->start, 0); 14045f39d397SChris Mason if (IS_ERR(split)) 14055f39d397SChris Mason return PTR_ERR(split); 140654aa1f4dSChris Mason 14075f39d397SChris Mason btrfs_set_header_flags(split, btrfs_header_flags(c)); 14085f39d397SChris Mason btrfs_set_header_level(split, btrfs_header_level(c)); 1409db94535dSChris Mason btrfs_set_header_bytenr(split, split->start); 14105f39d397SChris Mason btrfs_set_header_generation(split, trans->transid); 14115f39d397SChris Mason btrfs_set_header_owner(split, root->root_key.objectid); 14125f39d397SChris Mason write_extent_buffer(split, root->fs_info->fsid, 14135f39d397SChris Mason (unsigned long)btrfs_header_fsid(split), 14145f39d397SChris Mason BTRFS_FSID_SIZE); 14155f39d397SChris Mason 14167518a238SChris Mason mid = (c_nritems + 1) / 2; 14175f39d397SChris Mason 14185f39d397SChris Mason copy_extent_buffer(split, c, 14195f39d397SChris Mason btrfs_node_key_ptr_offset(0), 14205f39d397SChris Mason btrfs_node_key_ptr_offset(mid), 1421123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 14225f39d397SChris Mason btrfs_set_header_nritems(split, c_nritems - mid); 14235f39d397SChris Mason btrfs_set_header_nritems(c, mid); 1424aa5d6bedSChris Mason ret = 0; 1425aa5d6bedSChris Mason 14265f39d397SChris Mason btrfs_mark_buffer_dirty(c); 14275f39d397SChris Mason btrfs_mark_buffer_dirty(split); 14285f39d397SChris Mason 14295f39d397SChris Mason btrfs_node_key(split, &disk_key, 0); 1430db94535dSChris Mason wret = insert_ptr(trans, root, path, &disk_key, split->start, 14315f39d397SChris Mason path->slots[level + 1] + 1, 1432123abc88SChris Mason level + 1); 1433aa5d6bedSChris Mason if (wret) 1434aa5d6bedSChris Mason ret = wret; 1435aa5d6bedSChris Mason 14365de08d7dSChris Mason if (path->slots[level] >= mid) { 14375c680ed6SChris Mason path->slots[level] -= mid; 14385f39d397SChris Mason free_extent_buffer(c); 14395f39d397SChris Mason path->nodes[level] = split; 14405c680ed6SChris Mason path->slots[level + 1] += 1; 1441eb60ceacSChris Mason } else { 14425f39d397SChris Mason free_extent_buffer(split); 1443be0e5c09SChris Mason } 1444aa5d6bedSChris Mason return ret; 1445be0e5c09SChris Mason } 1446be0e5c09SChris Mason 144774123bd7SChris Mason /* 144874123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 144974123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 145074123bd7SChris Mason * space used both by the item structs and the item data 145174123bd7SChris Mason */ 14525f39d397SChris Mason static int leaf_space_used(struct extent_buffer *l, int start, int nr) 1453be0e5c09SChris Mason { 1454be0e5c09SChris Mason int data_len; 14555f39d397SChris Mason int nritems = btrfs_header_nritems(l); 1456d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 1457be0e5c09SChris Mason 1458be0e5c09SChris Mason if (!nr) 1459be0e5c09SChris Mason return 0; 14605f39d397SChris Mason data_len = btrfs_item_end_nr(l, start); 14615f39d397SChris Mason data_len = data_len - btrfs_item_offset_nr(l, end); 14620783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 1463d4dbff95SChris Mason WARN_ON(data_len < 0); 1464be0e5c09SChris Mason return data_len; 1465be0e5c09SChris Mason } 1466be0e5c09SChris Mason 146774123bd7SChris Mason /* 1468d4dbff95SChris Mason * The space between the end of the leaf items and 1469d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 1470d4dbff95SChris Mason * the leaf has left for both items and data 1471d4dbff95SChris Mason */ 14725f39d397SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf) 1473d4dbff95SChris Mason { 14745f39d397SChris Mason int nritems = btrfs_header_nritems(leaf); 14755f39d397SChris Mason int ret; 14765f39d397SChris Mason ret = BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 14775f39d397SChris Mason if (ret < 0) { 14785f39d397SChris Mason printk("leaf free space ret %d, leaf data size %lu, used %d nritems %d\n", 1479ae2f5411SJens Axboe ret, (unsigned long) BTRFS_LEAF_DATA_SIZE(root), 14805f39d397SChris Mason leaf_space_used(leaf, 0, nritems), nritems); 14815f39d397SChris Mason } 14825f39d397SChris Mason return ret; 1483d4dbff95SChris Mason } 1484d4dbff95SChris Mason 1485d4dbff95SChris Mason /* 148600ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 148700ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 1488aa5d6bedSChris Mason * 1489aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 1490aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 149100ec4c51SChris Mason */ 1492e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 149334a38218SChris Mason *root, struct btrfs_path *path, int data_size, 149434a38218SChris Mason int empty) 149500ec4c51SChris Mason { 14965f39d397SChris Mason struct extent_buffer *left = path->nodes[0]; 14975f39d397SChris Mason struct extent_buffer *right; 14985f39d397SChris Mason struct extent_buffer *upper; 14995f39d397SChris Mason struct btrfs_disk_key disk_key; 150000ec4c51SChris Mason int slot; 150134a38218SChris Mason u32 i; 150200ec4c51SChris Mason int free_space; 150300ec4c51SChris Mason int push_space = 0; 150400ec4c51SChris Mason int push_items = 0; 15050783fcfcSChris Mason struct btrfs_item *item; 15067518a238SChris Mason u32 left_nritems; 150734a38218SChris Mason u32 nr; 15087518a238SChris Mason u32 right_nritems; 15095f39d397SChris Mason u32 data_end; 1510db94535dSChris Mason u32 this_item_size; 151154aa1f4dSChris Mason int ret; 151200ec4c51SChris Mason 151300ec4c51SChris Mason slot = path->slots[1]; 151400ec4c51SChris Mason if (!path->nodes[1]) { 151500ec4c51SChris Mason return 1; 151600ec4c51SChris Mason } 151700ec4c51SChris Mason upper = path->nodes[1]; 15185f39d397SChris Mason if (slot >= btrfs_header_nritems(upper) - 1) 151900ec4c51SChris Mason return 1; 15205f39d397SChris Mason 1521db94535dSChris Mason right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1), 1522db94535dSChris Mason root->leafsize); 1523123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 15240783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 15255f39d397SChris Mason free_extent_buffer(right); 152602217ed2SChris Mason return 1; 152702217ed2SChris Mason } 152802217ed2SChris Mason 15295f39d397SChris Mason /* cow and double check */ 15305f39d397SChris Mason ret = btrfs_cow_block(trans, root, right, upper, 15315f39d397SChris Mason slot + 1, &right); 15325f39d397SChris Mason if (ret) { 15335f39d397SChris Mason free_extent_buffer(right); 1534a429e513SChris Mason return 1; 1535a429e513SChris Mason } 15365f39d397SChris Mason free_space = btrfs_leaf_free_space(root, right); 15375f39d397SChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 15385f39d397SChris Mason free_extent_buffer(right); 15395f39d397SChris Mason return 1; 15405f39d397SChris Mason } 15415f39d397SChris Mason 15425f39d397SChris Mason left_nritems = btrfs_header_nritems(left); 15435f39d397SChris Mason if (left_nritems == 0) { 15445f39d397SChris Mason free_extent_buffer(right); 15455f39d397SChris Mason return 1; 15465f39d397SChris Mason } 15475f39d397SChris Mason 154834a38218SChris Mason if (empty) 154934a38218SChris Mason nr = 0; 155034a38218SChris Mason else 155134a38218SChris Mason nr = 1; 155234a38218SChris Mason 155334a38218SChris Mason i = left_nritems - 1; 155434a38218SChris Mason while (i >= nr) { 15555f39d397SChris Mason item = btrfs_item_nr(left, i); 1556db94535dSChris Mason 155700ec4c51SChris Mason if (path->slots[0] == i) 155800ec4c51SChris Mason push_space += data_size + sizeof(*item); 1559db94535dSChris Mason 1560db94535dSChris Mason if (!left->map_token) { 1561db94535dSChris Mason map_extent_buffer(left, (unsigned long)item, 1562db94535dSChris Mason sizeof(struct btrfs_item), 1563db94535dSChris Mason &left->map_token, &left->kaddr, 1564db94535dSChris Mason &left->map_start, &left->map_len, 1565db94535dSChris Mason KM_USER1); 1566db94535dSChris Mason } 1567db94535dSChris Mason 1568db94535dSChris Mason this_item_size = btrfs_item_size(left, item); 1569db94535dSChris Mason if (this_item_size + sizeof(*item) + push_space > free_space) 157000ec4c51SChris Mason break; 157100ec4c51SChris Mason push_items++; 1572db94535dSChris Mason push_space += this_item_size + sizeof(*item); 157334a38218SChris Mason if (i == 0) 157434a38218SChris Mason break; 157534a38218SChris Mason i--; 1576db94535dSChris Mason } 1577db94535dSChris Mason if (left->map_token) { 1578db94535dSChris Mason unmap_extent_buffer(left, left->map_token, KM_USER1); 1579db94535dSChris Mason left->map_token = NULL; 158000ec4c51SChris Mason } 15815f39d397SChris Mason 158200ec4c51SChris Mason if (push_items == 0) { 15835f39d397SChris Mason free_extent_buffer(right); 158400ec4c51SChris Mason return 1; 158500ec4c51SChris Mason } 15865f39d397SChris Mason 158734a38218SChris Mason if (!empty && push_items == left_nritems) 1588a429e513SChris Mason WARN_ON(1); 15895f39d397SChris Mason 159000ec4c51SChris Mason /* push left to right */ 15915f39d397SChris Mason right_nritems = btrfs_header_nritems(right); 159234a38218SChris Mason 15935f39d397SChris Mason push_space = btrfs_item_end_nr(left, left_nritems - push_items); 1594123abc88SChris Mason push_space -= leaf_data_end(root, left); 15955f39d397SChris Mason 159600ec4c51SChris Mason /* make room in the right data area */ 15975f39d397SChris Mason data_end = leaf_data_end(root, right); 15985f39d397SChris Mason memmove_extent_buffer(right, 15995f39d397SChris Mason btrfs_leaf_data(right) + data_end - push_space, 16005f39d397SChris Mason btrfs_leaf_data(right) + data_end, 16015f39d397SChris Mason BTRFS_LEAF_DATA_SIZE(root) - data_end); 16025f39d397SChris Mason 160300ec4c51SChris Mason /* copy from the left data area */ 16045f39d397SChris Mason copy_extent_buffer(right, left, btrfs_leaf_data(right) + 1605d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1606d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1607d6025579SChris Mason push_space); 16085f39d397SChris Mason 16095f39d397SChris Mason memmove_extent_buffer(right, btrfs_item_nr_offset(push_items), 16105f39d397SChris Mason btrfs_item_nr_offset(0), 16110783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 16125f39d397SChris Mason 161300ec4c51SChris Mason /* copy the items from left to right */ 16145f39d397SChris Mason copy_extent_buffer(right, left, btrfs_item_nr_offset(0), 16155f39d397SChris Mason btrfs_item_nr_offset(left_nritems - push_items), 16160783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 161700ec4c51SChris Mason 161800ec4c51SChris Mason /* update the item pointers */ 16197518a238SChris Mason right_nritems += push_items; 16205f39d397SChris Mason btrfs_set_header_nritems(right, right_nritems); 1621123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 16227518a238SChris Mason for (i = 0; i < right_nritems; i++) { 16235f39d397SChris Mason item = btrfs_item_nr(right, i); 1624db94535dSChris Mason if (!right->map_token) { 1625db94535dSChris Mason map_extent_buffer(right, (unsigned long)item, 1626db94535dSChris Mason sizeof(struct btrfs_item), 1627db94535dSChris Mason &right->map_token, &right->kaddr, 1628db94535dSChris Mason &right->map_start, &right->map_len, 1629db94535dSChris Mason KM_USER1); 1630db94535dSChris Mason } 1631db94535dSChris Mason push_space -= btrfs_item_size(right, item); 1632db94535dSChris Mason btrfs_set_item_offset(right, item, push_space); 1633db94535dSChris Mason } 1634db94535dSChris Mason 1635db94535dSChris Mason if (right->map_token) { 1636db94535dSChris Mason unmap_extent_buffer(right, right->map_token, KM_USER1); 1637db94535dSChris Mason right->map_token = NULL; 163800ec4c51SChris Mason } 16397518a238SChris Mason left_nritems -= push_items; 16405f39d397SChris Mason btrfs_set_header_nritems(left, left_nritems); 164100ec4c51SChris Mason 164234a38218SChris Mason if (left_nritems) 16435f39d397SChris Mason btrfs_mark_buffer_dirty(left); 16445f39d397SChris Mason btrfs_mark_buffer_dirty(right); 1645a429e513SChris Mason 16465f39d397SChris Mason btrfs_item_key(right, &disk_key, 0); 16475f39d397SChris Mason btrfs_set_node_key(upper, &disk_key, slot + 1); 1648d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 164902217ed2SChris Mason 165000ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 16517518a238SChris Mason if (path->slots[0] >= left_nritems) { 16527518a238SChris Mason path->slots[0] -= left_nritems; 16535f39d397SChris Mason free_extent_buffer(path->nodes[0]); 16545f39d397SChris Mason path->nodes[0] = right; 165500ec4c51SChris Mason path->slots[1] += 1; 165600ec4c51SChris Mason } else { 16575f39d397SChris Mason free_extent_buffer(right); 165800ec4c51SChris Mason } 165900ec4c51SChris Mason return 0; 166000ec4c51SChris Mason } 166100ec4c51SChris Mason /* 166274123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 166374123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 166474123bd7SChris Mason */ 1665e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 166634a38218SChris Mason *root, struct btrfs_path *path, int data_size, 166734a38218SChris Mason int empty) 1668be0e5c09SChris Mason { 16695f39d397SChris Mason struct btrfs_disk_key disk_key; 16705f39d397SChris Mason struct extent_buffer *right = path->nodes[0]; 16715f39d397SChris Mason struct extent_buffer *left; 1672be0e5c09SChris Mason int slot; 1673be0e5c09SChris Mason int i; 1674be0e5c09SChris Mason int free_space; 1675be0e5c09SChris Mason int push_space = 0; 1676be0e5c09SChris Mason int push_items = 0; 16770783fcfcSChris Mason struct btrfs_item *item; 16787518a238SChris Mason u32 old_left_nritems; 16795f39d397SChris Mason u32 right_nritems; 168034a38218SChris Mason u32 nr; 1681aa5d6bedSChris Mason int ret = 0; 1682aa5d6bedSChris Mason int wret; 1683db94535dSChris Mason u32 this_item_size; 1684db94535dSChris Mason u32 old_left_item_size; 1685be0e5c09SChris Mason 1686be0e5c09SChris Mason slot = path->slots[1]; 16875f39d397SChris Mason if (slot == 0) 1688be0e5c09SChris Mason return 1; 16895f39d397SChris Mason if (!path->nodes[1]) 1690be0e5c09SChris Mason return 1; 16915f39d397SChris Mason 16923685f791SChris Mason right_nritems = btrfs_header_nritems(right); 16933685f791SChris Mason if (right_nritems == 0) { 16943685f791SChris Mason return 1; 16953685f791SChris Mason } 16963685f791SChris Mason 16975f39d397SChris Mason left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1], 1698db94535dSChris Mason slot - 1), root->leafsize); 1699123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 17000783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 17015f39d397SChris Mason free_extent_buffer(left); 1702be0e5c09SChris Mason return 1; 1703be0e5c09SChris Mason } 170402217ed2SChris Mason 170502217ed2SChris Mason /* cow and double check */ 17065f39d397SChris Mason ret = btrfs_cow_block(trans, root, left, 17075f39d397SChris Mason path->nodes[1], slot - 1, &left); 170854aa1f4dSChris Mason if (ret) { 170954aa1f4dSChris Mason /* we hit -ENOSPC, but it isn't fatal here */ 17105f39d397SChris Mason free_extent_buffer(left); 171154aa1f4dSChris Mason return 1; 171254aa1f4dSChris Mason } 17133685f791SChris Mason 1714123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 17150783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 17165f39d397SChris Mason free_extent_buffer(left); 171702217ed2SChris Mason return 1; 171802217ed2SChris Mason } 171902217ed2SChris Mason 172034a38218SChris Mason if (empty) 172134a38218SChris Mason nr = right_nritems; 172234a38218SChris Mason else 172334a38218SChris Mason nr = right_nritems - 1; 172434a38218SChris Mason 172534a38218SChris Mason for (i = 0; i < nr; i++) { 17265f39d397SChris Mason item = btrfs_item_nr(right, i); 1727db94535dSChris Mason if (!right->map_token) { 1728db94535dSChris Mason map_extent_buffer(right, (unsigned long)item, 1729db94535dSChris Mason sizeof(struct btrfs_item), 1730db94535dSChris Mason &right->map_token, &right->kaddr, 1731db94535dSChris Mason &right->map_start, &right->map_len, 1732db94535dSChris Mason KM_USER1); 1733db94535dSChris Mason } 1734db94535dSChris Mason 1735be0e5c09SChris Mason if (path->slots[0] == i) 1736be0e5c09SChris Mason push_space += data_size + sizeof(*item); 1737db94535dSChris Mason 1738db94535dSChris Mason this_item_size = btrfs_item_size(right, item); 1739db94535dSChris Mason if (this_item_size + sizeof(*item) + push_space > free_space) 1740be0e5c09SChris Mason break; 1741db94535dSChris Mason 1742be0e5c09SChris Mason push_items++; 1743db94535dSChris Mason push_space += this_item_size + sizeof(*item); 1744be0e5c09SChris Mason } 1745db94535dSChris Mason 1746db94535dSChris Mason if (right->map_token) { 1747db94535dSChris Mason unmap_extent_buffer(right, right->map_token, KM_USER1); 1748db94535dSChris Mason right->map_token = NULL; 1749db94535dSChris Mason } 1750db94535dSChris Mason 1751be0e5c09SChris Mason if (push_items == 0) { 17525f39d397SChris Mason free_extent_buffer(left); 1753be0e5c09SChris Mason return 1; 1754be0e5c09SChris Mason } 175534a38218SChris Mason if (!empty && push_items == btrfs_header_nritems(right)) 1756a429e513SChris Mason WARN_ON(1); 17575f39d397SChris Mason 1758be0e5c09SChris Mason /* push data from right to left */ 17595f39d397SChris Mason copy_extent_buffer(left, right, 17605f39d397SChris Mason btrfs_item_nr_offset(btrfs_header_nritems(left)), 17615f39d397SChris Mason btrfs_item_nr_offset(0), 17625f39d397SChris Mason push_items * sizeof(struct btrfs_item)); 17635f39d397SChris Mason 1764123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 17655f39d397SChris Mason btrfs_item_offset_nr(right, push_items -1); 17665f39d397SChris Mason 17675f39d397SChris Mason copy_extent_buffer(left, right, btrfs_leaf_data(left) + 1768d6025579SChris Mason leaf_data_end(root, left) - push_space, 1769123abc88SChris Mason btrfs_leaf_data(right) + 17705f39d397SChris Mason btrfs_item_offset_nr(right, push_items - 1), 1771be0e5c09SChris Mason push_space); 17725f39d397SChris Mason old_left_nritems = btrfs_header_nritems(left); 1773eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1774eb60ceacSChris Mason 1775db94535dSChris Mason old_left_item_size = btrfs_item_offset_nr(left, old_left_nritems - 1); 1776be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 17775f39d397SChris Mason u32 ioff; 1778db94535dSChris Mason 17795f39d397SChris Mason item = btrfs_item_nr(left, i); 1780db94535dSChris Mason if (!left->map_token) { 1781db94535dSChris Mason map_extent_buffer(left, (unsigned long)item, 1782db94535dSChris Mason sizeof(struct btrfs_item), 1783db94535dSChris Mason &left->map_token, &left->kaddr, 1784db94535dSChris Mason &left->map_start, &left->map_len, 1785db94535dSChris Mason KM_USER1); 1786db94535dSChris Mason } 1787db94535dSChris Mason 17885f39d397SChris Mason ioff = btrfs_item_offset(left, item); 17895f39d397SChris Mason btrfs_set_item_offset(left, item, 1790db94535dSChris Mason ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size)); 1791be0e5c09SChris Mason } 17925f39d397SChris Mason btrfs_set_header_nritems(left, old_left_nritems + push_items); 1793db94535dSChris Mason if (left->map_token) { 1794db94535dSChris Mason unmap_extent_buffer(left, left->map_token, KM_USER1); 1795db94535dSChris Mason left->map_token = NULL; 1796db94535dSChris Mason } 1797be0e5c09SChris Mason 1798be0e5c09SChris Mason /* fixup right node */ 179934a38218SChris Mason if (push_items > right_nritems) { 180034a38218SChris Mason printk("push items %d nr %u\n", push_items, right_nritems); 180134a38218SChris Mason WARN_ON(1); 180234a38218SChris Mason } 180334a38218SChris Mason 180434a38218SChris Mason if (push_items < right_nritems) { 18055f39d397SChris Mason push_space = btrfs_item_offset_nr(right, push_items - 1) - 1806123abc88SChris Mason leaf_data_end(root, right); 18075f39d397SChris Mason memmove_extent_buffer(right, btrfs_leaf_data(right) + 1808d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1809d6025579SChris Mason btrfs_leaf_data(right) + 1810123abc88SChris Mason leaf_data_end(root, right), push_space); 18115f39d397SChris Mason 18125f39d397SChris Mason memmove_extent_buffer(right, btrfs_item_nr_offset(0), 18135f39d397SChris Mason btrfs_item_nr_offset(push_items), 18145f39d397SChris Mason (btrfs_header_nritems(right) - push_items) * 18150783fcfcSChris Mason sizeof(struct btrfs_item)); 181634a38218SChris Mason } 1817eef1c494SYan right_nritems -= push_items; 1818eef1c494SYan btrfs_set_header_nritems(right, right_nritems); 1819123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 18205f39d397SChris Mason for (i = 0; i < right_nritems; i++) { 18215f39d397SChris Mason item = btrfs_item_nr(right, i); 1822db94535dSChris Mason 1823db94535dSChris Mason if (!right->map_token) { 1824db94535dSChris Mason map_extent_buffer(right, (unsigned long)item, 1825db94535dSChris Mason sizeof(struct btrfs_item), 1826db94535dSChris Mason &right->map_token, &right->kaddr, 1827db94535dSChris Mason &right->map_start, &right->map_len, 1828db94535dSChris Mason KM_USER1); 1829db94535dSChris Mason } 1830db94535dSChris Mason 1831db94535dSChris Mason push_space = push_space - btrfs_item_size(right, item); 1832db94535dSChris Mason btrfs_set_item_offset(right, item, push_space); 1833db94535dSChris Mason } 1834db94535dSChris Mason if (right->map_token) { 1835db94535dSChris Mason unmap_extent_buffer(right, right->map_token, KM_USER1); 1836db94535dSChris Mason right->map_token = NULL; 1837be0e5c09SChris Mason } 1838eb60ceacSChris Mason 18395f39d397SChris Mason btrfs_mark_buffer_dirty(left); 184034a38218SChris Mason if (right_nritems) 18415f39d397SChris Mason btrfs_mark_buffer_dirty(right); 1842098f59c2SChris Mason 18435f39d397SChris Mason btrfs_item_key(right, &disk_key, 0); 18445f39d397SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1845aa5d6bedSChris Mason if (wret) 1846aa5d6bedSChris Mason ret = wret; 1847be0e5c09SChris Mason 1848be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1849be0e5c09SChris Mason if (path->slots[0] < push_items) { 1850be0e5c09SChris Mason path->slots[0] += old_left_nritems; 18515f39d397SChris Mason free_extent_buffer(path->nodes[0]); 18525f39d397SChris Mason path->nodes[0] = left; 1853be0e5c09SChris Mason path->slots[1] -= 1; 1854be0e5c09SChris Mason } else { 18555f39d397SChris Mason free_extent_buffer(left); 1856be0e5c09SChris Mason path->slots[0] -= push_items; 1857be0e5c09SChris Mason } 1858eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1859aa5d6bedSChris Mason return ret; 1860be0e5c09SChris Mason } 1861be0e5c09SChris Mason 186274123bd7SChris Mason /* 186374123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 186474123bd7SChris Mason * available for the resulting leaf level of the path. 1865aa5d6bedSChris Mason * 1866aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 186774123bd7SChris Mason */ 1868e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1869d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1870cc0c5538SChris Mason struct btrfs_path *path, int data_size, int extend) 1871be0e5c09SChris Mason { 1872*7bb86316SChris Mason u64 root_gen; 18735f39d397SChris Mason struct extent_buffer *l; 18747518a238SChris Mason u32 nritems; 1875eb60ceacSChris Mason int mid; 1876eb60ceacSChris Mason int slot; 18775f39d397SChris Mason struct extent_buffer *right; 18780783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1879be0e5c09SChris Mason int data_copy_size; 1880be0e5c09SChris Mason int rt_data_off; 1881be0e5c09SChris Mason int i; 1882d4dbff95SChris Mason int ret = 0; 1883aa5d6bedSChris Mason int wret; 1884cc0c5538SChris Mason int double_split; 1885cc0c5538SChris Mason int num_doubles = 0; 1886d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1887be0e5c09SChris Mason 1888cc0c5538SChris Mason if (extend) 1889cc0c5538SChris Mason space_needed = data_size; 1890cc0c5538SChris Mason 1891*7bb86316SChris Mason if (root->ref_cows) 1892*7bb86316SChris Mason root_gen = trans->transid; 1893*7bb86316SChris Mason else 1894*7bb86316SChris Mason root_gen = 0; 1895*7bb86316SChris Mason 189640689478SChris Mason /* first try to make some room by pushing left and right */ 18973685f791SChris Mason if (ins_key->type != BTRFS_DIR_ITEM_KEY) { 189834a38218SChris Mason wret = push_leaf_right(trans, root, path, data_size, 0); 18993326d1b0SChris Mason if (wret < 0) { 1900eaee50e8SChris Mason return wret; 19013326d1b0SChris Mason } 1902eaee50e8SChris Mason if (wret) { 190334a38218SChris Mason wret = push_leaf_left(trans, root, path, data_size, 0); 1904eaee50e8SChris Mason if (wret < 0) 1905eaee50e8SChris Mason return wret; 1906eaee50e8SChris Mason } 19075f39d397SChris Mason l = path->nodes[0]; 1908aa5d6bedSChris Mason 1909aa5d6bedSChris Mason /* did the pushes work? */ 1910cc0c5538SChris Mason if (btrfs_leaf_free_space(root, l) >= space_needed) 1911be0e5c09SChris Mason return 0; 19123326d1b0SChris Mason } 1913aa5d6bedSChris Mason 19145c680ed6SChris Mason if (!path->nodes[1]) { 1915e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 19165c680ed6SChris Mason if (ret) 19175c680ed6SChris Mason return ret; 19185c680ed6SChris Mason } 1919cc0c5538SChris Mason again: 1920cc0c5538SChris Mason double_split = 0; 1921cc0c5538SChris Mason l = path->nodes[0]; 1922eb60ceacSChris Mason slot = path->slots[0]; 19235f39d397SChris Mason nritems = btrfs_header_nritems(l); 1924eb60ceacSChris Mason mid = (nritems + 1)/ 2; 192554aa1f4dSChris Mason 1926*7bb86316SChris Mason btrfs_item_key(l, &disk_key, 0); 1927*7bb86316SChris Mason 1928*7bb86316SChris Mason right = __btrfs_alloc_free_block(trans, root, root->leafsize, 1929*7bb86316SChris Mason root->root_key.objectid, 1930*7bb86316SChris Mason root_gen, disk_key.objectid, 0, 1931db94535dSChris Mason l->start, 0); 19325f39d397SChris Mason if (IS_ERR(right)) 19335f39d397SChris Mason return PTR_ERR(right); 193454aa1f4dSChris Mason 19355f39d397SChris Mason memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); 1936db94535dSChris Mason btrfs_set_header_bytenr(right, right->start); 19375f39d397SChris Mason btrfs_set_header_generation(right, trans->transid); 19385f39d397SChris Mason btrfs_set_header_owner(right, root->root_key.objectid); 19395f39d397SChris Mason btrfs_set_header_level(right, 0); 19405f39d397SChris Mason write_extent_buffer(right, root->fs_info->fsid, 19415f39d397SChris Mason (unsigned long)btrfs_header_fsid(right), 19425f39d397SChris Mason BTRFS_FSID_SIZE); 1943d4dbff95SChris Mason if (mid <= slot) { 1944d4dbff95SChris Mason if (nritems == 1 || 1945d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1946d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1947d4dbff95SChris Mason if (slot >= nritems) { 1948d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 19495f39d397SChris Mason btrfs_set_header_nritems(right, 0); 1950d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1951db94535dSChris Mason &disk_key, right->start, 1952d4dbff95SChris Mason path->slots[1] + 1, 1); 1953d4dbff95SChris Mason if (wret) 1954d4dbff95SChris Mason ret = wret; 19555f39d397SChris Mason free_extent_buffer(path->nodes[0]); 19565f39d397SChris Mason path->nodes[0] = right; 1957d4dbff95SChris Mason path->slots[0] = 0; 1958d4dbff95SChris Mason path->slots[1] += 1; 1959d4dbff95SChris Mason return ret; 1960d4dbff95SChris Mason } 1961d4dbff95SChris Mason mid = slot; 19623326d1b0SChris Mason if (mid != nritems && 19633326d1b0SChris Mason leaf_space_used(l, mid, nritems - mid) + 19643326d1b0SChris Mason space_needed > BTRFS_LEAF_DATA_SIZE(root)) { 1965d4dbff95SChris Mason double_split = 1; 1966d4dbff95SChris Mason } 19673326d1b0SChris Mason } 1968d4dbff95SChris Mason } else { 1969d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1970d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1971cc0c5538SChris Mason if (!extend && slot == 0) { 1972d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 19735f39d397SChris Mason btrfs_set_header_nritems(right, 0); 1974d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1975d4dbff95SChris Mason &disk_key, 1976db94535dSChris Mason right->start, 1977098f59c2SChris Mason path->slots[1], 1); 1978d4dbff95SChris Mason if (wret) 1979d4dbff95SChris Mason ret = wret; 19805f39d397SChris Mason free_extent_buffer(path->nodes[0]); 19815f39d397SChris Mason path->nodes[0] = right; 1982d4dbff95SChris Mason path->slots[0] = 0; 1983a429e513SChris Mason if (path->slots[1] == 0) { 1984a429e513SChris Mason wret = fixup_low_keys(trans, root, 1985a429e513SChris Mason path, &disk_key, 1); 1986a429e513SChris Mason if (wret) 1987a429e513SChris Mason ret = wret; 1988a429e513SChris Mason } 1989d4dbff95SChris Mason return ret; 1990cc0c5538SChris Mason } else if (extend && slot == 0) { 1991cc0c5538SChris Mason mid = 1; 1992cc0c5538SChris Mason } else { 1993d4dbff95SChris Mason mid = slot; 19945ee78ac7SChris Mason if (mid != nritems && 19955ee78ac7SChris Mason leaf_space_used(l, mid, nritems - mid) + 19965ee78ac7SChris Mason space_needed > BTRFS_LEAF_DATA_SIZE(root)) { 1997d4dbff95SChris Mason double_split = 1; 1998d4dbff95SChris Mason } 1999d4dbff95SChris Mason } 20005ee78ac7SChris Mason } 2001cc0c5538SChris Mason } 20025f39d397SChris Mason nritems = nritems - mid; 20035f39d397SChris Mason btrfs_set_header_nritems(right, nritems); 20045f39d397SChris Mason data_copy_size = btrfs_item_end_nr(l, mid) - leaf_data_end(root, l); 20055f39d397SChris Mason 20065f39d397SChris Mason copy_extent_buffer(right, l, btrfs_item_nr_offset(0), 20075f39d397SChris Mason btrfs_item_nr_offset(mid), 20085f39d397SChris Mason nritems * sizeof(struct btrfs_item)); 20095f39d397SChris Mason 20105f39d397SChris Mason copy_extent_buffer(right, l, 2011d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 2012123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 2013123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 201474123bd7SChris Mason 20155f39d397SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 20165f39d397SChris Mason btrfs_item_end_nr(l, mid); 20175f39d397SChris Mason 20185f39d397SChris Mason for (i = 0; i < nritems; i++) { 20195f39d397SChris Mason struct btrfs_item *item = btrfs_item_nr(right, i); 2020db94535dSChris Mason u32 ioff; 2021db94535dSChris Mason 2022db94535dSChris Mason if (!right->map_token) { 2023db94535dSChris Mason map_extent_buffer(right, (unsigned long)item, 2024db94535dSChris Mason sizeof(struct btrfs_item), 2025db94535dSChris Mason &right->map_token, &right->kaddr, 2026db94535dSChris Mason &right->map_start, &right->map_len, 2027db94535dSChris Mason KM_USER1); 2028db94535dSChris Mason } 2029db94535dSChris Mason 2030db94535dSChris Mason ioff = btrfs_item_offset(right, item); 20315f39d397SChris Mason btrfs_set_item_offset(right, item, ioff + rt_data_off); 20320783fcfcSChris Mason } 203374123bd7SChris Mason 2034db94535dSChris Mason if (right->map_token) { 2035db94535dSChris Mason unmap_extent_buffer(right, right->map_token, KM_USER1); 2036db94535dSChris Mason right->map_token = NULL; 2037db94535dSChris Mason } 2038db94535dSChris Mason 20395f39d397SChris Mason btrfs_set_header_nritems(l, mid); 2040aa5d6bedSChris Mason ret = 0; 20415f39d397SChris Mason btrfs_item_key(right, &disk_key, 0); 2042db94535dSChris Mason wret = insert_ptr(trans, root, path, &disk_key, right->start, 2043db94535dSChris Mason path->slots[1] + 1, 1); 2044aa5d6bedSChris Mason if (wret) 2045aa5d6bedSChris Mason ret = wret; 20465f39d397SChris Mason 20475f39d397SChris Mason btrfs_mark_buffer_dirty(right); 20485f39d397SChris Mason btrfs_mark_buffer_dirty(l); 2049eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 20505f39d397SChris Mason 2051be0e5c09SChris Mason if (mid <= slot) { 20525f39d397SChris Mason free_extent_buffer(path->nodes[0]); 20535f39d397SChris Mason path->nodes[0] = right; 2054be0e5c09SChris Mason path->slots[0] -= mid; 2055be0e5c09SChris Mason path->slots[1] += 1; 2056eb60ceacSChris Mason } else 20575f39d397SChris Mason free_extent_buffer(right); 20585f39d397SChris Mason 2059eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 2060d4dbff95SChris Mason 2061cc0c5538SChris Mason if (double_split) { 2062cc0c5538SChris Mason BUG_ON(num_doubles != 0); 2063cc0c5538SChris Mason num_doubles++; 2064cc0c5538SChris Mason goto again; 20653326d1b0SChris Mason } 2066be0e5c09SChris Mason return ret; 2067be0e5c09SChris Mason } 2068be0e5c09SChris Mason 2069b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 2070b18c6685SChris Mason struct btrfs_root *root, 2071b18c6685SChris Mason struct btrfs_path *path, 2072179e29e4SChris Mason u32 new_size, int from_end) 2073b18c6685SChris Mason { 2074b18c6685SChris Mason int ret = 0; 2075b18c6685SChris Mason int slot; 2076b18c6685SChris Mason int slot_orig; 20775f39d397SChris Mason struct extent_buffer *leaf; 20785f39d397SChris Mason struct btrfs_item *item; 2079b18c6685SChris Mason u32 nritems; 2080b18c6685SChris Mason unsigned int data_end; 2081b18c6685SChris Mason unsigned int old_data_start; 2082b18c6685SChris Mason unsigned int old_size; 2083b18c6685SChris Mason unsigned int size_diff; 2084b18c6685SChris Mason int i; 2085b18c6685SChris Mason 2086b18c6685SChris Mason slot_orig = path->slots[0]; 20875f39d397SChris Mason leaf = path->nodes[0]; 2088179e29e4SChris Mason slot = path->slots[0]; 2089179e29e4SChris Mason 2090179e29e4SChris Mason old_size = btrfs_item_size_nr(leaf, slot); 2091179e29e4SChris Mason if (old_size == new_size) 2092179e29e4SChris Mason return 0; 2093b18c6685SChris Mason 20945f39d397SChris Mason nritems = btrfs_header_nritems(leaf); 2095b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 2096b18c6685SChris Mason 20975f39d397SChris Mason old_data_start = btrfs_item_offset_nr(leaf, slot); 2098179e29e4SChris Mason 2099b18c6685SChris Mason size_diff = old_size - new_size; 2100b18c6685SChris Mason 2101b18c6685SChris Mason BUG_ON(slot < 0); 2102b18c6685SChris Mason BUG_ON(slot >= nritems); 2103b18c6685SChris Mason 2104b18c6685SChris Mason /* 2105b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 2106b18c6685SChris Mason */ 2107b18c6685SChris Mason /* first correct the data pointers */ 2108b18c6685SChris Mason for (i = slot; i < nritems; i++) { 21095f39d397SChris Mason u32 ioff; 21105f39d397SChris Mason item = btrfs_item_nr(leaf, i); 2111db94535dSChris Mason 2112db94535dSChris Mason if (!leaf->map_token) { 2113db94535dSChris Mason map_extent_buffer(leaf, (unsigned long)item, 2114db94535dSChris Mason sizeof(struct btrfs_item), 2115db94535dSChris Mason &leaf->map_token, &leaf->kaddr, 2116db94535dSChris Mason &leaf->map_start, &leaf->map_len, 2117db94535dSChris Mason KM_USER1); 2118db94535dSChris Mason } 2119db94535dSChris Mason 21205f39d397SChris Mason ioff = btrfs_item_offset(leaf, item); 21215f39d397SChris Mason btrfs_set_item_offset(leaf, item, ioff + size_diff); 2122b18c6685SChris Mason } 2123db94535dSChris Mason 2124db94535dSChris Mason if (leaf->map_token) { 2125db94535dSChris Mason unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); 2126db94535dSChris Mason leaf->map_token = NULL; 2127db94535dSChris Mason } 2128db94535dSChris Mason 2129b18c6685SChris Mason /* shift the data */ 2130179e29e4SChris Mason if (from_end) { 21315f39d397SChris Mason memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + 2132b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 2133b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 2134179e29e4SChris Mason } else { 2135179e29e4SChris Mason struct btrfs_disk_key disk_key; 2136179e29e4SChris Mason u64 offset; 2137179e29e4SChris Mason 2138179e29e4SChris Mason btrfs_item_key(leaf, &disk_key, slot); 2139179e29e4SChris Mason 2140179e29e4SChris Mason if (btrfs_disk_key_type(&disk_key) == BTRFS_EXTENT_DATA_KEY) { 2141179e29e4SChris Mason unsigned long ptr; 2142179e29e4SChris Mason struct btrfs_file_extent_item *fi; 2143179e29e4SChris Mason 2144179e29e4SChris Mason fi = btrfs_item_ptr(leaf, slot, 2145179e29e4SChris Mason struct btrfs_file_extent_item); 2146179e29e4SChris Mason fi = (struct btrfs_file_extent_item *)( 2147179e29e4SChris Mason (unsigned long)fi - size_diff); 2148179e29e4SChris Mason 2149179e29e4SChris Mason if (btrfs_file_extent_type(leaf, fi) == 2150179e29e4SChris Mason BTRFS_FILE_EXTENT_INLINE) { 2151179e29e4SChris Mason ptr = btrfs_item_ptr_offset(leaf, slot); 2152179e29e4SChris Mason memmove_extent_buffer(leaf, ptr, 2153179e29e4SChris Mason (unsigned long)fi, 2154179e29e4SChris Mason offsetof(struct btrfs_file_extent_item, 2155179e29e4SChris Mason disk_bytenr)); 2156179e29e4SChris Mason } 2157179e29e4SChris Mason } 2158179e29e4SChris Mason 2159179e29e4SChris Mason memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + 2160179e29e4SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 2161179e29e4SChris Mason data_end, old_data_start - data_end); 2162179e29e4SChris Mason 2163179e29e4SChris Mason offset = btrfs_disk_key_offset(&disk_key); 2164179e29e4SChris Mason btrfs_set_disk_key_offset(&disk_key, offset + size_diff); 2165179e29e4SChris Mason btrfs_set_item_key(leaf, &disk_key, slot); 2166179e29e4SChris Mason if (slot == 0) 2167179e29e4SChris Mason fixup_low_keys(trans, root, path, &disk_key, 1); 2168179e29e4SChris Mason } 21695f39d397SChris Mason 21705f39d397SChris Mason item = btrfs_item_nr(leaf, slot); 21715f39d397SChris Mason btrfs_set_item_size(leaf, item, new_size); 21725f39d397SChris Mason btrfs_mark_buffer_dirty(leaf); 2173b18c6685SChris Mason 2174b18c6685SChris Mason ret = 0; 21755f39d397SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) { 21765f39d397SChris Mason btrfs_print_leaf(root, leaf); 2177b18c6685SChris Mason BUG(); 21785f39d397SChris Mason } 2179b18c6685SChris Mason return ret; 2180b18c6685SChris Mason } 2181b18c6685SChris Mason 21825f39d397SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, 21835f39d397SChris Mason struct btrfs_root *root, struct btrfs_path *path, 21845f39d397SChris Mason u32 data_size) 21856567e837SChris Mason { 21866567e837SChris Mason int ret = 0; 21876567e837SChris Mason int slot; 21886567e837SChris Mason int slot_orig; 21895f39d397SChris Mason struct extent_buffer *leaf; 21905f39d397SChris Mason struct btrfs_item *item; 21916567e837SChris Mason u32 nritems; 21926567e837SChris Mason unsigned int data_end; 21936567e837SChris Mason unsigned int old_data; 21946567e837SChris Mason unsigned int old_size; 21956567e837SChris Mason int i; 21966567e837SChris Mason 21976567e837SChris Mason slot_orig = path->slots[0]; 21985f39d397SChris Mason leaf = path->nodes[0]; 21996567e837SChris Mason 22005f39d397SChris Mason nritems = btrfs_header_nritems(leaf); 22016567e837SChris Mason data_end = leaf_data_end(root, leaf); 22026567e837SChris Mason 22035f39d397SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) { 22045f39d397SChris Mason btrfs_print_leaf(root, leaf); 22056567e837SChris Mason BUG(); 22065f39d397SChris Mason } 22076567e837SChris Mason slot = path->slots[0]; 22085f39d397SChris Mason old_data = btrfs_item_end_nr(leaf, slot); 22096567e837SChris Mason 22106567e837SChris Mason BUG_ON(slot < 0); 22113326d1b0SChris Mason if (slot >= nritems) { 22123326d1b0SChris Mason btrfs_print_leaf(root, leaf); 22133326d1b0SChris Mason printk("slot %d too large, nritems %d\n", slot, nritems); 22143326d1b0SChris Mason BUG_ON(1); 22153326d1b0SChris Mason } 22166567e837SChris Mason 22176567e837SChris Mason /* 22186567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 22196567e837SChris Mason */ 22206567e837SChris Mason /* first correct the data pointers */ 22216567e837SChris Mason for (i = slot; i < nritems; i++) { 22225f39d397SChris Mason u32 ioff; 22235f39d397SChris Mason item = btrfs_item_nr(leaf, i); 2224db94535dSChris Mason 2225db94535dSChris Mason if (!leaf->map_token) { 2226db94535dSChris Mason map_extent_buffer(leaf, (unsigned long)item, 2227db94535dSChris Mason sizeof(struct btrfs_item), 2228db94535dSChris Mason &leaf->map_token, &leaf->kaddr, 2229db94535dSChris Mason &leaf->map_start, &leaf->map_len, 2230db94535dSChris Mason KM_USER1); 2231db94535dSChris Mason } 22325f39d397SChris Mason ioff = btrfs_item_offset(leaf, item); 22335f39d397SChris Mason btrfs_set_item_offset(leaf, item, ioff - data_size); 22346567e837SChris Mason } 22355f39d397SChris Mason 2236db94535dSChris Mason if (leaf->map_token) { 2237db94535dSChris Mason unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); 2238db94535dSChris Mason leaf->map_token = NULL; 2239db94535dSChris Mason } 2240db94535dSChris Mason 22416567e837SChris Mason /* shift the data */ 22425f39d397SChris Mason memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + 22436567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 22446567e837SChris Mason data_end, old_data - data_end); 22455f39d397SChris Mason 22466567e837SChris Mason data_end = old_data; 22475f39d397SChris Mason old_size = btrfs_item_size_nr(leaf, slot); 22485f39d397SChris Mason item = btrfs_item_nr(leaf, slot); 22495f39d397SChris Mason btrfs_set_item_size(leaf, item, old_size + data_size); 22505f39d397SChris Mason btrfs_mark_buffer_dirty(leaf); 22516567e837SChris Mason 22526567e837SChris Mason ret = 0; 22535f39d397SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) { 22545f39d397SChris Mason btrfs_print_leaf(root, leaf); 22556567e837SChris Mason BUG(); 22565f39d397SChris Mason } 22576567e837SChris Mason return ret; 22586567e837SChris Mason } 22596567e837SChris Mason 226074123bd7SChris Mason /* 226174123bd7SChris Mason * Given a key and some data, insert an item into the tree. 226274123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 226374123bd7SChris Mason */ 22645f39d397SChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, 22655f39d397SChris Mason struct btrfs_root *root, 22665f39d397SChris Mason struct btrfs_path *path, 22675f39d397SChris Mason struct btrfs_key *cpu_key, u32 data_size) 2268be0e5c09SChris Mason { 22695f39d397SChris Mason struct extent_buffer *leaf; 22705f39d397SChris Mason struct btrfs_item *item; 2271aa5d6bedSChris Mason int ret = 0; 2272be0e5c09SChris Mason int slot; 2273eb60ceacSChris Mason int slot_orig; 22747518a238SChris Mason u32 nritems; 2275be0e5c09SChris Mason unsigned int data_end; 2276e2fa7227SChris Mason struct btrfs_disk_key disk_key; 2277e2fa7227SChris Mason 2278e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 2279be0e5c09SChris Mason 228074123bd7SChris Mason /* create a root if there isn't one */ 22815c680ed6SChris Mason if (!root->node) 2282cfaa7295SChris Mason BUG(); 22835f39d397SChris Mason 2284e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 2285eb60ceacSChris Mason if (ret == 0) { 2286f0930a37SChris Mason return -EEXIST; 2287aa5d6bedSChris Mason } 2288ed2ff2cbSChris Mason if (ret < 0) 2289ed2ff2cbSChris Mason goto out; 2290be0e5c09SChris Mason 229162e2749eSChris Mason slot_orig = path->slots[0]; 22925f39d397SChris Mason leaf = path->nodes[0]; 229374123bd7SChris Mason 22945f39d397SChris Mason nritems = btrfs_header_nritems(leaf); 2295123abc88SChris Mason data_end = leaf_data_end(root, leaf); 2296eb60ceacSChris Mason 2297123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 2298d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 22993326d1b0SChris Mason btrfs_print_leaf(root, leaf); 23003326d1b0SChris Mason printk("not enough freespace need %u have %d\n", 23013326d1b0SChris Mason data_size, btrfs_leaf_free_space(root, leaf)); 2302be0e5c09SChris Mason BUG(); 2303d4dbff95SChris Mason } 23045f39d397SChris Mason 230562e2749eSChris Mason slot = path->slots[0]; 2306eb60ceacSChris Mason BUG_ON(slot < 0); 23075f39d397SChris Mason 2308be0e5c09SChris Mason if (slot != nritems) { 2309be0e5c09SChris Mason int i; 23105f39d397SChris Mason unsigned int old_data = btrfs_item_end_nr(leaf, slot); 2311be0e5c09SChris Mason 23125f39d397SChris Mason if (old_data < data_end) { 23135f39d397SChris Mason btrfs_print_leaf(root, leaf); 23145f39d397SChris Mason printk("slot %d old_data %d data_end %d\n", 23155f39d397SChris Mason slot, old_data, data_end); 23165f39d397SChris Mason BUG_ON(1); 23175f39d397SChris Mason } 2318be0e5c09SChris Mason /* 2319be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 2320be0e5c09SChris Mason */ 2321be0e5c09SChris Mason /* first correct the data pointers */ 2322db94535dSChris Mason WARN_ON(leaf->map_token); 23230783fcfcSChris Mason for (i = slot; i < nritems; i++) { 23245f39d397SChris Mason u32 ioff; 2325db94535dSChris Mason 23265f39d397SChris Mason item = btrfs_item_nr(leaf, i); 2327db94535dSChris Mason if (!leaf->map_token) { 2328db94535dSChris Mason map_extent_buffer(leaf, (unsigned long)item, 2329db94535dSChris Mason sizeof(struct btrfs_item), 2330db94535dSChris Mason &leaf->map_token, &leaf->kaddr, 2331db94535dSChris Mason &leaf->map_start, &leaf->map_len, 2332db94535dSChris Mason KM_USER1); 2333db94535dSChris Mason } 2334db94535dSChris Mason 23355f39d397SChris Mason ioff = btrfs_item_offset(leaf, item); 23365f39d397SChris Mason btrfs_set_item_offset(leaf, item, ioff - data_size); 23370783fcfcSChris Mason } 2338db94535dSChris Mason if (leaf->map_token) { 2339db94535dSChris Mason unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); 2340db94535dSChris Mason leaf->map_token = NULL; 2341db94535dSChris Mason } 2342be0e5c09SChris Mason 2343be0e5c09SChris Mason /* shift the items */ 23445f39d397SChris Mason memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), 23455f39d397SChris Mason btrfs_item_nr_offset(slot), 23460783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 2347be0e5c09SChris Mason 2348be0e5c09SChris Mason /* shift the data */ 23495f39d397SChris Mason memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + 2350d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 2351be0e5c09SChris Mason data_end, old_data - data_end); 2352be0e5c09SChris Mason data_end = old_data; 2353be0e5c09SChris Mason } 23545f39d397SChris Mason 235562e2749eSChris Mason /* setup the item for the new data */ 23565f39d397SChris Mason btrfs_set_item_key(leaf, &disk_key, slot); 23575f39d397SChris Mason item = btrfs_item_nr(leaf, slot); 23585f39d397SChris Mason btrfs_set_item_offset(leaf, item, data_end - data_size); 23595f39d397SChris Mason btrfs_set_item_size(leaf, item, data_size); 23605f39d397SChris Mason btrfs_set_header_nritems(leaf, nritems + 1); 23615f39d397SChris Mason btrfs_mark_buffer_dirty(leaf); 2362aa5d6bedSChris Mason 2363aa5d6bedSChris Mason ret = 0; 23648e19f2cdSChris Mason if (slot == 0) 2365e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 2366aa5d6bedSChris Mason 23675f39d397SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) { 23685f39d397SChris Mason btrfs_print_leaf(root, leaf); 2369be0e5c09SChris Mason BUG(); 23705f39d397SChris Mason } 2371ed2ff2cbSChris Mason out: 237262e2749eSChris Mason return ret; 237362e2749eSChris Mason } 237462e2749eSChris Mason 237562e2749eSChris Mason /* 237662e2749eSChris Mason * Given a key and some data, insert an item into the tree. 237762e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 237862e2749eSChris Mason */ 2379e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 2380e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 2381e089f05cSChris Mason data_size) 238262e2749eSChris Mason { 238362e2749eSChris Mason int ret = 0; 23842c90e5d6SChris Mason struct btrfs_path *path; 23855f39d397SChris Mason struct extent_buffer *leaf; 23865f39d397SChris Mason unsigned long ptr; 238762e2749eSChris Mason 23882c90e5d6SChris Mason path = btrfs_alloc_path(); 23892c90e5d6SChris Mason BUG_ON(!path); 23902c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 239162e2749eSChris Mason if (!ret) { 23925f39d397SChris Mason leaf = path->nodes[0]; 23935f39d397SChris Mason ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); 23945f39d397SChris Mason write_extent_buffer(leaf, data, ptr, data_size); 23955f39d397SChris Mason btrfs_mark_buffer_dirty(leaf); 239662e2749eSChris Mason } 23972c90e5d6SChris Mason btrfs_free_path(path); 2398aa5d6bedSChris Mason return ret; 2399be0e5c09SChris Mason } 2400be0e5c09SChris Mason 240174123bd7SChris Mason /* 24025de08d7dSChris Mason * delete the pointer from a given node. 240374123bd7SChris Mason * 240474123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 240574123bd7SChris Mason * continuing all the way the root if required. The root is converted into 240674123bd7SChris Mason * a leaf if all the nodes are emptied. 240774123bd7SChris Mason */ 2408e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 2409e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 2410be0e5c09SChris Mason { 24115f39d397SChris Mason struct extent_buffer *parent = path->nodes[level]; 24127518a238SChris Mason u32 nritems; 2413aa5d6bedSChris Mason int ret = 0; 2414bb803951SChris Mason int wret; 2415be0e5c09SChris Mason 24165f39d397SChris Mason nritems = btrfs_header_nritems(parent); 2417be0e5c09SChris Mason if (slot != nritems -1) { 24185f39d397SChris Mason memmove_extent_buffer(parent, 24195f39d397SChris Mason btrfs_node_key_ptr_offset(slot), 24205f39d397SChris Mason btrfs_node_key_ptr_offset(slot + 1), 2421d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 2422d6025579SChris Mason (nritems - slot - 1)); 2423be0e5c09SChris Mason } 24247518a238SChris Mason nritems--; 24255f39d397SChris Mason btrfs_set_header_nritems(parent, nritems); 24267518a238SChris Mason if (nritems == 0 && parent == root->node) { 24275f39d397SChris Mason BUG_ON(btrfs_header_level(root->node) != 1); 2428eb60ceacSChris Mason /* just turn the root into a leaf and break */ 24295f39d397SChris Mason btrfs_set_header_level(root->node, 0); 2430bb803951SChris Mason } else if (slot == 0) { 24315f39d397SChris Mason struct btrfs_disk_key disk_key; 24325f39d397SChris Mason 24335f39d397SChris Mason btrfs_node_key(parent, &disk_key, 0); 24345f39d397SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, level + 1); 24350f70abe2SChris Mason if (wret) 24360f70abe2SChris Mason ret = wret; 2437be0e5c09SChris Mason } 2438d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 2439aa5d6bedSChris Mason return ret; 2440be0e5c09SChris Mason } 2441be0e5c09SChris Mason 244274123bd7SChris Mason /* 244374123bd7SChris Mason * delete the item at the leaf level in path. If that empties 244474123bd7SChris Mason * the leaf, remove it from the tree 244574123bd7SChris Mason */ 2446e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 2447e089f05cSChris Mason struct btrfs_path *path) 2448be0e5c09SChris Mason { 2449be0e5c09SChris Mason int slot; 24505f39d397SChris Mason struct extent_buffer *leaf; 24515f39d397SChris Mason struct btrfs_item *item; 2452be0e5c09SChris Mason int doff; 2453be0e5c09SChris Mason int dsize; 2454aa5d6bedSChris Mason int ret = 0; 2455aa5d6bedSChris Mason int wret; 24567518a238SChris Mason u32 nritems; 2457be0e5c09SChris Mason 24585f39d397SChris Mason leaf = path->nodes[0]; 24594920c9acSChris Mason slot = path->slots[0]; 24605f39d397SChris Mason doff = btrfs_item_offset_nr(leaf, slot); 24615f39d397SChris Mason dsize = btrfs_item_size_nr(leaf, slot); 24625f39d397SChris Mason nritems = btrfs_header_nritems(leaf); 2463be0e5c09SChris Mason 24647518a238SChris Mason if (slot != nritems - 1) { 2465be0e5c09SChris Mason int i; 2466123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 24675f39d397SChris Mason 24685f39d397SChris Mason memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + 2469d6025579SChris Mason data_end + dsize, 2470123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 2471be0e5c09SChris Mason doff - data_end); 24725f39d397SChris Mason 24730783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 24745f39d397SChris Mason u32 ioff; 2475db94535dSChris Mason 24765f39d397SChris Mason item = btrfs_item_nr(leaf, i); 2477db94535dSChris Mason if (!leaf->map_token) { 2478db94535dSChris Mason map_extent_buffer(leaf, (unsigned long)item, 2479db94535dSChris Mason sizeof(struct btrfs_item), 2480db94535dSChris Mason &leaf->map_token, &leaf->kaddr, 2481db94535dSChris Mason &leaf->map_start, &leaf->map_len, 2482db94535dSChris Mason KM_USER1); 2483db94535dSChris Mason } 24845f39d397SChris Mason ioff = btrfs_item_offset(leaf, item); 24855f39d397SChris Mason btrfs_set_item_offset(leaf, item, ioff + dsize); 24860783fcfcSChris Mason } 2487db94535dSChris Mason 2488db94535dSChris Mason if (leaf->map_token) { 2489db94535dSChris Mason unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); 2490db94535dSChris Mason leaf->map_token = NULL; 2491db94535dSChris Mason } 2492db94535dSChris Mason 24935f39d397SChris Mason memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), 24945f39d397SChris Mason btrfs_item_nr_offset(slot + 1), 24950783fcfcSChris Mason sizeof(struct btrfs_item) * 24967518a238SChris Mason (nritems - slot - 1)); 2497be0e5c09SChris Mason } 24985f39d397SChris Mason btrfs_set_header_nritems(leaf, nritems - 1); 24997518a238SChris Mason nritems--; 25005f39d397SChris Mason 250174123bd7SChris Mason /* delete the leaf if we've emptied it */ 25027518a238SChris Mason if (nritems == 0) { 25035f39d397SChris Mason if (leaf == root->node) { 25045f39d397SChris Mason btrfs_set_header_level(leaf, 0); 25059a8dd150SChris Mason } else { 2506*7bb86316SChris Mason u64 root_gen = btrfs_header_generation(path->nodes[1]); 25075f39d397SChris Mason clean_tree_block(trans, root, leaf); 25085f39d397SChris Mason wait_on_tree_block_writeback(root, leaf); 2509e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 2510aa5d6bedSChris Mason if (wret) 2511aa5d6bedSChris Mason ret = wret; 2512e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 2513*7bb86316SChris Mason leaf->start, leaf->len, 2514*7bb86316SChris Mason btrfs_header_owner(path->nodes[1]), 2515*7bb86316SChris Mason root_gen, 0, 0, 1); 25160f70abe2SChris Mason if (wret) 25170f70abe2SChris Mason ret = wret; 25189a8dd150SChris Mason } 2519be0e5c09SChris Mason } else { 25207518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 2521aa5d6bedSChris Mason if (slot == 0) { 25225f39d397SChris Mason struct btrfs_disk_key disk_key; 25235f39d397SChris Mason 25245f39d397SChris Mason btrfs_item_key(leaf, &disk_key, 0); 2525e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 25265f39d397SChris Mason &disk_key, 1); 2527aa5d6bedSChris Mason if (wret) 2528aa5d6bedSChris Mason ret = wret; 2529aa5d6bedSChris Mason } 2530aa5d6bedSChris Mason 253174123bd7SChris Mason /* delete the leaf if it is mostly empty */ 25327936ca38SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 2533be0e5c09SChris Mason /* push_leaf_left fixes the path. 2534be0e5c09SChris Mason * make sure the path still points to our leaf 2535be0e5c09SChris Mason * for possible call to del_ptr below 2536be0e5c09SChris Mason */ 25374920c9acSChris Mason slot = path->slots[1]; 25385f39d397SChris Mason extent_buffer_get(leaf); 25395f39d397SChris Mason 254034a38218SChris Mason wret = push_leaf_right(trans, root, path, 1, 1); 254154aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 2542aa5d6bedSChris Mason ret = wret; 25435f39d397SChris Mason 25445f39d397SChris Mason if (path->nodes[0] == leaf && 25455f39d397SChris Mason btrfs_header_nritems(leaf)) { 254634a38218SChris Mason wret = push_leaf_left(trans, root, path, 1, 1); 254754aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 2548aa5d6bedSChris Mason ret = wret; 2549aa5d6bedSChris Mason } 25505f39d397SChris Mason 25515f39d397SChris Mason if (btrfs_header_nritems(leaf) == 0) { 2552*7bb86316SChris Mason u64 root_gen; 2553db94535dSChris Mason u64 bytenr = leaf->start; 2554db94535dSChris Mason u32 blocksize = leaf->len; 25555f39d397SChris Mason 2556*7bb86316SChris Mason root_gen = btrfs_header_generation( 2557*7bb86316SChris Mason path->nodes[1]); 2558*7bb86316SChris Mason 25595f39d397SChris Mason clean_tree_block(trans, root, leaf); 25605f39d397SChris Mason wait_on_tree_block_writeback(root, leaf); 25615f39d397SChris Mason 2562e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 2563aa5d6bedSChris Mason if (wret) 2564aa5d6bedSChris Mason ret = wret; 25655f39d397SChris Mason 25665f39d397SChris Mason free_extent_buffer(leaf); 2567db94535dSChris Mason wret = btrfs_free_extent(trans, root, bytenr, 2568*7bb86316SChris Mason blocksize, 2569*7bb86316SChris Mason btrfs_header_owner(path->nodes[1]), 2570*7bb86316SChris Mason root_gen, 0, 0, 1); 25710f70abe2SChris Mason if (wret) 25720f70abe2SChris Mason ret = wret; 25735de08d7dSChris Mason } else { 25745f39d397SChris Mason btrfs_mark_buffer_dirty(leaf); 25755f39d397SChris Mason free_extent_buffer(leaf); 2576be0e5c09SChris Mason } 2577d5719762SChris Mason } else { 25785f39d397SChris Mason btrfs_mark_buffer_dirty(leaf); 2579be0e5c09SChris Mason } 25809a8dd150SChris Mason } 2581aa5d6bedSChris Mason return ret; 25829a8dd150SChris Mason } 25839a8dd150SChris Mason 258497571fd0SChris Mason /* 2585*7bb86316SChris Mason * walk up the tree as far as required to find the previous leaf. 2586*7bb86316SChris Mason * returns 0 if it found something or 1 if there are no lesser leaves. 2587*7bb86316SChris Mason * returns < 0 on io errors. 2588*7bb86316SChris Mason */ 2589*7bb86316SChris Mason int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) 2590*7bb86316SChris Mason { 2591*7bb86316SChris Mason int slot; 2592*7bb86316SChris Mason int level = 1; 2593*7bb86316SChris Mason u64 bytenr; 2594*7bb86316SChris Mason struct extent_buffer *c; 2595*7bb86316SChris Mason struct extent_buffer *next = NULL; 2596*7bb86316SChris Mason 2597*7bb86316SChris Mason while(level < BTRFS_MAX_LEVEL) { 2598*7bb86316SChris Mason if (!path->nodes[level]) 2599*7bb86316SChris Mason return 1; 2600*7bb86316SChris Mason 2601*7bb86316SChris Mason slot = path->slots[level]; 2602*7bb86316SChris Mason c = path->nodes[level]; 2603*7bb86316SChris Mason if (slot == 0) { 2604*7bb86316SChris Mason level++; 2605*7bb86316SChris Mason if (level == BTRFS_MAX_LEVEL) 2606*7bb86316SChris Mason return 1; 2607*7bb86316SChris Mason continue; 2608*7bb86316SChris Mason } 2609*7bb86316SChris Mason slot--; 2610*7bb86316SChris Mason 2611*7bb86316SChris Mason bytenr = btrfs_node_blockptr(c, slot); 2612*7bb86316SChris Mason if (next) 2613*7bb86316SChris Mason free_extent_buffer(next); 2614*7bb86316SChris Mason 2615*7bb86316SChris Mason if (path->reada < 0) 2616*7bb86316SChris Mason reada_for_search(root, path, level, slot); 2617*7bb86316SChris Mason 2618*7bb86316SChris Mason next = read_tree_block(root, bytenr, 2619*7bb86316SChris Mason btrfs_level_size(root, level - 1)); 2620*7bb86316SChris Mason break; 2621*7bb86316SChris Mason } 2622*7bb86316SChris Mason path->slots[level] = slot; 2623*7bb86316SChris Mason while(1) { 2624*7bb86316SChris Mason level--; 2625*7bb86316SChris Mason c = path->nodes[level]; 2626*7bb86316SChris Mason free_extent_buffer(c); 2627*7bb86316SChris Mason path->nodes[level] = next; 2628*7bb86316SChris Mason path->slots[level] = 0; 2629*7bb86316SChris Mason if (!level) 2630*7bb86316SChris Mason break; 2631*7bb86316SChris Mason if (path->reada) 2632*7bb86316SChris Mason reada_for_search(root, path, level, 0); 2633*7bb86316SChris Mason next = read_tree_block(root, btrfs_node_blockptr(next, 0), 2634*7bb86316SChris Mason btrfs_level_size(root, level - 1)); 2635*7bb86316SChris Mason } 2636*7bb86316SChris Mason return 0; 2637*7bb86316SChris Mason } 2638*7bb86316SChris Mason 2639*7bb86316SChris Mason /* 264097571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 26410f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 26420f70abe2SChris Mason * returns < 0 on io errors. 264397571fd0SChris Mason */ 2644234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 2645d97e63b6SChris Mason { 2646d97e63b6SChris Mason int slot; 2647d97e63b6SChris Mason int level = 1; 2648db94535dSChris Mason u64 bytenr; 26495f39d397SChris Mason struct extent_buffer *c; 26505f39d397SChris Mason struct extent_buffer *next = NULL; 2651d97e63b6SChris Mason 2652234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 2653d97e63b6SChris Mason if (!path->nodes[level]) 26540f70abe2SChris Mason return 1; 26555f39d397SChris Mason 2656d97e63b6SChris Mason slot = path->slots[level] + 1; 2657d97e63b6SChris Mason c = path->nodes[level]; 26585f39d397SChris Mason if (slot >= btrfs_header_nritems(c)) { 2659d97e63b6SChris Mason level++; 2660*7bb86316SChris Mason if (level == BTRFS_MAX_LEVEL) 2661*7bb86316SChris Mason return 1; 2662d97e63b6SChris Mason continue; 2663d97e63b6SChris Mason } 26645f39d397SChris Mason 2665db94535dSChris Mason bytenr = btrfs_node_blockptr(c, slot); 2666cfaa7295SChris Mason if (next) 26675f39d397SChris Mason free_extent_buffer(next); 26685f39d397SChris Mason 26696702ed49SChris Mason if (path->reada) 26706702ed49SChris Mason reada_for_search(root, path, level, slot); 26715f39d397SChris Mason 2672db94535dSChris Mason next = read_tree_block(root, bytenr, 2673db94535dSChris Mason btrfs_level_size(root, level -1)); 2674d97e63b6SChris Mason break; 2675d97e63b6SChris Mason } 2676d97e63b6SChris Mason path->slots[level] = slot; 2677d97e63b6SChris Mason while(1) { 2678d97e63b6SChris Mason level--; 2679d97e63b6SChris Mason c = path->nodes[level]; 26805f39d397SChris Mason free_extent_buffer(c); 2681d97e63b6SChris Mason path->nodes[level] = next; 2682d97e63b6SChris Mason path->slots[level] = 0; 2683d97e63b6SChris Mason if (!level) 2684d97e63b6SChris Mason break; 26856702ed49SChris Mason if (path->reada) 268632020611SYan reada_for_search(root, path, level, 0); 2687db94535dSChris Mason next = read_tree_block(root, btrfs_node_blockptr(next, 0), 2688db94535dSChris Mason btrfs_level_size(root, level - 1)); 2689d97e63b6SChris Mason } 2690d97e63b6SChris Mason return 0; 2691d97e63b6SChris Mason } 2692