16cbd5570SChris Mason /* 26cbd5570SChris Mason * Copyright (C) 2007 Oracle. All rights reserved. 36cbd5570SChris Mason * 46cbd5570SChris Mason * This program is free software; you can redistribute it and/or 56cbd5570SChris Mason * modify it under the terms of the GNU General Public 66cbd5570SChris Mason * License v2 as published by the Free Software Foundation. 76cbd5570SChris Mason * 86cbd5570SChris Mason * This program is distributed in the hope that it will be useful, 96cbd5570SChris Mason * but WITHOUT ANY WARRANTY; without even the implied warranty of 106cbd5570SChris Mason * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 116cbd5570SChris Mason * General Public License for more details. 126cbd5570SChris Mason * 136cbd5570SChris Mason * You should have received a copy of the GNU General Public 146cbd5570SChris Mason * License along with this program; if not, write to the 156cbd5570SChris Mason * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 166cbd5570SChris Mason * Boston, MA 021110-1307, USA. 176cbd5570SChris Mason */ 186cbd5570SChris Mason 19eb60ceacSChris Mason #include "ctree.h" 20eb60ceacSChris Mason #include "disk-io.h" 217f5c1516SChris Mason #include "transaction.h" 229a8dd150SChris Mason 23e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 24e089f05cSChris Mason *root, struct btrfs_path *path, int level); 25e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 26d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 27d4dbff95SChris Mason struct btrfs_path *path, int data_size); 28e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 29e20d96d6SChris Mason *root, struct buffer_head *dst, struct buffer_head 30e089f05cSChris Mason *src); 31e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 32e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 33e20d96d6SChris Mason struct buffer_head *src_buf); 34e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 35e089f05cSChris Mason struct btrfs_path *path, int level, int slot); 36d97e63b6SChris Mason 37df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p) 38df24a2b9SChris Mason { 39df24a2b9SChris Mason memset(p, 0, sizeof(*p)); 40df24a2b9SChris Mason } 41df24a2b9SChris Mason 422c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void) 432c90e5d6SChris Mason { 44df24a2b9SChris Mason struct btrfs_path *path; 45df24a2b9SChris Mason path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); 46df24a2b9SChris Mason if (path) 47df24a2b9SChris Mason btrfs_init_path(path); 48df24a2b9SChris Mason return path; 492c90e5d6SChris Mason } 502c90e5d6SChris Mason 512c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p) 522c90e5d6SChris Mason { 53df24a2b9SChris Mason btrfs_release_path(NULL, p); 542c90e5d6SChris Mason kmem_cache_free(btrfs_path_cachep, p); 552c90e5d6SChris Mason } 562c90e5d6SChris Mason 57234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) 58eb60ceacSChris Mason { 59eb60ceacSChris Mason int i; 60234b63a0SChris Mason for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 61eb60ceacSChris Mason if (!p->nodes[i]) 62eb60ceacSChris Mason break; 63234b63a0SChris Mason btrfs_block_release(root, p->nodes[i]); 64eb60ceacSChris Mason } 65aa5d6bedSChris Mason memset(p, 0, sizeof(*p)); 66eb60ceacSChris Mason } 67eb60ceacSChris Mason 686702ed49SChris Mason static int __btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 696702ed49SChris Mason *root, struct buffer_head *buf, struct buffer_head 706702ed49SChris Mason *parent, int parent_slot, struct buffer_head 716702ed49SChris Mason **cow_ret, u64 search_start, u64 empty_size) 726702ed49SChris Mason { 736702ed49SChris Mason struct buffer_head *cow; 746702ed49SChris Mason struct btrfs_node *cow_node; 756702ed49SChris Mason int ret = 0; 766702ed49SChris Mason int different_trans = 0; 776702ed49SChris Mason 786702ed49SChris Mason WARN_ON(root->ref_cows && trans->transid != root->last_trans); 796702ed49SChris Mason WARN_ON(!buffer_uptodate(buf)); 806702ed49SChris Mason cow = btrfs_alloc_free_block(trans, root, search_start, empty_size); 816702ed49SChris Mason if (IS_ERR(cow)) 826702ed49SChris Mason return PTR_ERR(cow); 836702ed49SChris Mason 846702ed49SChris Mason cow_node = btrfs_buffer_node(cow); 856702ed49SChris Mason if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) 866702ed49SChris Mason WARN_ON(1); 876702ed49SChris Mason 886702ed49SChris Mason memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 896702ed49SChris Mason btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); 906702ed49SChris Mason btrfs_set_header_generation(&cow_node->header, trans->transid); 916702ed49SChris Mason btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); 926702ed49SChris Mason 936702ed49SChris Mason WARN_ON(btrfs_header_generation(btrfs_buffer_header(buf)) > 946702ed49SChris Mason trans->transid); 956702ed49SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) != 966702ed49SChris Mason trans->transid) { 976702ed49SChris Mason different_trans = 1; 986702ed49SChris Mason ret = btrfs_inc_ref(trans, root, buf); 996702ed49SChris Mason if (ret) 1006702ed49SChris Mason return ret; 1016702ed49SChris Mason } else { 1026702ed49SChris Mason clean_tree_block(trans, root, buf); 1036702ed49SChris Mason } 1046702ed49SChris Mason 1056702ed49SChris Mason if (buf == root->node) { 1066702ed49SChris Mason root->node = cow; 1076702ed49SChris Mason get_bh(cow); 1086702ed49SChris Mason if (buf != root->commit_root) { 1096702ed49SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 1106702ed49SChris Mason } 1116702ed49SChris Mason btrfs_block_release(root, buf); 1126702ed49SChris Mason } else { 1136702ed49SChris Mason btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 1146702ed49SChris Mason bh_blocknr(cow)); 1156702ed49SChris Mason btrfs_mark_buffer_dirty(parent); 1166702ed49SChris Mason WARN_ON(btrfs_header_generation(btrfs_buffer_header(parent)) != 1176702ed49SChris Mason trans->transid); 1186702ed49SChris Mason btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); 1196702ed49SChris Mason } 1206702ed49SChris Mason btrfs_block_release(root, buf); 1216702ed49SChris Mason btrfs_mark_buffer_dirty(cow); 1226702ed49SChris Mason *cow_ret = cow; 1236702ed49SChris Mason return 0; 1246702ed49SChris Mason } 1256702ed49SChris Mason 1266702ed49SChris Mason int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 127e20d96d6SChris Mason *root, struct buffer_head *buf, struct buffer_head 128e20d96d6SChris Mason *parent, int parent_slot, struct buffer_head 129e089f05cSChris Mason **cow_ret) 13002217ed2SChris Mason { 1316702ed49SChris Mason u64 search_start; 132ccd467d6SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 133ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 134ccd467d6SChris Mason root->fs_info->running_transaction->transid); 135ccd467d6SChris Mason WARN_ON(1); 136ccd467d6SChris Mason } 137ccd467d6SChris Mason if (trans->transid != root->fs_info->generation) { 138ccd467d6SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 139ccd467d6SChris Mason root->fs_info->generation); 140ccd467d6SChris Mason WARN_ON(1); 141ccd467d6SChris Mason } 1427f5c1516SChris Mason if (btrfs_header_generation(btrfs_buffer_header(buf)) == 1437f5c1516SChris Mason trans->transid) { 14402217ed2SChris Mason *cow_ret = buf; 14502217ed2SChris Mason return 0; 14602217ed2SChris Mason } 1476702ed49SChris Mason 1486702ed49SChris Mason search_start = bh_blocknr(buf) & ~((u64)65535); 1496702ed49SChris Mason return __btrfs_cow_block(trans, root, buf, parent, 1506702ed49SChris Mason parent_slot, cow_ret, search_start, 0); 1512c90e5d6SChris Mason } 1526702ed49SChris Mason 1536702ed49SChris Mason static int close_blocks(u64 blocknr, u64 other) 1546702ed49SChris Mason { 1556702ed49SChris Mason if (blocknr < other && other - blocknr < 8) 1566702ed49SChris Mason return 1; 1576702ed49SChris Mason if (blocknr > other && blocknr - other < 8) 1586702ed49SChris Mason return 1; 15902217ed2SChris Mason return 0; 16002217ed2SChris Mason } 16102217ed2SChris Mason 1626702ed49SChris Mason int btrfs_realloc_node(struct btrfs_trans_handle *trans, 1636702ed49SChris Mason struct btrfs_root *root, struct buffer_head *parent, 164*e9d0b13bSChris Mason int cache_only, u64 *last_ret) 1656702ed49SChris Mason { 1666702ed49SChris Mason struct btrfs_node *parent_node; 1676702ed49SChris Mason struct buffer_head *cur_bh; 1686702ed49SChris Mason struct buffer_head *tmp_bh; 1696702ed49SChris Mason u64 blocknr; 170*e9d0b13bSChris Mason u64 search_start = *last_ret; 171*e9d0b13bSChris Mason u64 last_block = 0; 1726702ed49SChris Mason u64 other; 1736702ed49SChris Mason u32 parent_nritems; 1746702ed49SChris Mason int start_slot; 1756702ed49SChris Mason int end_slot; 1766702ed49SChris Mason int i; 1776702ed49SChris Mason int err = 0; 1786702ed49SChris Mason 1796702ed49SChris Mason if (trans->transaction != root->fs_info->running_transaction) { 1806702ed49SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 1816702ed49SChris Mason root->fs_info->running_transaction->transid); 1826702ed49SChris Mason WARN_ON(1); 1836702ed49SChris Mason } 1846702ed49SChris Mason if (trans->transid != root->fs_info->generation) { 1856702ed49SChris Mason printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid, 1866702ed49SChris Mason root->fs_info->generation); 1876702ed49SChris Mason WARN_ON(1); 1886702ed49SChris Mason } 1896702ed49SChris Mason parent_node = btrfs_buffer_node(parent); 1906702ed49SChris Mason parent_nritems = btrfs_header_nritems(&parent_node->header); 1916702ed49SChris Mason 1926702ed49SChris Mason start_slot = 0; 1936702ed49SChris Mason end_slot = parent_nritems; 1946702ed49SChris Mason 1956702ed49SChris Mason if (parent_nritems == 1) 1966702ed49SChris Mason return 0; 1976702ed49SChris Mason 1986702ed49SChris Mason for (i = start_slot; i < end_slot; i++) { 1996702ed49SChris Mason int close = 1; 2006702ed49SChris Mason blocknr = btrfs_node_blockptr(parent_node, i); 201*e9d0b13bSChris Mason if (last_block == 0) 202*e9d0b13bSChris Mason last_block = blocknr; 2036702ed49SChris Mason if (i > 0) { 2046702ed49SChris Mason other = btrfs_node_blockptr(parent_node, i - 1); 2056702ed49SChris Mason close = close_blocks(blocknr, other); 2066702ed49SChris Mason } 2076702ed49SChris Mason if (close && i < end_slot - 1) { 2086702ed49SChris Mason other = btrfs_node_blockptr(parent_node, i + 1); 2096702ed49SChris Mason close = close_blocks(blocknr, other); 2106702ed49SChris Mason } 211*e9d0b13bSChris Mason if (close) { 212*e9d0b13bSChris Mason last_block = blocknr; 2136702ed49SChris Mason continue; 214*e9d0b13bSChris Mason } 2156702ed49SChris Mason 2166702ed49SChris Mason cur_bh = btrfs_find_tree_block(root, blocknr); 2176702ed49SChris Mason if (!cur_bh || !buffer_uptodate(cur_bh) || 2186702ed49SChris Mason buffer_locked(cur_bh)) { 2196702ed49SChris Mason if (cache_only) { 2206702ed49SChris Mason brelse(cur_bh); 2216702ed49SChris Mason continue; 2226702ed49SChris Mason } 2236702ed49SChris Mason brelse(cur_bh); 2246702ed49SChris Mason cur_bh = read_tree_block(root, blocknr); 2256702ed49SChris Mason } 226*e9d0b13bSChris Mason if (search_start == 0) 227*e9d0b13bSChris Mason search_start = last_block & ~((u64)65535); 228*e9d0b13bSChris Mason 2296702ed49SChris Mason err = __btrfs_cow_block(trans, root, cur_bh, parent, i, 2306702ed49SChris Mason &tmp_bh, search_start, 2316702ed49SChris Mason min(8, end_slot - i)); 2326702ed49SChris Mason if (err) 2336702ed49SChris Mason break; 2346702ed49SChris Mason search_start = bh_blocknr(tmp_bh); 2356702ed49SChris Mason brelse(tmp_bh); 2366702ed49SChris Mason } 2376702ed49SChris Mason return err; 2386702ed49SChris Mason } 2396702ed49SChris Mason 24074123bd7SChris Mason /* 24174123bd7SChris Mason * The leaf data grows from end-to-front in the node. 24274123bd7SChris Mason * this returns the address of the start of the last item, 24374123bd7SChris Mason * which is the stop of the leaf data stack 24474123bd7SChris Mason */ 245123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root, 246123abc88SChris Mason struct btrfs_leaf *leaf) 247be0e5c09SChris Mason { 2487518a238SChris Mason u32 nr = btrfs_header_nritems(&leaf->header); 249be0e5c09SChris Mason if (nr == 0) 250123abc88SChris Mason return BTRFS_LEAF_DATA_SIZE(root); 2510783fcfcSChris Mason return btrfs_item_offset(leaf->items + nr - 1); 252be0e5c09SChris Mason } 253be0e5c09SChris Mason 25474123bd7SChris Mason /* 25574123bd7SChris Mason * compare two keys in a memcmp fashion 25674123bd7SChris Mason */ 2579aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) 258be0e5c09SChris Mason { 259e2fa7227SChris Mason struct btrfs_key k1; 260e2fa7227SChris Mason 261e2fa7227SChris Mason btrfs_disk_key_to_cpu(&k1, disk); 262e2fa7227SChris Mason 263e2fa7227SChris Mason if (k1.objectid > k2->objectid) 264be0e5c09SChris Mason return 1; 265e2fa7227SChris Mason if (k1.objectid < k2->objectid) 266be0e5c09SChris Mason return -1; 267f254e52cSChris Mason if (k1.flags > k2->flags) 268f254e52cSChris Mason return 1; 269f254e52cSChris Mason if (k1.flags < k2->flags) 270f254e52cSChris Mason return -1; 27170b2befdSChris Mason if (k1.offset > k2->offset) 27270b2befdSChris Mason return 1; 27370b2befdSChris Mason if (k1.offset < k2->offset) 27470b2befdSChris Mason return -1; 275be0e5c09SChris Mason return 0; 276be0e5c09SChris Mason } 27774123bd7SChris Mason 278123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path, 279123abc88SChris Mason int level) 280aa5d6bedSChris Mason { 281234b63a0SChris Mason struct btrfs_node *parent = NULL; 282e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 283aa5d6bedSChris Mason int parent_slot; 2848d7be552SChris Mason int slot; 2858d7be552SChris Mason struct btrfs_key cpukey; 2867518a238SChris Mason u32 nritems = btrfs_header_nritems(&node->header); 287aa5d6bedSChris Mason 288aa5d6bedSChris Mason if (path->nodes[level + 1]) 289e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 290a1f39630SAneesh 2918d7be552SChris Mason slot = path->slots[level]; 2927518a238SChris Mason BUG_ON(nritems == 0); 2937518a238SChris Mason if (parent) { 294e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 295a1f39630SAneesh 296a1f39630SAneesh parent_slot = path->slots[level + 1]; 297123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 298123abc88SChris Mason BUG_ON(memcmp(parent_key, &node->ptrs[0].key, 299e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 3001d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 3017518a238SChris Mason btrfs_header_blocknr(&node->header)); 302aa5d6bedSChris Mason } 303123abc88SChris Mason BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); 3048d7be552SChris Mason if (slot != 0) { 3058d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key); 3068d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0); 3078d7be552SChris Mason } 3088d7be552SChris Mason if (slot < nritems - 1) { 3098d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key); 3108d7be552SChris Mason BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0); 311aa5d6bedSChris Mason } 312aa5d6bedSChris Mason return 0; 313aa5d6bedSChris Mason } 314aa5d6bedSChris Mason 315123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, 316123abc88SChris Mason int level) 317aa5d6bedSChris Mason { 318e20d96d6SChris Mason struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); 319234b63a0SChris Mason struct btrfs_node *parent = NULL; 320aa5d6bedSChris Mason int parent_slot; 3218d7be552SChris Mason int slot = path->slots[0]; 3228d7be552SChris Mason struct btrfs_key cpukey; 3238d7be552SChris Mason 3247518a238SChris Mason u32 nritems = btrfs_header_nritems(&leaf->header); 325aa5d6bedSChris Mason 326aa5d6bedSChris Mason if (path->nodes[level + 1]) 327e20d96d6SChris Mason parent = btrfs_buffer_node(path->nodes[level + 1]); 328a1f39630SAneesh 329123abc88SChris Mason BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 3307518a238SChris Mason 3317518a238SChris Mason if (nritems == 0) 3327518a238SChris Mason return 0; 3337518a238SChris Mason 3347518a238SChris Mason if (parent) { 335e2fa7227SChris Mason struct btrfs_disk_key *parent_key; 336a1f39630SAneesh 337a1f39630SAneesh parent_slot = path->slots[level + 1]; 338123abc88SChris Mason parent_key = &parent->ptrs[parent_slot].key; 3396702ed49SChris Mason 340aa5d6bedSChris Mason BUG_ON(memcmp(parent_key, &leaf->items[0].key, 341e2fa7227SChris Mason sizeof(struct btrfs_disk_key))); 3421d4f8a0cSChris Mason BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 3437518a238SChris Mason btrfs_header_blocknr(&leaf->header)); 344aa5d6bedSChris Mason } 3458d7be552SChris Mason if (slot != 0) { 3468d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key); 3478d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0); 3488d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot - 1) != 3498d7be552SChris Mason btrfs_item_end(leaf->items + slot)); 350aa5d6bedSChris Mason } 3518d7be552SChris Mason if (slot < nritems - 1) { 3528d7be552SChris Mason btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key); 3538d7be552SChris Mason BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0); 3548d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items + slot) != 3558d7be552SChris Mason btrfs_item_end(leaf->items + slot + 1)); 356aa5d6bedSChris Mason } 3578d7be552SChris Mason BUG_ON(btrfs_item_offset(leaf->items) + 3588d7be552SChris Mason btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root)); 359aa5d6bedSChris Mason return 0; 360aa5d6bedSChris Mason } 361aa5d6bedSChris Mason 362123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path, 363123abc88SChris Mason int level) 364aa5d6bedSChris Mason { 3653eb0314dSChris Mason struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); 3663eb0314dSChris Mason if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, 3673eb0314dSChris Mason sizeof(node->header.fsid))) 3683eb0314dSChris Mason BUG(); 369aa5d6bedSChris Mason if (level == 0) 370123abc88SChris Mason return check_leaf(root, path, level); 371123abc88SChris Mason return check_node(root, path, level); 372aa5d6bedSChris Mason } 373aa5d6bedSChris Mason 37474123bd7SChris Mason /* 37574123bd7SChris Mason * search for key in the array p. items p are item_size apart 37674123bd7SChris Mason * and there are 'max' items in p 37774123bd7SChris Mason * the slot in the array is returned via slot, and it points to 37874123bd7SChris Mason * the place where you would insert key if it is not found in 37974123bd7SChris Mason * the array. 38074123bd7SChris Mason * 38174123bd7SChris Mason * slot may point to max if the key is bigger than all of the keys 38274123bd7SChris Mason */ 3839aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, 384be0e5c09SChris Mason int max, int *slot) 385be0e5c09SChris Mason { 386be0e5c09SChris Mason int low = 0; 387be0e5c09SChris Mason int high = max; 388be0e5c09SChris Mason int mid; 389be0e5c09SChris Mason int ret; 390e2fa7227SChris Mason struct btrfs_disk_key *tmp; 391be0e5c09SChris Mason 392be0e5c09SChris Mason while(low < high) { 393be0e5c09SChris Mason mid = (low + high) / 2; 394e2fa7227SChris Mason tmp = (struct btrfs_disk_key *)(p + mid * item_size); 395be0e5c09SChris Mason ret = comp_keys(tmp, key); 396be0e5c09SChris Mason 397be0e5c09SChris Mason if (ret < 0) 398be0e5c09SChris Mason low = mid + 1; 399be0e5c09SChris Mason else if (ret > 0) 400be0e5c09SChris Mason high = mid; 401be0e5c09SChris Mason else { 402be0e5c09SChris Mason *slot = mid; 403be0e5c09SChris Mason return 0; 404be0e5c09SChris Mason } 405be0e5c09SChris Mason } 406be0e5c09SChris Mason *slot = low; 407be0e5c09SChris Mason return 1; 408be0e5c09SChris Mason } 409be0e5c09SChris Mason 41097571fd0SChris Mason /* 41197571fd0SChris Mason * simple bin_search frontend that does the right thing for 41297571fd0SChris Mason * leaves vs nodes 41397571fd0SChris Mason */ 4149aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) 415be0e5c09SChris Mason { 4167518a238SChris Mason if (btrfs_is_leaf(c)) { 417234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 4180783fcfcSChris Mason return generic_bin_search((void *)l->items, 4190783fcfcSChris Mason sizeof(struct btrfs_item), 4207518a238SChris Mason key, btrfs_header_nritems(&c->header), 4217518a238SChris Mason slot); 422be0e5c09SChris Mason } else { 423123abc88SChris Mason return generic_bin_search((void *)c->ptrs, 424123abc88SChris Mason sizeof(struct btrfs_key_ptr), 4257518a238SChris Mason key, btrfs_header_nritems(&c->header), 4267518a238SChris Mason slot); 427be0e5c09SChris Mason } 428be0e5c09SChris Mason return -1; 429be0e5c09SChris Mason } 430be0e5c09SChris Mason 431e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root, 432e20d96d6SChris Mason struct buffer_head *parent_buf, 433bb803951SChris Mason int slot) 434bb803951SChris Mason { 435e20d96d6SChris Mason struct btrfs_node *node = btrfs_buffer_node(parent_buf); 436bb803951SChris Mason if (slot < 0) 437bb803951SChris Mason return NULL; 4387518a238SChris Mason if (slot >= btrfs_header_nritems(&node->header)) 439bb803951SChris Mason return NULL; 4401d4f8a0cSChris Mason return read_tree_block(root, btrfs_node_blockptr(node, slot)); 441bb803951SChris Mason } 442bb803951SChris Mason 443e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 444e089f05cSChris Mason *root, struct btrfs_path *path, int level) 445bb803951SChris Mason { 446e20d96d6SChris Mason struct buffer_head *right_buf; 447e20d96d6SChris Mason struct buffer_head *mid_buf; 448e20d96d6SChris Mason struct buffer_head *left_buf; 449e20d96d6SChris Mason struct buffer_head *parent_buf = NULL; 450234b63a0SChris Mason struct btrfs_node *right = NULL; 451234b63a0SChris Mason struct btrfs_node *mid; 452234b63a0SChris Mason struct btrfs_node *left = NULL; 453234b63a0SChris Mason struct btrfs_node *parent = NULL; 454bb803951SChris Mason int ret = 0; 455bb803951SChris Mason int wret; 456bb803951SChris Mason int pslot; 457bb803951SChris Mason int orig_slot = path->slots[level]; 45854aa1f4dSChris Mason int err_on_enospc = 0; 45979f95c82SChris Mason u64 orig_ptr; 460bb803951SChris Mason 461bb803951SChris Mason if (level == 0) 462bb803951SChris Mason return 0; 463bb803951SChris Mason 464bb803951SChris Mason mid_buf = path->nodes[level]; 465e20d96d6SChris Mason mid = btrfs_buffer_node(mid_buf); 4661d4f8a0cSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 46779f95c82SChris Mason 468234b63a0SChris Mason if (level < BTRFS_MAX_LEVEL - 1) 469bb803951SChris Mason parent_buf = path->nodes[level + 1]; 470bb803951SChris Mason pslot = path->slots[level + 1]; 471bb803951SChris Mason 47240689478SChris Mason /* 47340689478SChris Mason * deal with the case where there is only one pointer in the root 47440689478SChris Mason * by promoting the node below to a root 47540689478SChris Mason */ 476bb803951SChris Mason if (!parent_buf) { 477e20d96d6SChris Mason struct buffer_head *child; 4787eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 479bb803951SChris Mason 4807518a238SChris Mason if (btrfs_header_nritems(&mid->header) != 1) 481bb803951SChris Mason return 0; 482bb803951SChris Mason 483bb803951SChris Mason /* promote the child to a root */ 484bb803951SChris Mason child = read_node_slot(root, mid_buf, 0); 485bb803951SChris Mason BUG_ON(!child); 486bb803951SChris Mason root->node = child; 487bb803951SChris Mason path->nodes[level] = NULL; 488d6025579SChris Mason clean_tree_block(trans, root, mid_buf); 489d6025579SChris Mason wait_on_buffer(mid_buf); 490bb803951SChris Mason /* once for the path */ 491234b63a0SChris Mason btrfs_block_release(root, mid_buf); 492bb803951SChris Mason /* once for the root ptr */ 493234b63a0SChris Mason btrfs_block_release(root, mid_buf); 494e089f05cSChris Mason return btrfs_free_extent(trans, root, blocknr, 1, 1); 495bb803951SChris Mason } 496e20d96d6SChris Mason parent = btrfs_buffer_node(parent_buf); 497bb803951SChris Mason 498123abc88SChris Mason if (btrfs_header_nritems(&mid->header) > 499123abc88SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 500bb803951SChris Mason return 0; 501bb803951SChris Mason 50254aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 50354aa1f4dSChris Mason err_on_enospc = 1; 50454aa1f4dSChris Mason 505bb803951SChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 506bb803951SChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 50779f95c82SChris Mason 50879f95c82SChris Mason /* first, try to make some room in the middle buffer */ 509bb803951SChris Mason if (left_buf) { 51054aa1f4dSChris Mason wret = btrfs_cow_block(trans, root, left_buf, 51154aa1f4dSChris Mason parent_buf, pslot - 1, &left_buf); 51254aa1f4dSChris Mason if (wret) { 51354aa1f4dSChris Mason ret = wret; 51454aa1f4dSChris Mason goto enospc; 51554aa1f4dSChris Mason } 516e20d96d6SChris Mason left = btrfs_buffer_node(left_buf); 5177518a238SChris Mason orig_slot += btrfs_header_nritems(&left->header); 518e089f05cSChris Mason wret = push_node_left(trans, root, left_buf, mid_buf); 51979f95c82SChris Mason if (wret < 0) 52079f95c82SChris Mason ret = wret; 52154aa1f4dSChris Mason if (btrfs_header_nritems(&mid->header) < 2) 52254aa1f4dSChris Mason err_on_enospc = 1; 523bb803951SChris Mason } 52479f95c82SChris Mason 52579f95c82SChris Mason /* 52679f95c82SChris Mason * then try to empty the right most buffer into the middle 52779f95c82SChris Mason */ 528bb803951SChris Mason if (right_buf) { 52954aa1f4dSChris Mason wret = btrfs_cow_block(trans, root, right_buf, 53054aa1f4dSChris Mason parent_buf, pslot + 1, &right_buf); 53154aa1f4dSChris Mason if (wret) { 53254aa1f4dSChris Mason ret = wret; 53354aa1f4dSChris Mason goto enospc; 53454aa1f4dSChris Mason } 53554aa1f4dSChris Mason 536e20d96d6SChris Mason right = btrfs_buffer_node(right_buf); 537e089f05cSChris Mason wret = push_node_left(trans, root, mid_buf, right_buf); 53854aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 53979f95c82SChris Mason ret = wret; 5407518a238SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 5417eccb903SChris Mason u64 blocknr = bh_blocknr(right_buf); 542e089f05cSChris Mason clean_tree_block(trans, root, right_buf); 543d6025579SChris Mason wait_on_buffer(right_buf); 544d6025579SChris Mason btrfs_block_release(root, right_buf); 545bb803951SChris Mason right_buf = NULL; 546bb803951SChris Mason right = NULL; 547e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot + 548e089f05cSChris Mason 1); 549bb803951SChris Mason if (wret) 550bb803951SChris Mason ret = wret; 551e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 552bb803951SChris Mason if (wret) 553bb803951SChris Mason ret = wret; 554bb803951SChris Mason } else { 555d6025579SChris Mason btrfs_memcpy(root, parent, 556d6025579SChris Mason &parent->ptrs[pslot + 1].key, 557123abc88SChris Mason &right->ptrs[0].key, 558e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 559d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 560bb803951SChris Mason } 561bb803951SChris Mason } 5627518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 1) { 56379f95c82SChris Mason /* 56479f95c82SChris Mason * we're not allowed to leave a node with one item in the 56579f95c82SChris Mason * tree during a delete. A deletion from lower in the tree 56679f95c82SChris Mason * could try to delete the only pointer in this node. 56779f95c82SChris Mason * So, pull some keys from the left. 56879f95c82SChris Mason * There has to be a left pointer at this point because 56979f95c82SChris Mason * otherwise we would have pulled some pointers from the 57079f95c82SChris Mason * right 57179f95c82SChris Mason */ 57279f95c82SChris Mason BUG_ON(!left_buf); 573e089f05cSChris Mason wret = balance_node_right(trans, root, mid_buf, left_buf); 57454aa1f4dSChris Mason if (wret < 0) { 57579f95c82SChris Mason ret = wret; 57654aa1f4dSChris Mason goto enospc; 57754aa1f4dSChris Mason } 57879f95c82SChris Mason BUG_ON(wret == 1); 57979f95c82SChris Mason } 5807518a238SChris Mason if (btrfs_header_nritems(&mid->header) == 0) { 58179f95c82SChris Mason /* we've managed to empty the middle node, drop it */ 5827eccb903SChris Mason u64 blocknr = bh_blocknr(mid_buf); 583e089f05cSChris Mason clean_tree_block(trans, root, mid_buf); 584d6025579SChris Mason wait_on_buffer(mid_buf); 585d6025579SChris Mason btrfs_block_release(root, mid_buf); 586bb803951SChris Mason mid_buf = NULL; 587bb803951SChris Mason mid = NULL; 588e089f05cSChris Mason wret = del_ptr(trans, root, path, level + 1, pslot); 589bb803951SChris Mason if (wret) 590bb803951SChris Mason ret = wret; 591e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 1, 1); 592bb803951SChris Mason if (wret) 593bb803951SChris Mason ret = wret; 59479f95c82SChris Mason } else { 59579f95c82SChris Mason /* update the parent key to reflect our changes */ 596d6025579SChris Mason btrfs_memcpy(root, parent, 597d6025579SChris Mason &parent->ptrs[pslot].key, &mid->ptrs[0].key, 598e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 599d6025579SChris Mason btrfs_mark_buffer_dirty(parent_buf); 60079f95c82SChris Mason } 601bb803951SChris Mason 60279f95c82SChris Mason /* update the path */ 603bb803951SChris Mason if (left_buf) { 6047518a238SChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 605e20d96d6SChris Mason get_bh(left_buf); 606bb803951SChris Mason path->nodes[level] = left_buf; 607bb803951SChris Mason path->slots[level + 1] -= 1; 608bb803951SChris Mason path->slots[level] = orig_slot; 609bb803951SChris Mason if (mid_buf) 610234b63a0SChris Mason btrfs_block_release(root, mid_buf); 611bb803951SChris Mason } else { 6127518a238SChris Mason orig_slot -= btrfs_header_nritems(&left->header); 613bb803951SChris Mason path->slots[level] = orig_slot; 614bb803951SChris Mason } 615bb803951SChris Mason } 61679f95c82SChris Mason /* double check we haven't messed things up */ 617123abc88SChris Mason check_block(root, path, level); 618e20d96d6SChris Mason if (orig_ptr != 619e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 6201d4f8a0cSChris Mason path->slots[level])) 62179f95c82SChris Mason BUG(); 62254aa1f4dSChris Mason enospc: 623bb803951SChris Mason if (right_buf) 624234b63a0SChris Mason btrfs_block_release(root, right_buf); 625bb803951SChris Mason if (left_buf) 626234b63a0SChris Mason btrfs_block_release(root, left_buf); 627bb803951SChris Mason return ret; 628bb803951SChris Mason } 629bb803951SChris Mason 630e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */ 631e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans, 632e66f709bSChris Mason struct btrfs_root *root, 633e66f709bSChris Mason struct btrfs_path *path, int level) 634e66f709bSChris Mason { 635e66f709bSChris Mason struct buffer_head *right_buf; 636e66f709bSChris Mason struct buffer_head *mid_buf; 637e66f709bSChris Mason struct buffer_head *left_buf; 638e66f709bSChris Mason struct buffer_head *parent_buf = NULL; 639e66f709bSChris Mason struct btrfs_node *right = NULL; 640e66f709bSChris Mason struct btrfs_node *mid; 641e66f709bSChris Mason struct btrfs_node *left = NULL; 642e66f709bSChris Mason struct btrfs_node *parent = NULL; 643e66f709bSChris Mason int ret = 0; 644e66f709bSChris Mason int wret; 645e66f709bSChris Mason int pslot; 646e66f709bSChris Mason int orig_slot = path->slots[level]; 647e66f709bSChris Mason u64 orig_ptr; 648e66f709bSChris Mason 649e66f709bSChris Mason if (level == 0) 650e66f709bSChris Mason return 1; 651e66f709bSChris Mason 652e66f709bSChris Mason mid_buf = path->nodes[level]; 653e66f709bSChris Mason mid = btrfs_buffer_node(mid_buf); 654e66f709bSChris Mason orig_ptr = btrfs_node_blockptr(mid, orig_slot); 655e66f709bSChris Mason 656e66f709bSChris Mason if (level < BTRFS_MAX_LEVEL - 1) 657e66f709bSChris Mason parent_buf = path->nodes[level + 1]; 658e66f709bSChris Mason pslot = path->slots[level + 1]; 659e66f709bSChris Mason 660e66f709bSChris Mason if (!parent_buf) 661e66f709bSChris Mason return 1; 662e66f709bSChris Mason parent = btrfs_buffer_node(parent_buf); 663e66f709bSChris Mason 664e66f709bSChris Mason left_buf = read_node_slot(root, parent_buf, pslot - 1); 665e66f709bSChris Mason 666e66f709bSChris Mason /* first, try to make some room in the middle buffer */ 667e66f709bSChris Mason if (left_buf) { 668e66f709bSChris Mason u32 left_nr; 669e66f709bSChris Mason left = btrfs_buffer_node(left_buf); 670e66f709bSChris Mason left_nr = btrfs_header_nritems(&left->header); 67133ade1f8SChris Mason if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 67233ade1f8SChris Mason wret = 1; 67333ade1f8SChris Mason } else { 67454aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, left_buf, parent_buf, 67533ade1f8SChris Mason pslot - 1, &left_buf); 67654aa1f4dSChris Mason if (ret) 67754aa1f4dSChris Mason wret = 1; 67854aa1f4dSChris Mason else { 67933ade1f8SChris Mason left = btrfs_buffer_node(left_buf); 68054aa1f4dSChris Mason wret = push_node_left(trans, root, 68154aa1f4dSChris Mason left_buf, mid_buf); 68254aa1f4dSChris Mason } 68333ade1f8SChris Mason } 684e66f709bSChris Mason if (wret < 0) 685e66f709bSChris Mason ret = wret; 686e66f709bSChris Mason if (wret == 0) { 687e66f709bSChris Mason orig_slot += left_nr; 688e66f709bSChris Mason btrfs_memcpy(root, parent, 689e66f709bSChris Mason &parent->ptrs[pslot].key, 690e66f709bSChris Mason &mid->ptrs[0].key, 691e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 692e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 693e66f709bSChris Mason if (btrfs_header_nritems(&left->header) > orig_slot) { 694e66f709bSChris Mason path->nodes[level] = left_buf; 695e66f709bSChris Mason path->slots[level + 1] -= 1; 696e66f709bSChris Mason path->slots[level] = orig_slot; 697e66f709bSChris Mason btrfs_block_release(root, mid_buf); 698e66f709bSChris Mason } else { 699e66f709bSChris Mason orig_slot -= 700e66f709bSChris Mason btrfs_header_nritems(&left->header); 701e66f709bSChris Mason path->slots[level] = orig_slot; 702e66f709bSChris Mason btrfs_block_release(root, left_buf); 703e66f709bSChris Mason } 704e66f709bSChris Mason check_node(root, path, level); 705e66f709bSChris Mason return 0; 706e66f709bSChris Mason } 707e66f709bSChris Mason btrfs_block_release(root, left_buf); 708e66f709bSChris Mason } 709e66f709bSChris Mason right_buf = read_node_slot(root, parent_buf, pslot + 1); 710e66f709bSChris Mason 711e66f709bSChris Mason /* 712e66f709bSChris Mason * then try to empty the right most buffer into the middle 713e66f709bSChris Mason */ 714e66f709bSChris Mason if (right_buf) { 71533ade1f8SChris Mason u32 right_nr; 716e66f709bSChris Mason right = btrfs_buffer_node(right_buf); 71733ade1f8SChris Mason right_nr = btrfs_header_nritems(&right->header); 71833ade1f8SChris Mason if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 71933ade1f8SChris Mason wret = 1; 72033ade1f8SChris Mason } else { 72154aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, 72254aa1f4dSChris Mason parent_buf, pslot + 1, 72354aa1f4dSChris Mason &right_buf); 72454aa1f4dSChris Mason if (ret) 72554aa1f4dSChris Mason wret = 1; 72654aa1f4dSChris Mason else { 72733ade1f8SChris Mason right = btrfs_buffer_node(right_buf); 72833ade1f8SChris Mason wret = balance_node_right(trans, root, 72933ade1f8SChris Mason right_buf, mid_buf); 73033ade1f8SChris Mason } 73154aa1f4dSChris Mason } 732e66f709bSChris Mason if (wret < 0) 733e66f709bSChris Mason ret = wret; 734e66f709bSChris Mason if (wret == 0) { 735e66f709bSChris Mason btrfs_memcpy(root, parent, 736e66f709bSChris Mason &parent->ptrs[pslot + 1].key, 737e66f709bSChris Mason &right->ptrs[0].key, 738e66f709bSChris Mason sizeof(struct btrfs_disk_key)); 739e66f709bSChris Mason btrfs_mark_buffer_dirty(parent_buf); 740e66f709bSChris Mason if (btrfs_header_nritems(&mid->header) <= orig_slot) { 741e66f709bSChris Mason path->nodes[level] = right_buf; 742e66f709bSChris Mason path->slots[level + 1] += 1; 743e66f709bSChris Mason path->slots[level] = orig_slot - 744e66f709bSChris Mason btrfs_header_nritems(&mid->header); 745e66f709bSChris Mason btrfs_block_release(root, mid_buf); 746e66f709bSChris Mason } else { 747e66f709bSChris Mason btrfs_block_release(root, right_buf); 748e66f709bSChris Mason } 749e66f709bSChris Mason check_node(root, path, level); 750e66f709bSChris Mason return 0; 751e66f709bSChris Mason } 752e66f709bSChris Mason btrfs_block_release(root, right_buf); 753e66f709bSChris Mason } 754e66f709bSChris Mason check_node(root, path, level); 755e66f709bSChris Mason return 1; 756e66f709bSChris Mason } 757e66f709bSChris Mason 75874123bd7SChris Mason /* 7593c69faecSChris Mason * readahead one full node of leaves 7603c69faecSChris Mason */ 7613c69faecSChris Mason static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, 7626702ed49SChris Mason int level, int slot) 7633c69faecSChris Mason { 7643c69faecSChris Mason struct btrfs_node *node; 7653c69faecSChris Mason int i; 7663c69faecSChris Mason u32 nritems; 7673c69faecSChris Mason u64 item_objectid; 7683c69faecSChris Mason u64 blocknr; 7693c69faecSChris Mason u64 search; 7703c69faecSChris Mason u64 cluster_start; 7713c69faecSChris Mason int ret; 7723c69faecSChris Mason int nread = 0; 7733c69faecSChris Mason int direction = path->reada; 7743c69faecSChris Mason struct radix_tree_root found; 7753c69faecSChris Mason unsigned long gang[8]; 7763c69faecSChris Mason struct buffer_head *bh; 7773c69faecSChris Mason 7786702ed49SChris Mason if (level == 0) 7793c69faecSChris Mason return; 7803c69faecSChris Mason 7816702ed49SChris Mason if (!path->nodes[level]) 7826702ed49SChris Mason return; 7836702ed49SChris Mason 7846702ed49SChris Mason node = btrfs_buffer_node(path->nodes[level]); 7853c69faecSChris Mason search = btrfs_node_blockptr(node, slot); 7863c69faecSChris Mason bh = btrfs_find_tree_block(root, search); 7873c69faecSChris Mason if (bh) { 7883c69faecSChris Mason brelse(bh); 7893c69faecSChris Mason return; 7903c69faecSChris Mason } 7913c69faecSChris Mason 7923c69faecSChris Mason init_bit_radix(&found); 7933c69faecSChris Mason nritems = btrfs_header_nritems(&node->header); 7943c69faecSChris Mason for (i = slot; i < nritems; i++) { 7953c69faecSChris Mason item_objectid = btrfs_disk_key_objectid(&node->ptrs[i].key); 7963c69faecSChris Mason blocknr = btrfs_node_blockptr(node, i); 7973c69faecSChris Mason set_radix_bit(&found, blocknr); 7983c69faecSChris Mason } 7993c69faecSChris Mason if (direction > 0) { 8003c69faecSChris Mason cluster_start = search - 4; 8013c69faecSChris Mason if (cluster_start > search) 8023c69faecSChris Mason cluster_start = 0; 8033c69faecSChris Mason } else 8043c69faecSChris Mason cluster_start = search + 4; 8053c69faecSChris Mason while(1) { 8063c69faecSChris Mason ret = find_first_radix_bit(&found, gang, 0, ARRAY_SIZE(gang)); 8073c69faecSChris Mason if (!ret) 8083c69faecSChris Mason break; 8093c69faecSChris Mason for (i = 0; i < ret; i++) { 8103c69faecSChris Mason blocknr = gang[i]; 8113c69faecSChris Mason clear_radix_bit(&found, blocknr); 8126702ed49SChris Mason if (nread > 32) 8133c69faecSChris Mason continue; 8143c69faecSChris Mason if (direction > 0 && cluster_start <= blocknr && 8153c69faecSChris Mason cluster_start + 8 > blocknr) { 8163c69faecSChris Mason cluster_start = blocknr; 8173c69faecSChris Mason readahead_tree_block(root, blocknr); 8183c69faecSChris Mason nread++; 8193c69faecSChris Mason } else if (direction < 0 && cluster_start >= blocknr && 8203c69faecSChris Mason blocknr + 8 > cluster_start) { 8213c69faecSChris Mason cluster_start = blocknr; 8223c69faecSChris Mason readahead_tree_block(root, blocknr); 8233c69faecSChris Mason nread++; 8243c69faecSChris Mason } 8253c69faecSChris Mason } 8263c69faecSChris Mason } 8273c69faecSChris Mason } 8283c69faecSChris Mason /* 82974123bd7SChris Mason * look for key in the tree. path is filled in with nodes along the way 83074123bd7SChris Mason * if key is found, we return zero and you can find the item in the leaf 83174123bd7SChris Mason * level of the path (level 0) 83274123bd7SChris Mason * 83374123bd7SChris Mason * If the key isn't found, the path points to the slot where it should 834aa5d6bedSChris Mason * be inserted, and 1 is returned. If there are other errors during the 835aa5d6bedSChris Mason * search a negative error number is returned. 83697571fd0SChris Mason * 83797571fd0SChris Mason * if ins_len > 0, nodes and leaves will be split as we walk down the 83897571fd0SChris Mason * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 83997571fd0SChris Mason * possible) 84074123bd7SChris Mason */ 841e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 842e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_path *p, int 843e089f05cSChris Mason ins_len, int cow) 844be0e5c09SChris Mason { 845e20d96d6SChris Mason struct buffer_head *b; 846e20d96d6SChris Mason struct buffer_head *cow_buf; 847234b63a0SChris Mason struct btrfs_node *c; 8483c69faecSChris Mason u64 blocknr; 849be0e5c09SChris Mason int slot; 850be0e5c09SChris Mason int ret; 851be0e5c09SChris Mason int level; 8523c69faecSChris Mason int should_reada = p->reada; 8539f3a7427SChris Mason u8 lowest_level = 0; 8549f3a7427SChris Mason 8556702ed49SChris Mason lowest_level = p->lowest_level; 8566702ed49SChris Mason WARN_ON(lowest_level && ins_len); 85722b0ebdaSChris Mason WARN_ON(p->nodes[0] != NULL); 85822b0ebdaSChris Mason WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); 859bb803951SChris Mason again: 860bb803951SChris Mason b = root->node; 861e20d96d6SChris Mason get_bh(b); 862eb60ceacSChris Mason while (b) { 863e20d96d6SChris Mason c = btrfs_buffer_node(b); 864e20d96d6SChris Mason level = btrfs_header_level(&c->header); 86502217ed2SChris Mason if (cow) { 86602217ed2SChris Mason int wret; 867e20d96d6SChris Mason wret = btrfs_cow_block(trans, root, b, 868e20d96d6SChris Mason p->nodes[level + 1], 869e20d96d6SChris Mason p->slots[level + 1], 870e089f05cSChris Mason &cow_buf); 87154aa1f4dSChris Mason if (wret) { 87254aa1f4dSChris Mason btrfs_block_release(root, cow_buf); 87354aa1f4dSChris Mason return wret; 87454aa1f4dSChris Mason } 87502217ed2SChris Mason b = cow_buf; 8762c90e5d6SChris Mason c = btrfs_buffer_node(b); 87702217ed2SChris Mason } 87802217ed2SChris Mason BUG_ON(!cow && ins_len); 8792c90e5d6SChris Mason if (level != btrfs_header_level(&c->header)) 8802c90e5d6SChris Mason WARN_ON(1); 8812c90e5d6SChris Mason level = btrfs_header_level(&c->header); 882eb60ceacSChris Mason p->nodes[level] = b; 883123abc88SChris Mason ret = check_block(root, p, level); 884aa5d6bedSChris Mason if (ret) 885aa5d6bedSChris Mason return -1; 886be0e5c09SChris Mason ret = bin_search(c, key, &slot); 8877518a238SChris Mason if (!btrfs_is_leaf(c)) { 888be0e5c09SChris Mason if (ret && slot > 0) 889be0e5c09SChris Mason slot -= 1; 890be0e5c09SChris Mason p->slots[level] = slot; 891d4dbff95SChris Mason if (ins_len > 0 && btrfs_header_nritems(&c->header) >= 892d4dbff95SChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 893e089f05cSChris Mason int sret = split_node(trans, root, p, level); 8945c680ed6SChris Mason BUG_ON(sret > 0); 8955c680ed6SChris Mason if (sret) 8965c680ed6SChris Mason return sret; 8975c680ed6SChris Mason b = p->nodes[level]; 898e20d96d6SChris Mason c = btrfs_buffer_node(b); 8995c680ed6SChris Mason slot = p->slots[level]; 900bb803951SChris Mason } else if (ins_len < 0) { 901e089f05cSChris Mason int sret = balance_level(trans, root, p, 902e089f05cSChris Mason level); 903bb803951SChris Mason if (sret) 904bb803951SChris Mason return sret; 905bb803951SChris Mason b = p->nodes[level]; 906bb803951SChris Mason if (!b) 907bb803951SChris Mason goto again; 908e20d96d6SChris Mason c = btrfs_buffer_node(b); 909bb803951SChris Mason slot = p->slots[level]; 9107518a238SChris Mason BUG_ON(btrfs_header_nritems(&c->header) == 1); 9115c680ed6SChris Mason } 9129f3a7427SChris Mason /* this is only true while dropping a snapshot */ 9139f3a7427SChris Mason if (level == lowest_level) 9149f3a7427SChris Mason break; 9153c69faecSChris Mason blocknr = btrfs_node_blockptr(c, slot); 9166702ed49SChris Mason if (should_reada) 9176702ed49SChris Mason reada_for_search(root, p, level, slot); 9181d4f8a0cSChris Mason b = read_tree_block(root, btrfs_node_blockptr(c, slot)); 9193c69faecSChris Mason 920be0e5c09SChris Mason } else { 921234b63a0SChris Mason struct btrfs_leaf *l = (struct btrfs_leaf *)c; 922be0e5c09SChris Mason p->slots[level] = slot; 923123abc88SChris Mason if (ins_len > 0 && btrfs_leaf_free_space(root, l) < 9240783fcfcSChris Mason sizeof(struct btrfs_item) + ins_len) { 925d4dbff95SChris Mason int sret = split_leaf(trans, root, key, 926d4dbff95SChris Mason p, ins_len); 9275c680ed6SChris Mason BUG_ON(sret > 0); 9285c680ed6SChris Mason if (sret) 9295c680ed6SChris Mason return sret; 9305c680ed6SChris Mason } 931be0e5c09SChris Mason return ret; 932be0e5c09SChris Mason } 933be0e5c09SChris Mason } 934aa5d6bedSChris Mason return 1; 935be0e5c09SChris Mason } 936be0e5c09SChris Mason 93774123bd7SChris Mason /* 93874123bd7SChris Mason * adjust the pointers going up the tree, starting at level 93974123bd7SChris Mason * making sure the right key of each node is points to 'key'. 94074123bd7SChris Mason * This is used after shifting pointers to the left, so it stops 94174123bd7SChris Mason * fixing up pointers when a given leaf/node is not in slot 0 of the 94274123bd7SChris Mason * higher levels 943aa5d6bedSChris Mason * 944aa5d6bedSChris Mason * If this fails to write a tree block, it returns -1, but continues 945aa5d6bedSChris Mason * fixing up the blocks in ram so the tree is consistent. 94674123bd7SChris Mason */ 947e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root 948e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 949e089f05cSChris Mason *key, int level) 950be0e5c09SChris Mason { 951be0e5c09SChris Mason int i; 952aa5d6bedSChris Mason int ret = 0; 953234b63a0SChris Mason for (i = level; i < BTRFS_MAX_LEVEL; i++) { 954234b63a0SChris Mason struct btrfs_node *t; 955be0e5c09SChris Mason int tslot = path->slots[i]; 956eb60ceacSChris Mason if (!path->nodes[i]) 957be0e5c09SChris Mason break; 958e20d96d6SChris Mason t = btrfs_buffer_node(path->nodes[i]); 959d6025579SChris Mason btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); 960d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[i]); 961be0e5c09SChris Mason if (tslot != 0) 962be0e5c09SChris Mason break; 963be0e5c09SChris Mason } 964aa5d6bedSChris Mason return ret; 965be0e5c09SChris Mason } 966be0e5c09SChris Mason 96774123bd7SChris Mason /* 96874123bd7SChris Mason * try to push data from one node into the next node left in the 96979f95c82SChris Mason * tree. 970aa5d6bedSChris Mason * 971aa5d6bedSChris Mason * returns 0 if some ptrs were pushed left, < 0 if there was some horrible 972aa5d6bedSChris Mason * error, and > 0 if there was no room in the left hand block. 97374123bd7SChris Mason */ 974e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 975e20d96d6SChris Mason *root, struct buffer_head *dst_buf, struct 976e20d96d6SChris Mason buffer_head *src_buf) 977be0e5c09SChris Mason { 978e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 979e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 980be0e5c09SChris Mason int push_items = 0; 981bb803951SChris Mason int src_nritems; 982bb803951SChris Mason int dst_nritems; 983aa5d6bedSChris Mason int ret = 0; 984be0e5c09SChris Mason 9857518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 9867518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 987123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 98854aa1f4dSChris Mason 989eb60ceacSChris Mason if (push_items <= 0) { 990be0e5c09SChris Mason return 1; 991eb60ceacSChris Mason } 992be0e5c09SChris Mason 993be0e5c09SChris Mason if (src_nritems < push_items) 994be0e5c09SChris Mason push_items = src_nritems; 99579f95c82SChris Mason 996d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, 997123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 998bb803951SChris Mason if (push_items < src_nritems) { 999d6025579SChris Mason btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, 1000e2fa7227SChris Mason (src_nritems - push_items) * 1001123abc88SChris Mason sizeof(struct btrfs_key_ptr)); 1002bb803951SChris Mason } 10037518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 10047518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 1005d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 1006d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 1007bb803951SChris Mason return ret; 1008be0e5c09SChris Mason } 1009be0e5c09SChris Mason 101097571fd0SChris Mason /* 101179f95c82SChris Mason * try to push data from one node into the next node right in the 101279f95c82SChris Mason * tree. 101379f95c82SChris Mason * 101479f95c82SChris Mason * returns 0 if some ptrs were pushed, < 0 if there was some horrible 101579f95c82SChris Mason * error, and > 0 if there was no room in the right hand block. 101679f95c82SChris Mason * 101779f95c82SChris Mason * this will only push up to 1/2 the contents of the left node over 101879f95c82SChris Mason */ 1019e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct 1020e20d96d6SChris Mason btrfs_root *root, struct buffer_head *dst_buf, 1021e20d96d6SChris Mason struct buffer_head *src_buf) 102279f95c82SChris Mason { 1023e20d96d6SChris Mason struct btrfs_node *src = btrfs_buffer_node(src_buf); 1024e20d96d6SChris Mason struct btrfs_node *dst = btrfs_buffer_node(dst_buf); 102579f95c82SChris Mason int push_items = 0; 102679f95c82SChris Mason int max_push; 102779f95c82SChris Mason int src_nritems; 102879f95c82SChris Mason int dst_nritems; 102979f95c82SChris Mason int ret = 0; 103079f95c82SChris Mason 10317518a238SChris Mason src_nritems = btrfs_header_nritems(&src->header); 10327518a238SChris Mason dst_nritems = btrfs_header_nritems(&dst->header); 1033123abc88SChris Mason push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 103479f95c82SChris Mason if (push_items <= 0) { 103579f95c82SChris Mason return 1; 103679f95c82SChris Mason } 103779f95c82SChris Mason 103879f95c82SChris Mason max_push = src_nritems / 2 + 1; 103979f95c82SChris Mason /* don't try to empty the node */ 104079f95c82SChris Mason if (max_push > src_nritems) 104179f95c82SChris Mason return 1; 104279f95c82SChris Mason if (max_push < push_items) 104379f95c82SChris Mason push_items = max_push; 104479f95c82SChris Mason 1045d6025579SChris Mason btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, 1046123abc88SChris Mason dst_nritems * sizeof(struct btrfs_key_ptr)); 1047d6025579SChris Mason 1048d6025579SChris Mason btrfs_memcpy(root, dst, dst->ptrs, 1049d6025579SChris Mason src->ptrs + src_nritems - push_items, 1050123abc88SChris Mason push_items * sizeof(struct btrfs_key_ptr)); 105179f95c82SChris Mason 10527518a238SChris Mason btrfs_set_header_nritems(&src->header, src_nritems - push_items); 10537518a238SChris Mason btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 105479f95c82SChris Mason 1055d6025579SChris Mason btrfs_mark_buffer_dirty(src_buf); 1056d6025579SChris Mason btrfs_mark_buffer_dirty(dst_buf); 105779f95c82SChris Mason return ret; 105879f95c82SChris Mason } 105979f95c82SChris Mason 106079f95c82SChris Mason /* 106197571fd0SChris Mason * helper function to insert a new root level in the tree. 106297571fd0SChris Mason * A new node is allocated, and a single item is inserted to 106397571fd0SChris Mason * point to the existing root 1064aa5d6bedSChris Mason * 1065aa5d6bedSChris Mason * returns zero on success or < 0 on failure. 106697571fd0SChris Mason */ 1067e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 1068e089f05cSChris Mason *root, struct btrfs_path *path, int level) 106974123bd7SChris Mason { 1070e20d96d6SChris Mason struct buffer_head *t; 1071234b63a0SChris Mason struct btrfs_node *lower; 1072234b63a0SChris Mason struct btrfs_node *c; 1073e2fa7227SChris Mason struct btrfs_disk_key *lower_key; 10745c680ed6SChris Mason 10755c680ed6SChris Mason BUG_ON(path->nodes[level]); 10765c680ed6SChris Mason BUG_ON(path->nodes[level-1] != root->node); 10775c680ed6SChris Mason 10786702ed49SChris Mason t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr, 0); 107954aa1f4dSChris Mason if (IS_ERR(t)) 108054aa1f4dSChris Mason return PTR_ERR(t); 1081e20d96d6SChris Mason c = btrfs_buffer_node(t); 1082123abc88SChris Mason memset(c, 0, root->blocksize); 10837518a238SChris Mason btrfs_set_header_nritems(&c->header, 1); 10847518a238SChris Mason btrfs_set_header_level(&c->header, level); 10857eccb903SChris Mason btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); 10867f5c1516SChris Mason btrfs_set_header_generation(&c->header, trans->transid); 10874d775673SChris Mason btrfs_set_header_owner(&c->header, root->root_key.objectid); 1088e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level-1]); 10893eb0314dSChris Mason memcpy(c->header.fsid, root->fs_info->disk_super->fsid, 10903eb0314dSChris Mason sizeof(c->header.fsid)); 10917518a238SChris Mason if (btrfs_is_leaf(lower)) 1092234b63a0SChris Mason lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 109374123bd7SChris Mason else 1094123abc88SChris Mason lower_key = &lower->ptrs[0].key; 1095d6025579SChris Mason btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, 1096d6025579SChris Mason sizeof(struct btrfs_disk_key)); 10977eccb903SChris Mason btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); 1098d5719762SChris Mason 1099d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1100d5719762SChris Mason 1101cfaa7295SChris Mason /* the super has an extra ref to root->node */ 1102234b63a0SChris Mason btrfs_block_release(root, root->node); 110374123bd7SChris Mason root->node = t; 1104e20d96d6SChris Mason get_bh(t); 110574123bd7SChris Mason path->nodes[level] = t; 110674123bd7SChris Mason path->slots[level] = 0; 110774123bd7SChris Mason return 0; 110874123bd7SChris Mason } 11095c680ed6SChris Mason 11105c680ed6SChris Mason /* 11115c680ed6SChris Mason * worker function to insert a single pointer in a node. 11125c680ed6SChris Mason * the node should have enough room for the pointer already 111397571fd0SChris Mason * 11145c680ed6SChris Mason * slot and level indicate where you want the key to go, and 11155c680ed6SChris Mason * blocknr is the block the key points to. 1116aa5d6bedSChris Mason * 1117aa5d6bedSChris Mason * returns zero on success and < 0 on any error 11185c680ed6SChris Mason */ 1119e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root 1120e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_disk_key 1121e089f05cSChris Mason *key, u64 blocknr, int slot, int level) 11225c680ed6SChris Mason { 1123234b63a0SChris Mason struct btrfs_node *lower; 11245c680ed6SChris Mason int nritems; 11255c680ed6SChris Mason 11265c680ed6SChris Mason BUG_ON(!path->nodes[level]); 1127e20d96d6SChris Mason lower = btrfs_buffer_node(path->nodes[level]); 11287518a238SChris Mason nritems = btrfs_header_nritems(&lower->header); 112974123bd7SChris Mason if (slot > nritems) 113074123bd7SChris Mason BUG(); 1131123abc88SChris Mason if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) 113274123bd7SChris Mason BUG(); 113374123bd7SChris Mason if (slot != nritems) { 1134d6025579SChris Mason btrfs_memmove(root, lower, lower->ptrs + slot + 1, 1135d6025579SChris Mason lower->ptrs + slot, 1136123abc88SChris Mason (nritems - slot) * sizeof(struct btrfs_key_ptr)); 113774123bd7SChris Mason } 1138d6025579SChris Mason btrfs_memcpy(root, lower, &lower->ptrs[slot].key, 1139d6025579SChris Mason key, sizeof(struct btrfs_disk_key)); 11401d4f8a0cSChris Mason btrfs_set_node_blockptr(lower, slot, blocknr); 11417518a238SChris Mason btrfs_set_header_nritems(&lower->header, nritems + 1); 1142d6025579SChris Mason btrfs_mark_buffer_dirty(path->nodes[level]); 1143098f59c2SChris Mason check_node(root, path, level); 114474123bd7SChris Mason return 0; 114574123bd7SChris Mason } 114674123bd7SChris Mason 114797571fd0SChris Mason /* 114897571fd0SChris Mason * split the node at the specified level in path in two. 114997571fd0SChris Mason * The path is corrected to point to the appropriate node after the split 115097571fd0SChris Mason * 115197571fd0SChris Mason * Before splitting this tries to make some room in the node by pushing 115297571fd0SChris Mason * left and right, if either one works, it returns right away. 1153aa5d6bedSChris Mason * 1154aa5d6bedSChris Mason * returns 0 on success and < 0 on failure 115597571fd0SChris Mason */ 1156e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 1157e089f05cSChris Mason *root, struct btrfs_path *path, int level) 1158be0e5c09SChris Mason { 1159e20d96d6SChris Mason struct buffer_head *t; 1160234b63a0SChris Mason struct btrfs_node *c; 1161e20d96d6SChris Mason struct buffer_head *split_buffer; 1162234b63a0SChris Mason struct btrfs_node *split; 1163be0e5c09SChris Mason int mid; 11645c680ed6SChris Mason int ret; 1165aa5d6bedSChris Mason int wret; 11667518a238SChris Mason u32 c_nritems; 1167be0e5c09SChris Mason 11685c680ed6SChris Mason t = path->nodes[level]; 1169e20d96d6SChris Mason c = btrfs_buffer_node(t); 11705c680ed6SChris Mason if (t == root->node) { 11715c680ed6SChris Mason /* trying to split the root, lets make a new one */ 1172e089f05cSChris Mason ret = insert_new_root(trans, root, path, level + 1); 11735c680ed6SChris Mason if (ret) 11745c680ed6SChris Mason return ret; 1175e66f709bSChris Mason } else { 1176e66f709bSChris Mason ret = push_nodes_for_insert(trans, root, path, level); 1177e66f709bSChris Mason t = path->nodes[level]; 1178e66f709bSChris Mason c = btrfs_buffer_node(t); 1179e66f709bSChris Mason if (!ret && 1180e66f709bSChris Mason btrfs_header_nritems(&c->header) < 1181e66f709bSChris Mason BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 1182e66f709bSChris Mason return 0; 118354aa1f4dSChris Mason if (ret < 0) 118454aa1f4dSChris Mason return ret; 11855c680ed6SChris Mason } 1186e66f709bSChris Mason 11877518a238SChris Mason c_nritems = btrfs_header_nritems(&c->header); 11886702ed49SChris Mason split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr, 0); 118954aa1f4dSChris Mason if (IS_ERR(split_buffer)) 119054aa1f4dSChris Mason return PTR_ERR(split_buffer); 119154aa1f4dSChris Mason 1192e20d96d6SChris Mason split = btrfs_buffer_node(split_buffer); 11937518a238SChris Mason btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 11949a6f11edSChris Mason btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 11957eccb903SChris Mason btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); 11967f5c1516SChris Mason btrfs_set_header_generation(&split->header, trans->transid); 11974d775673SChris Mason btrfs_set_header_owner(&split->header, root->root_key.objectid); 11983eb0314dSChris Mason memcpy(split->header.fsid, root->fs_info->disk_super->fsid, 11993eb0314dSChris Mason sizeof(split->header.fsid)); 12007518a238SChris Mason mid = (c_nritems + 1) / 2; 1201d6025579SChris Mason btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, 1202123abc88SChris Mason (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 12037518a238SChris Mason btrfs_set_header_nritems(&split->header, c_nritems - mid); 12047518a238SChris Mason btrfs_set_header_nritems(&c->header, mid); 1205aa5d6bedSChris Mason ret = 0; 1206aa5d6bedSChris Mason 1207d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1208d6025579SChris Mason btrfs_mark_buffer_dirty(split_buffer); 1209e089f05cSChris Mason wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 12107eccb903SChris Mason bh_blocknr(split_buffer), path->slots[level + 1] + 1, 1211123abc88SChris Mason level + 1); 1212aa5d6bedSChris Mason if (wret) 1213aa5d6bedSChris Mason ret = wret; 1214aa5d6bedSChris Mason 12155de08d7dSChris Mason if (path->slots[level] >= mid) { 12165c680ed6SChris Mason path->slots[level] -= mid; 1217234b63a0SChris Mason btrfs_block_release(root, t); 12185c680ed6SChris Mason path->nodes[level] = split_buffer; 12195c680ed6SChris Mason path->slots[level + 1] += 1; 1220eb60ceacSChris Mason } else { 1221234b63a0SChris Mason btrfs_block_release(root, split_buffer); 1222be0e5c09SChris Mason } 1223aa5d6bedSChris Mason return ret; 1224be0e5c09SChris Mason } 1225be0e5c09SChris Mason 122674123bd7SChris Mason /* 122774123bd7SChris Mason * how many bytes are required to store the items in a leaf. start 122874123bd7SChris Mason * and nr indicate which items in the leaf to check. This totals up the 122974123bd7SChris Mason * space used both by the item structs and the item data 123074123bd7SChris Mason */ 1231234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) 1232be0e5c09SChris Mason { 1233be0e5c09SChris Mason int data_len; 1234d4dbff95SChris Mason int nritems = btrfs_header_nritems(&l->header); 1235d4dbff95SChris Mason int end = min(nritems, start + nr) - 1; 1236be0e5c09SChris Mason 1237be0e5c09SChris Mason if (!nr) 1238be0e5c09SChris Mason return 0; 12390783fcfcSChris Mason data_len = btrfs_item_end(l->items + start); 12400783fcfcSChris Mason data_len = data_len - btrfs_item_offset(l->items + end); 12410783fcfcSChris Mason data_len += sizeof(struct btrfs_item) * nr; 1242d4dbff95SChris Mason WARN_ON(data_len < 0); 1243be0e5c09SChris Mason return data_len; 1244be0e5c09SChris Mason } 1245be0e5c09SChris Mason 124674123bd7SChris Mason /* 1247d4dbff95SChris Mason * The space between the end of the leaf items and 1248d4dbff95SChris Mason * the start of the leaf data. IOW, how much room 1249d4dbff95SChris Mason * the leaf has left for both items and data 1250d4dbff95SChris Mason */ 1251d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) 1252d4dbff95SChris Mason { 1253d4dbff95SChris Mason int nritems = btrfs_header_nritems(&leaf->header); 1254d4dbff95SChris Mason return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); 1255d4dbff95SChris Mason } 1256d4dbff95SChris Mason 1257d4dbff95SChris Mason /* 125800ec4c51SChris Mason * push some data in the path leaf to the right, trying to free up at 125900ec4c51SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 1260aa5d6bedSChris Mason * 1261aa5d6bedSChris Mason * returns 1 if the push failed because the other node didn't have enough 1262aa5d6bedSChris Mason * room, 0 if everything worked out and < 0 if there were major errors. 126300ec4c51SChris Mason */ 1264e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 1265e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 126600ec4c51SChris Mason { 1267e20d96d6SChris Mason struct buffer_head *left_buf = path->nodes[0]; 1268e20d96d6SChris Mason struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); 1269234b63a0SChris Mason struct btrfs_leaf *right; 1270e20d96d6SChris Mason struct buffer_head *right_buf; 1271e20d96d6SChris Mason struct buffer_head *upper; 1272e20d96d6SChris Mason struct btrfs_node *upper_node; 127300ec4c51SChris Mason int slot; 127400ec4c51SChris Mason int i; 127500ec4c51SChris Mason int free_space; 127600ec4c51SChris Mason int push_space = 0; 127700ec4c51SChris Mason int push_items = 0; 12780783fcfcSChris Mason struct btrfs_item *item; 12797518a238SChris Mason u32 left_nritems; 12807518a238SChris Mason u32 right_nritems; 128154aa1f4dSChris Mason int ret; 128200ec4c51SChris Mason 128300ec4c51SChris Mason slot = path->slots[1]; 128400ec4c51SChris Mason if (!path->nodes[1]) { 128500ec4c51SChris Mason return 1; 128600ec4c51SChris Mason } 128700ec4c51SChris Mason upper = path->nodes[1]; 1288e20d96d6SChris Mason upper_node = btrfs_buffer_node(upper); 1289e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { 129000ec4c51SChris Mason return 1; 129100ec4c51SChris Mason } 1292e20d96d6SChris Mason right_buf = read_tree_block(root, 1293e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); 1294e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1295123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 12960783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1297234b63a0SChris Mason btrfs_block_release(root, right_buf); 129800ec4c51SChris Mason return 1; 129900ec4c51SChris Mason } 130002217ed2SChris Mason /* cow and double check */ 130154aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, right_buf, upper, 130254aa1f4dSChris Mason slot + 1, &right_buf); 130354aa1f4dSChris Mason if (ret) { 130454aa1f4dSChris Mason btrfs_block_release(root, right_buf); 130554aa1f4dSChris Mason return 1; 130654aa1f4dSChris Mason } 1307e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buf); 1308123abc88SChris Mason free_space = btrfs_leaf_free_space(root, right); 13090783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1310234b63a0SChris Mason btrfs_block_release(root, right_buf); 131102217ed2SChris Mason return 1; 131202217ed2SChris Mason } 131302217ed2SChris Mason 13147518a238SChris Mason left_nritems = btrfs_header_nritems(&left->header); 1315a429e513SChris Mason if (left_nritems == 0) { 1316a429e513SChris Mason btrfs_block_release(root, right_buf); 1317a429e513SChris Mason return 1; 1318a429e513SChris Mason } 1319a429e513SChris Mason for (i = left_nritems - 1; i >= 1; i--) { 132000ec4c51SChris Mason item = left->items + i; 132100ec4c51SChris Mason if (path->slots[0] == i) 132200ec4c51SChris Mason push_space += data_size + sizeof(*item); 13230783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 13240783fcfcSChris Mason free_space) 132500ec4c51SChris Mason break; 132600ec4c51SChris Mason push_items++; 13270783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 132800ec4c51SChris Mason } 132900ec4c51SChris Mason if (push_items == 0) { 1330234b63a0SChris Mason btrfs_block_release(root, right_buf); 133100ec4c51SChris Mason return 1; 133200ec4c51SChris Mason } 1333a429e513SChris Mason if (push_items == left_nritems) 1334a429e513SChris Mason WARN_ON(1); 13357518a238SChris Mason right_nritems = btrfs_header_nritems(&right->header); 133600ec4c51SChris Mason /* push left to right */ 13370783fcfcSChris Mason push_space = btrfs_item_end(left->items + left_nritems - push_items); 1338123abc88SChris Mason push_space -= leaf_data_end(root, left); 133900ec4c51SChris Mason /* make room in the right data area */ 1340d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1341d6025579SChris Mason leaf_data_end(root, right) - push_space, 1342d6025579SChris Mason btrfs_leaf_data(right) + 1343d6025579SChris Mason leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - 1344d6025579SChris Mason leaf_data_end(root, right)); 134500ec4c51SChris Mason /* copy from the left data area */ 1346d6025579SChris Mason btrfs_memcpy(root, right, btrfs_leaf_data(right) + 1347d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1348d6025579SChris Mason btrfs_leaf_data(left) + leaf_data_end(root, left), 1349d6025579SChris Mason push_space); 1350d6025579SChris Mason btrfs_memmove(root, right, right->items + push_items, right->items, 13510783fcfcSChris Mason right_nritems * sizeof(struct btrfs_item)); 135200ec4c51SChris Mason /* copy the items from left to right */ 1353d6025579SChris Mason btrfs_memcpy(root, right, right->items, left->items + 1354d6025579SChris Mason left_nritems - push_items, 13550783fcfcSChris Mason push_items * sizeof(struct btrfs_item)); 135600ec4c51SChris Mason 135700ec4c51SChris Mason /* update the item pointers */ 13587518a238SChris Mason right_nritems += push_items; 13597518a238SChris Mason btrfs_set_header_nritems(&right->header, right_nritems); 1360123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 13617518a238SChris Mason for (i = 0; i < right_nritems; i++) { 13620783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 13630783fcfcSChris Mason btrfs_item_size(right->items + i)); 13640783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 136500ec4c51SChris Mason } 13667518a238SChris Mason left_nritems -= push_items; 13677518a238SChris Mason btrfs_set_header_nritems(&left->header, left_nritems); 136800ec4c51SChris Mason 1369d6025579SChris Mason btrfs_mark_buffer_dirty(left_buf); 1370d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1371a429e513SChris Mason 1372d6025579SChris Mason btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, 1373e2fa7227SChris Mason &right->items[0].key, sizeof(struct btrfs_disk_key)); 1374d6025579SChris Mason btrfs_mark_buffer_dirty(upper); 137502217ed2SChris Mason 137600ec4c51SChris Mason /* then fixup the leaf pointer in the path */ 13777518a238SChris Mason if (path->slots[0] >= left_nritems) { 13787518a238SChris Mason path->slots[0] -= left_nritems; 1379234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 138000ec4c51SChris Mason path->nodes[0] = right_buf; 138100ec4c51SChris Mason path->slots[1] += 1; 138200ec4c51SChris Mason } else { 1383234b63a0SChris Mason btrfs_block_release(root, right_buf); 138400ec4c51SChris Mason } 1385098f59c2SChris Mason if (path->nodes[1]) 1386098f59c2SChris Mason check_node(root, path, 1); 138700ec4c51SChris Mason return 0; 138800ec4c51SChris Mason } 138900ec4c51SChris Mason /* 139074123bd7SChris Mason * push some data in the path leaf to the left, trying to free up at 139174123bd7SChris Mason * least data_size bytes. returns zero if the push worked, nonzero otherwise 139274123bd7SChris Mason */ 1393e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 1394e089f05cSChris Mason *root, struct btrfs_path *path, int data_size) 1395be0e5c09SChris Mason { 1396e20d96d6SChris Mason struct buffer_head *right_buf = path->nodes[0]; 1397e20d96d6SChris Mason struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); 1398e20d96d6SChris Mason struct buffer_head *t; 1399234b63a0SChris Mason struct btrfs_leaf *left; 1400be0e5c09SChris Mason int slot; 1401be0e5c09SChris Mason int i; 1402be0e5c09SChris Mason int free_space; 1403be0e5c09SChris Mason int push_space = 0; 1404be0e5c09SChris Mason int push_items = 0; 14050783fcfcSChris Mason struct btrfs_item *item; 14067518a238SChris Mason u32 old_left_nritems; 1407aa5d6bedSChris Mason int ret = 0; 1408aa5d6bedSChris Mason int wret; 1409be0e5c09SChris Mason 1410be0e5c09SChris Mason slot = path->slots[1]; 1411be0e5c09SChris Mason if (slot == 0) { 1412be0e5c09SChris Mason return 1; 1413be0e5c09SChris Mason } 1414be0e5c09SChris Mason if (!path->nodes[1]) { 1415be0e5c09SChris Mason return 1; 1416be0e5c09SChris Mason } 1417e20d96d6SChris Mason t = read_tree_block(root, 1418e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); 1419e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1420123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 14210783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1422234b63a0SChris Mason btrfs_block_release(root, t); 1423be0e5c09SChris Mason return 1; 1424be0e5c09SChris Mason } 142502217ed2SChris Mason 142602217ed2SChris Mason /* cow and double check */ 142754aa1f4dSChris Mason ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 142854aa1f4dSChris Mason if (ret) { 142954aa1f4dSChris Mason /* we hit -ENOSPC, but it isn't fatal here */ 143054aa1f4dSChris Mason return 1; 143154aa1f4dSChris Mason } 1432e20d96d6SChris Mason left = btrfs_buffer_leaf(t); 1433123abc88SChris Mason free_space = btrfs_leaf_free_space(root, left); 14340783fcfcSChris Mason if (free_space < data_size + sizeof(struct btrfs_item)) { 1435234b63a0SChris Mason btrfs_block_release(root, t); 143602217ed2SChris Mason return 1; 143702217ed2SChris Mason } 143802217ed2SChris Mason 1439a429e513SChris Mason if (btrfs_header_nritems(&right->header) == 0) { 1440a429e513SChris Mason btrfs_block_release(root, t); 1441a429e513SChris Mason return 1; 1442a429e513SChris Mason } 1443a429e513SChris Mason 1444a429e513SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { 1445be0e5c09SChris Mason item = right->items + i; 1446be0e5c09SChris Mason if (path->slots[0] == i) 1447be0e5c09SChris Mason push_space += data_size + sizeof(*item); 14480783fcfcSChris Mason if (btrfs_item_size(item) + sizeof(*item) + push_space > 14490783fcfcSChris Mason free_space) 1450be0e5c09SChris Mason break; 1451be0e5c09SChris Mason push_items++; 14520783fcfcSChris Mason push_space += btrfs_item_size(item) + sizeof(*item); 1453be0e5c09SChris Mason } 1454be0e5c09SChris Mason if (push_items == 0) { 1455234b63a0SChris Mason btrfs_block_release(root, t); 1456be0e5c09SChris Mason return 1; 1457be0e5c09SChris Mason } 1458a429e513SChris Mason if (push_items == btrfs_header_nritems(&right->header)) 1459a429e513SChris Mason WARN_ON(1); 1460be0e5c09SChris Mason /* push data from right to left */ 1461d6025579SChris Mason btrfs_memcpy(root, left, left->items + 1462d6025579SChris Mason btrfs_header_nritems(&left->header), 14630783fcfcSChris Mason right->items, push_items * sizeof(struct btrfs_item)); 1464123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root) - 14650783fcfcSChris Mason btrfs_item_offset(right->items + push_items -1); 1466d6025579SChris Mason btrfs_memcpy(root, left, btrfs_leaf_data(left) + 1467d6025579SChris Mason leaf_data_end(root, left) - push_space, 1468123abc88SChris Mason btrfs_leaf_data(right) + 1469123abc88SChris Mason btrfs_item_offset(right->items + push_items - 1), 1470be0e5c09SChris Mason push_space); 14717518a238SChris Mason old_left_nritems = btrfs_header_nritems(&left->header); 1472eb60ceacSChris Mason BUG_ON(old_left_nritems < 0); 1473eb60ceacSChris Mason 1474be0e5c09SChris Mason for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 1475123abc88SChris Mason u32 ioff = btrfs_item_offset(left->items + i); 1476123abc88SChris Mason btrfs_set_item_offset(left->items + i, ioff - 1477123abc88SChris Mason (BTRFS_LEAF_DATA_SIZE(root) - 14780783fcfcSChris Mason btrfs_item_offset(left->items + 14790783fcfcSChris Mason old_left_nritems - 1))); 1480be0e5c09SChris Mason } 14817518a238SChris Mason btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); 1482be0e5c09SChris Mason 1483be0e5c09SChris Mason /* fixup right node */ 14840783fcfcSChris Mason push_space = btrfs_item_offset(right->items + push_items - 1) - 1485123abc88SChris Mason leaf_data_end(root, right); 1486d6025579SChris Mason btrfs_memmove(root, right, btrfs_leaf_data(right) + 1487d6025579SChris Mason BTRFS_LEAF_DATA_SIZE(root) - push_space, 1488d6025579SChris Mason btrfs_leaf_data(right) + 1489123abc88SChris Mason leaf_data_end(root, right), push_space); 1490d6025579SChris Mason btrfs_memmove(root, right, right->items, right->items + push_items, 14917518a238SChris Mason (btrfs_header_nritems(&right->header) - push_items) * 14920783fcfcSChris Mason sizeof(struct btrfs_item)); 14937518a238SChris Mason btrfs_set_header_nritems(&right->header, 14947518a238SChris Mason btrfs_header_nritems(&right->header) - 14957518a238SChris Mason push_items); 1496123abc88SChris Mason push_space = BTRFS_LEAF_DATA_SIZE(root); 1497eb60ceacSChris Mason 14987518a238SChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 14990783fcfcSChris Mason btrfs_set_item_offset(right->items + i, push_space - 15000783fcfcSChris Mason btrfs_item_size(right->items + i)); 15010783fcfcSChris Mason push_space = btrfs_item_offset(right->items + i); 1502be0e5c09SChris Mason } 1503eb60ceacSChris Mason 1504d6025579SChris Mason btrfs_mark_buffer_dirty(t); 1505d6025579SChris Mason btrfs_mark_buffer_dirty(right_buf); 1506098f59c2SChris Mason 1507e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1508aa5d6bedSChris Mason if (wret) 1509aa5d6bedSChris Mason ret = wret; 1510be0e5c09SChris Mason 1511be0e5c09SChris Mason /* then fixup the leaf pointer in the path */ 1512be0e5c09SChris Mason if (path->slots[0] < push_items) { 1513be0e5c09SChris Mason path->slots[0] += old_left_nritems; 1514234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1515eb60ceacSChris Mason path->nodes[0] = t; 1516be0e5c09SChris Mason path->slots[1] -= 1; 1517be0e5c09SChris Mason } else { 1518234b63a0SChris Mason btrfs_block_release(root, t); 1519be0e5c09SChris Mason path->slots[0] -= push_items; 1520be0e5c09SChris Mason } 1521eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1522098f59c2SChris Mason if (path->nodes[1]) 1523098f59c2SChris Mason check_node(root, path, 1); 1524aa5d6bedSChris Mason return ret; 1525be0e5c09SChris Mason } 1526be0e5c09SChris Mason 152774123bd7SChris Mason /* 152874123bd7SChris Mason * split the path's leaf in two, making sure there is at least data_size 152974123bd7SChris Mason * available for the resulting leaf level of the path. 1530aa5d6bedSChris Mason * 1531aa5d6bedSChris Mason * returns 0 if all went well and < 0 on failure. 153274123bd7SChris Mason */ 1533e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1534d4dbff95SChris Mason *root, struct btrfs_key *ins_key, 1535d4dbff95SChris Mason struct btrfs_path *path, int data_size) 1536be0e5c09SChris Mason { 1537e20d96d6SChris Mason struct buffer_head *l_buf; 1538234b63a0SChris Mason struct btrfs_leaf *l; 15397518a238SChris Mason u32 nritems; 1540eb60ceacSChris Mason int mid; 1541eb60ceacSChris Mason int slot; 1542234b63a0SChris Mason struct btrfs_leaf *right; 1543e20d96d6SChris Mason struct buffer_head *right_buffer; 15440783fcfcSChris Mason int space_needed = data_size + sizeof(struct btrfs_item); 1545be0e5c09SChris Mason int data_copy_size; 1546be0e5c09SChris Mason int rt_data_off; 1547be0e5c09SChris Mason int i; 1548d4dbff95SChris Mason int ret = 0; 1549aa5d6bedSChris Mason int wret; 1550d4dbff95SChris Mason int double_split = 0; 1551d4dbff95SChris Mason struct btrfs_disk_key disk_key; 1552be0e5c09SChris Mason 155340689478SChris Mason /* first try to make some room by pushing left and right */ 1554e089f05cSChris Mason wret = push_leaf_left(trans, root, path, data_size); 1555eaee50e8SChris Mason if (wret < 0) 1556eaee50e8SChris Mason return wret; 1557eaee50e8SChris Mason if (wret) { 1558e089f05cSChris Mason wret = push_leaf_right(trans, root, path, data_size); 1559eaee50e8SChris Mason if (wret < 0) 1560eaee50e8SChris Mason return wret; 1561eaee50e8SChris Mason } 1562eb60ceacSChris Mason l_buf = path->nodes[0]; 1563e20d96d6SChris Mason l = btrfs_buffer_leaf(l_buf); 1564aa5d6bedSChris Mason 1565aa5d6bedSChris Mason /* did the pushes work? */ 1566123abc88SChris Mason if (btrfs_leaf_free_space(root, l) >= 1567123abc88SChris Mason sizeof(struct btrfs_item) + data_size) 1568be0e5c09SChris Mason return 0; 1569aa5d6bedSChris Mason 15705c680ed6SChris Mason if (!path->nodes[1]) { 1571e089f05cSChris Mason ret = insert_new_root(trans, root, path, 1); 15725c680ed6SChris Mason if (ret) 15735c680ed6SChris Mason return ret; 15745c680ed6SChris Mason } 1575eb60ceacSChris Mason slot = path->slots[0]; 15767518a238SChris Mason nritems = btrfs_header_nritems(&l->header); 1577eb60ceacSChris Mason mid = (nritems + 1)/ 2; 157854aa1f4dSChris Mason 15796702ed49SChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0); 158054aa1f4dSChris Mason if (IS_ERR(right_buffer)) 158154aa1f4dSChris Mason return PTR_ERR(right_buffer); 158254aa1f4dSChris Mason 1583e20d96d6SChris Mason right = btrfs_buffer_leaf(right_buffer); 1584123abc88SChris Mason memset(&right->header, 0, sizeof(right->header)); 15857eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 15867f5c1516SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 15874d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 15887518a238SChris Mason btrfs_set_header_level(&right->header, 0); 15893eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 15903eb0314dSChris Mason sizeof(right->header.fsid)); 1591d4dbff95SChris Mason if (mid <= slot) { 1592d4dbff95SChris Mason if (nritems == 1 || 1593d4dbff95SChris Mason leaf_space_used(l, mid, nritems - mid) + space_needed > 1594d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1595d4dbff95SChris Mason if (slot >= nritems) { 1596d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1597d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1598d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1599d4dbff95SChris Mason &disk_key, 16007eccb903SChris Mason bh_blocknr(right_buffer), 1601d4dbff95SChris Mason path->slots[1] + 1, 1); 1602d4dbff95SChris Mason if (wret) 1603d4dbff95SChris Mason ret = wret; 1604d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1605d4dbff95SChris Mason path->nodes[0] = right_buffer; 1606d4dbff95SChris Mason path->slots[0] = 0; 1607d4dbff95SChris Mason path->slots[1] += 1; 1608d4dbff95SChris Mason return ret; 1609d4dbff95SChris Mason } 1610d4dbff95SChris Mason mid = slot; 1611d4dbff95SChris Mason double_split = 1; 1612d4dbff95SChris Mason } 1613d4dbff95SChris Mason } else { 1614d4dbff95SChris Mason if (leaf_space_used(l, 0, mid + 1) + space_needed > 1615d4dbff95SChris Mason BTRFS_LEAF_DATA_SIZE(root)) { 1616d4dbff95SChris Mason if (slot == 0) { 1617d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1618d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1619d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1620d4dbff95SChris Mason &disk_key, 16217eccb903SChris Mason bh_blocknr(right_buffer), 1622098f59c2SChris Mason path->slots[1], 1); 1623d4dbff95SChris Mason if (wret) 1624d4dbff95SChris Mason ret = wret; 1625d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1626d4dbff95SChris Mason path->nodes[0] = right_buffer; 1627d4dbff95SChris Mason path->slots[0] = 0; 1628a429e513SChris Mason if (path->slots[1] == 0) { 1629a429e513SChris Mason wret = fixup_low_keys(trans, root, 1630a429e513SChris Mason path, &disk_key, 1); 1631a429e513SChris Mason if (wret) 1632a429e513SChris Mason ret = wret; 1633a429e513SChris Mason } 1634d4dbff95SChris Mason return ret; 1635d4dbff95SChris Mason } 1636d4dbff95SChris Mason mid = slot; 1637d4dbff95SChris Mason double_split = 1; 1638d4dbff95SChris Mason } 1639d4dbff95SChris Mason } 1640d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, nritems - mid); 1641123abc88SChris Mason data_copy_size = btrfs_item_end(l->items + mid) - 1642123abc88SChris Mason leaf_data_end(root, l); 1643d6025579SChris Mason btrfs_memcpy(root, right, right->items, l->items + mid, 16440783fcfcSChris Mason (nritems - mid) * sizeof(struct btrfs_item)); 1645d6025579SChris Mason btrfs_memcpy(root, right, 1646d6025579SChris Mason btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - 1647123abc88SChris Mason data_copy_size, btrfs_leaf_data(l) + 1648123abc88SChris Mason leaf_data_end(root, l), data_copy_size); 1649123abc88SChris Mason rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - 1650123abc88SChris Mason btrfs_item_end(l->items + mid); 165174123bd7SChris Mason 16520783fcfcSChris Mason for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1653123abc88SChris Mason u32 ioff = btrfs_item_offset(right->items + i); 16540783fcfcSChris Mason btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 16550783fcfcSChris Mason } 165674123bd7SChris Mason 16577518a238SChris Mason btrfs_set_header_nritems(&l->header, mid); 1658aa5d6bedSChris Mason ret = 0; 1659e089f05cSChris Mason wret = insert_ptr(trans, root, path, &right->items[0].key, 16607eccb903SChris Mason bh_blocknr(right_buffer), path->slots[1] + 1, 1); 1661aa5d6bedSChris Mason if (wret) 1662aa5d6bedSChris Mason ret = wret; 1663d6025579SChris Mason btrfs_mark_buffer_dirty(right_buffer); 1664d6025579SChris Mason btrfs_mark_buffer_dirty(l_buf); 1665eb60ceacSChris Mason BUG_ON(path->slots[0] != slot); 1666be0e5c09SChris Mason if (mid <= slot) { 1667234b63a0SChris Mason btrfs_block_release(root, path->nodes[0]); 1668eb60ceacSChris Mason path->nodes[0] = right_buffer; 1669be0e5c09SChris Mason path->slots[0] -= mid; 1670be0e5c09SChris Mason path->slots[1] += 1; 1671eb60ceacSChris Mason } else 1672234b63a0SChris Mason btrfs_block_release(root, right_buffer); 1673eb60ceacSChris Mason BUG_ON(path->slots[0] < 0); 1674098f59c2SChris Mason check_node(root, path, 1); 1675d4dbff95SChris Mason 1676d4dbff95SChris Mason if (!double_split) 1677d4dbff95SChris Mason return ret; 16786702ed49SChris Mason right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0); 167954aa1f4dSChris Mason if (IS_ERR(right_buffer)) 168054aa1f4dSChris Mason return PTR_ERR(right_buffer); 168154aa1f4dSChris Mason 1682d4dbff95SChris Mason right = btrfs_buffer_leaf(right_buffer); 1683d4dbff95SChris Mason memset(&right->header, 0, sizeof(right->header)); 16847eccb903SChris Mason btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1685d4dbff95SChris Mason btrfs_set_header_generation(&right->header, trans->transid); 16864d775673SChris Mason btrfs_set_header_owner(&right->header, root->root_key.objectid); 1687d4dbff95SChris Mason btrfs_set_header_level(&right->header, 0); 16883eb0314dSChris Mason memcpy(right->header.fsid, root->fs_info->disk_super->fsid, 16893eb0314dSChris Mason sizeof(right->header.fsid)); 1690d4dbff95SChris Mason btrfs_cpu_key_to_disk(&disk_key, ins_key); 1691d4dbff95SChris Mason btrfs_set_header_nritems(&right->header, 0); 1692d4dbff95SChris Mason wret = insert_ptr(trans, root, path, 1693d4dbff95SChris Mason &disk_key, 16947eccb903SChris Mason bh_blocknr(right_buffer), 1695d4dbff95SChris Mason path->slots[1], 1); 1696d4dbff95SChris Mason if (wret) 1697d4dbff95SChris Mason ret = wret; 1698a429e513SChris Mason if (path->slots[1] == 0) { 1699a429e513SChris Mason wret = fixup_low_keys(trans, root, path, &disk_key, 1); 1700a429e513SChris Mason if (wret) 1701a429e513SChris Mason ret = wret; 1702a429e513SChris Mason } 1703d4dbff95SChris Mason btrfs_block_release(root, path->nodes[0]); 1704d4dbff95SChris Mason path->nodes[0] = right_buffer; 1705d4dbff95SChris Mason path->slots[0] = 0; 1706d4dbff95SChris Mason check_node(root, path, 1); 1707d4dbff95SChris Mason check_leaf(root, path, 0); 1708be0e5c09SChris Mason return ret; 1709be0e5c09SChris Mason } 1710be0e5c09SChris Mason 1711b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1712b18c6685SChris Mason struct btrfs_root *root, 1713b18c6685SChris Mason struct btrfs_path *path, 1714b18c6685SChris Mason u32 new_size) 1715b18c6685SChris Mason { 1716b18c6685SChris Mason int ret = 0; 1717b18c6685SChris Mason int slot; 1718b18c6685SChris Mason int slot_orig; 1719b18c6685SChris Mason struct btrfs_leaf *leaf; 1720b18c6685SChris Mason struct buffer_head *leaf_buf; 1721b18c6685SChris Mason u32 nritems; 1722b18c6685SChris Mason unsigned int data_end; 1723b18c6685SChris Mason unsigned int old_data_start; 1724b18c6685SChris Mason unsigned int old_size; 1725b18c6685SChris Mason unsigned int size_diff; 1726b18c6685SChris Mason int i; 1727b18c6685SChris Mason 1728b18c6685SChris Mason slot_orig = path->slots[0]; 1729b18c6685SChris Mason leaf_buf = path->nodes[0]; 1730b18c6685SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 1731b18c6685SChris Mason 1732b18c6685SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1733b18c6685SChris Mason data_end = leaf_data_end(root, leaf); 1734b18c6685SChris Mason 1735b18c6685SChris Mason slot = path->slots[0]; 1736b18c6685SChris Mason old_data_start = btrfs_item_offset(leaf->items + slot); 1737b18c6685SChris Mason old_size = btrfs_item_size(leaf->items + slot); 1738b18c6685SChris Mason BUG_ON(old_size <= new_size); 1739b18c6685SChris Mason size_diff = old_size - new_size; 1740b18c6685SChris Mason 1741b18c6685SChris Mason BUG_ON(slot < 0); 1742b18c6685SChris Mason BUG_ON(slot >= nritems); 1743b18c6685SChris Mason 1744b18c6685SChris Mason /* 1745b18c6685SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1746b18c6685SChris Mason */ 1747b18c6685SChris Mason /* first correct the data pointers */ 1748b18c6685SChris Mason for (i = slot; i < nritems; i++) { 1749b18c6685SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 1750b18c6685SChris Mason btrfs_set_item_offset(leaf->items + i, 1751b18c6685SChris Mason ioff + size_diff); 1752b18c6685SChris Mason } 1753b18c6685SChris Mason /* shift the data */ 1754b18c6685SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1755b18c6685SChris Mason data_end + size_diff, btrfs_leaf_data(leaf) + 1756b18c6685SChris Mason data_end, old_data_start + new_size - data_end); 1757b18c6685SChris Mason btrfs_set_item_size(leaf->items + slot, new_size); 1758b18c6685SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1759b18c6685SChris Mason 1760b18c6685SChris Mason ret = 0; 1761b18c6685SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1762b18c6685SChris Mason BUG(); 1763b18c6685SChris Mason check_leaf(root, path, 0); 1764b18c6685SChris Mason return ret; 1765b18c6685SChris Mason } 1766b18c6685SChris Mason 17676567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 17686567e837SChris Mason *root, struct btrfs_path *path, u32 data_size) 17696567e837SChris Mason { 17706567e837SChris Mason int ret = 0; 17716567e837SChris Mason int slot; 17726567e837SChris Mason int slot_orig; 17736567e837SChris Mason struct btrfs_leaf *leaf; 17746567e837SChris Mason struct buffer_head *leaf_buf; 17756567e837SChris Mason u32 nritems; 17766567e837SChris Mason unsigned int data_end; 17776567e837SChris Mason unsigned int old_data; 17786567e837SChris Mason unsigned int old_size; 17796567e837SChris Mason int i; 17806567e837SChris Mason 17816567e837SChris Mason slot_orig = path->slots[0]; 17826567e837SChris Mason leaf_buf = path->nodes[0]; 17836567e837SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 17846567e837SChris Mason 17856567e837SChris Mason nritems = btrfs_header_nritems(&leaf->header); 17866567e837SChris Mason data_end = leaf_data_end(root, leaf); 17876567e837SChris Mason 17886567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < data_size) 17896567e837SChris Mason BUG(); 17906567e837SChris Mason slot = path->slots[0]; 17916567e837SChris Mason old_data = btrfs_item_end(leaf->items + slot); 17926567e837SChris Mason 17936567e837SChris Mason BUG_ON(slot < 0); 17946567e837SChris Mason BUG_ON(slot >= nritems); 17956567e837SChris Mason 17966567e837SChris Mason /* 17976567e837SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 17986567e837SChris Mason */ 17996567e837SChris Mason /* first correct the data pointers */ 18006567e837SChris Mason for (i = slot; i < nritems; i++) { 18016567e837SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 18026567e837SChris Mason btrfs_set_item_offset(leaf->items + i, 18036567e837SChris Mason ioff - data_size); 18046567e837SChris Mason } 18056567e837SChris Mason /* shift the data */ 18066567e837SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 18076567e837SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 18086567e837SChris Mason data_end, old_data - data_end); 18096567e837SChris Mason data_end = old_data; 18106567e837SChris Mason old_size = btrfs_item_size(leaf->items + slot); 18116567e837SChris Mason btrfs_set_item_size(leaf->items + slot, old_size + data_size); 18126567e837SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 18136567e837SChris Mason 18146567e837SChris Mason ret = 0; 18156567e837SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 18166567e837SChris Mason BUG(); 18176567e837SChris Mason check_leaf(root, path, 0); 18186567e837SChris Mason return ret; 18196567e837SChris Mason } 18206567e837SChris Mason 182174123bd7SChris Mason /* 182274123bd7SChris Mason * Given a key and some data, insert an item into the tree. 182374123bd7SChris Mason * This does all the path init required, making room in the tree if needed. 182474123bd7SChris Mason */ 1825e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root 1826e089f05cSChris Mason *root, struct btrfs_path *path, struct btrfs_key 1827e089f05cSChris Mason *cpu_key, u32 data_size) 1828be0e5c09SChris Mason { 1829aa5d6bedSChris Mason int ret = 0; 1830be0e5c09SChris Mason int slot; 1831eb60ceacSChris Mason int slot_orig; 1832234b63a0SChris Mason struct btrfs_leaf *leaf; 1833e20d96d6SChris Mason struct buffer_head *leaf_buf; 18347518a238SChris Mason u32 nritems; 1835be0e5c09SChris Mason unsigned int data_end; 1836e2fa7227SChris Mason struct btrfs_disk_key disk_key; 1837e2fa7227SChris Mason 1838e2fa7227SChris Mason btrfs_cpu_key_to_disk(&disk_key, cpu_key); 1839be0e5c09SChris Mason 184074123bd7SChris Mason /* create a root if there isn't one */ 18415c680ed6SChris Mason if (!root->node) 1842cfaa7295SChris Mason BUG(); 1843e089f05cSChris Mason ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); 1844eb60ceacSChris Mason if (ret == 0) { 1845f0930a37SChris Mason return -EEXIST; 1846aa5d6bedSChris Mason } 1847ed2ff2cbSChris Mason if (ret < 0) 1848ed2ff2cbSChris Mason goto out; 1849be0e5c09SChris Mason 185062e2749eSChris Mason slot_orig = path->slots[0]; 185162e2749eSChris Mason leaf_buf = path->nodes[0]; 1852e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 185374123bd7SChris Mason 18547518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1855123abc88SChris Mason data_end = leaf_data_end(root, leaf); 1856eb60ceacSChris Mason 1857123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 1858d4dbff95SChris Mason sizeof(struct btrfs_item) + data_size) { 1859be0e5c09SChris Mason BUG(); 1860d4dbff95SChris Mason } 186162e2749eSChris Mason slot = path->slots[0]; 1862eb60ceacSChris Mason BUG_ON(slot < 0); 1863be0e5c09SChris Mason if (slot != nritems) { 1864be0e5c09SChris Mason int i; 18650783fcfcSChris Mason unsigned int old_data = btrfs_item_end(leaf->items + slot); 1866be0e5c09SChris Mason 1867be0e5c09SChris Mason /* 1868be0e5c09SChris Mason * item0..itemN ... dataN.offset..dataN.size .. data0.size 1869be0e5c09SChris Mason */ 1870be0e5c09SChris Mason /* first correct the data pointers */ 18710783fcfcSChris Mason for (i = slot; i < nritems; i++) { 1872123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 18730783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, 18740783fcfcSChris Mason ioff - data_size); 18750783fcfcSChris Mason } 1876be0e5c09SChris Mason 1877be0e5c09SChris Mason /* shift the items */ 1878d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot + 1, 1879d6025579SChris Mason leaf->items + slot, 18800783fcfcSChris Mason (nritems - slot) * sizeof(struct btrfs_item)); 1881be0e5c09SChris Mason 1882be0e5c09SChris Mason /* shift the data */ 1883d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1884d6025579SChris Mason data_end - data_size, btrfs_leaf_data(leaf) + 1885be0e5c09SChris Mason data_end, old_data - data_end); 1886be0e5c09SChris Mason data_end = old_data; 1887be0e5c09SChris Mason } 188862e2749eSChris Mason /* setup the item for the new data */ 1889d6025579SChris Mason btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, 1890e2fa7227SChris Mason sizeof(struct btrfs_disk_key)); 18910783fcfcSChris Mason btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 18920783fcfcSChris Mason btrfs_set_item_size(leaf->items + slot, data_size); 18937518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems + 1); 1894d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 1895aa5d6bedSChris Mason 1896aa5d6bedSChris Mason ret = 0; 18978e19f2cdSChris Mason if (slot == 0) 1898e089f05cSChris Mason ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1899aa5d6bedSChris Mason 1900123abc88SChris Mason if (btrfs_leaf_free_space(root, leaf) < 0) 1901be0e5c09SChris Mason BUG(); 190262e2749eSChris Mason check_leaf(root, path, 0); 1903ed2ff2cbSChris Mason out: 190462e2749eSChris Mason return ret; 190562e2749eSChris Mason } 190662e2749eSChris Mason 190762e2749eSChris Mason /* 190862e2749eSChris Mason * Given a key and some data, insert an item into the tree. 190962e2749eSChris Mason * This does all the path init required, making room in the tree if needed. 191062e2749eSChris Mason */ 1911e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root 1912e089f05cSChris Mason *root, struct btrfs_key *cpu_key, void *data, u32 1913e089f05cSChris Mason data_size) 191462e2749eSChris Mason { 191562e2749eSChris Mason int ret = 0; 19162c90e5d6SChris Mason struct btrfs_path *path; 191762e2749eSChris Mason u8 *ptr; 191862e2749eSChris Mason 19192c90e5d6SChris Mason path = btrfs_alloc_path(); 19202c90e5d6SChris Mason BUG_ON(!path); 19212c90e5d6SChris Mason ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 192262e2749eSChris Mason if (!ret) { 19232c90e5d6SChris Mason ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 19242c90e5d6SChris Mason path->slots[0], u8); 19252c90e5d6SChris Mason btrfs_memcpy(root, path->nodes[0]->b_data, 1926d6025579SChris Mason ptr, data, data_size); 19272c90e5d6SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 192862e2749eSChris Mason } 19292c90e5d6SChris Mason btrfs_free_path(path); 1930aa5d6bedSChris Mason return ret; 1931be0e5c09SChris Mason } 1932be0e5c09SChris Mason 193374123bd7SChris Mason /* 19345de08d7dSChris Mason * delete the pointer from a given node. 193574123bd7SChris Mason * 193674123bd7SChris Mason * If the delete empties a node, the node is removed from the tree, 193774123bd7SChris Mason * continuing all the way the root if required. The root is converted into 193874123bd7SChris Mason * a leaf if all the nodes are emptied. 193974123bd7SChris Mason */ 1940e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1941e089f05cSChris Mason struct btrfs_path *path, int level, int slot) 1942be0e5c09SChris Mason { 1943234b63a0SChris Mason struct btrfs_node *node; 1944e20d96d6SChris Mason struct buffer_head *parent = path->nodes[level]; 19457518a238SChris Mason u32 nritems; 1946aa5d6bedSChris Mason int ret = 0; 1947bb803951SChris Mason int wret; 1948be0e5c09SChris Mason 1949e20d96d6SChris Mason node = btrfs_buffer_node(parent); 19507518a238SChris Mason nritems = btrfs_header_nritems(&node->header); 1951be0e5c09SChris Mason if (slot != nritems -1) { 1952d6025579SChris Mason btrfs_memmove(root, node, node->ptrs + slot, 1953d6025579SChris Mason node->ptrs + slot + 1, 1954d6025579SChris Mason sizeof(struct btrfs_key_ptr) * 1955d6025579SChris Mason (nritems - slot - 1)); 1956be0e5c09SChris Mason } 19577518a238SChris Mason nritems--; 19587518a238SChris Mason btrfs_set_header_nritems(&node->header, nritems); 19597518a238SChris Mason if (nritems == 0 && parent == root->node) { 1960e20d96d6SChris Mason struct btrfs_header *header = btrfs_buffer_header(root->node); 1961e20d96d6SChris Mason BUG_ON(btrfs_header_level(header) != 1); 1962eb60ceacSChris Mason /* just turn the root into a leaf and break */ 1963e20d96d6SChris Mason btrfs_set_header_level(header, 0); 1964bb803951SChris Mason } else if (slot == 0) { 1965e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1966123abc88SChris Mason level + 1); 19670f70abe2SChris Mason if (wret) 19680f70abe2SChris Mason ret = wret; 1969be0e5c09SChris Mason } 1970d6025579SChris Mason btrfs_mark_buffer_dirty(parent); 1971aa5d6bedSChris Mason return ret; 1972be0e5c09SChris Mason } 1973be0e5c09SChris Mason 197474123bd7SChris Mason /* 197574123bd7SChris Mason * delete the item at the leaf level in path. If that empties 197674123bd7SChris Mason * the leaf, remove it from the tree 197774123bd7SChris Mason */ 1978e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 1979e089f05cSChris Mason struct btrfs_path *path) 1980be0e5c09SChris Mason { 1981be0e5c09SChris Mason int slot; 1982234b63a0SChris Mason struct btrfs_leaf *leaf; 1983e20d96d6SChris Mason struct buffer_head *leaf_buf; 1984be0e5c09SChris Mason int doff; 1985be0e5c09SChris Mason int dsize; 1986aa5d6bedSChris Mason int ret = 0; 1987aa5d6bedSChris Mason int wret; 19887518a238SChris Mason u32 nritems; 1989be0e5c09SChris Mason 1990eb60ceacSChris Mason leaf_buf = path->nodes[0]; 1991e20d96d6SChris Mason leaf = btrfs_buffer_leaf(leaf_buf); 19924920c9acSChris Mason slot = path->slots[0]; 19930783fcfcSChris Mason doff = btrfs_item_offset(leaf->items + slot); 19940783fcfcSChris Mason dsize = btrfs_item_size(leaf->items + slot); 19957518a238SChris Mason nritems = btrfs_header_nritems(&leaf->header); 1996be0e5c09SChris Mason 19977518a238SChris Mason if (slot != nritems - 1) { 1998be0e5c09SChris Mason int i; 1999123abc88SChris Mason int data_end = leaf_data_end(root, leaf); 2000d6025579SChris Mason btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 2001d6025579SChris Mason data_end + dsize, 2002123abc88SChris Mason btrfs_leaf_data(leaf) + data_end, 2003be0e5c09SChris Mason doff - data_end); 20040783fcfcSChris Mason for (i = slot + 1; i < nritems; i++) { 2005123abc88SChris Mason u32 ioff = btrfs_item_offset(leaf->items + i); 20060783fcfcSChris Mason btrfs_set_item_offset(leaf->items + i, ioff + dsize); 20070783fcfcSChris Mason } 2008d6025579SChris Mason btrfs_memmove(root, leaf, leaf->items + slot, 2009d6025579SChris Mason leaf->items + slot + 1, 20100783fcfcSChris Mason sizeof(struct btrfs_item) * 20117518a238SChris Mason (nritems - slot - 1)); 2012be0e5c09SChris Mason } 20137518a238SChris Mason btrfs_set_header_nritems(&leaf->header, nritems - 1); 20147518a238SChris Mason nritems--; 201574123bd7SChris Mason /* delete the leaf if we've emptied it */ 20167518a238SChris Mason if (nritems == 0) { 2017eb60ceacSChris Mason if (leaf_buf == root->node) { 20187518a238SChris Mason btrfs_set_header_level(&leaf->header, 0); 20199a8dd150SChris Mason } else { 2020e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 2021d6025579SChris Mason wait_on_buffer(leaf_buf); 2022e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, path->slots[1]); 2023aa5d6bedSChris Mason if (wret) 2024aa5d6bedSChris Mason ret = wret; 2025e089f05cSChris Mason wret = btrfs_free_extent(trans, root, 20267eccb903SChris Mason bh_blocknr(leaf_buf), 1, 1); 20270f70abe2SChris Mason if (wret) 20280f70abe2SChris Mason ret = wret; 20299a8dd150SChris Mason } 2030be0e5c09SChris Mason } else { 20317518a238SChris Mason int used = leaf_space_used(leaf, 0, nritems); 2032aa5d6bedSChris Mason if (slot == 0) { 2033e089f05cSChris Mason wret = fixup_low_keys(trans, root, path, 2034aa5d6bedSChris Mason &leaf->items[0].key, 1); 2035aa5d6bedSChris Mason if (wret) 2036aa5d6bedSChris Mason ret = wret; 2037aa5d6bedSChris Mason } 2038aa5d6bedSChris Mason 203974123bd7SChris Mason /* delete the leaf if it is mostly empty */ 2040123abc88SChris Mason if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 2041be0e5c09SChris Mason /* push_leaf_left fixes the path. 2042be0e5c09SChris Mason * make sure the path still points to our leaf 2043be0e5c09SChris Mason * for possible call to del_ptr below 2044be0e5c09SChris Mason */ 20454920c9acSChris Mason slot = path->slots[1]; 2046e20d96d6SChris Mason get_bh(leaf_buf); 2047e089f05cSChris Mason wret = push_leaf_left(trans, root, path, 1); 204854aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 2049aa5d6bedSChris Mason ret = wret; 2050f0930a37SChris Mason if (path->nodes[0] == leaf_buf && 20517518a238SChris Mason btrfs_header_nritems(&leaf->header)) { 2052e089f05cSChris Mason wret = push_leaf_right(trans, root, path, 1); 205354aa1f4dSChris Mason if (wret < 0 && wret != -ENOSPC) 2054aa5d6bedSChris Mason ret = wret; 2055aa5d6bedSChris Mason } 20567518a238SChris Mason if (btrfs_header_nritems(&leaf->header) == 0) { 20577eccb903SChris Mason u64 blocknr = bh_blocknr(leaf_buf); 2058e089f05cSChris Mason clean_tree_block(trans, root, leaf_buf); 2059d6025579SChris Mason wait_on_buffer(leaf_buf); 2060e089f05cSChris Mason wret = del_ptr(trans, root, path, 1, slot); 2061aa5d6bedSChris Mason if (wret) 2062aa5d6bedSChris Mason ret = wret; 2063234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 2064e089f05cSChris Mason wret = btrfs_free_extent(trans, root, blocknr, 2065e089f05cSChris Mason 1, 1); 20660f70abe2SChris Mason if (wret) 20670f70abe2SChris Mason ret = wret; 20685de08d7dSChris Mason } else { 2069d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 2070234b63a0SChris Mason btrfs_block_release(root, leaf_buf); 2071be0e5c09SChris Mason } 2072d5719762SChris Mason } else { 2073d6025579SChris Mason btrfs_mark_buffer_dirty(leaf_buf); 2074be0e5c09SChris Mason } 20759a8dd150SChris Mason } 2076aa5d6bedSChris Mason return ret; 20779a8dd150SChris Mason } 20789a8dd150SChris Mason 207997571fd0SChris Mason /* 208097571fd0SChris Mason * walk up the tree as far as required to find the next leaf. 20810f70abe2SChris Mason * returns 0 if it found something or 1 if there are no greater leaves. 20820f70abe2SChris Mason * returns < 0 on io errors. 208397571fd0SChris Mason */ 2084234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) 2085d97e63b6SChris Mason { 2086d97e63b6SChris Mason int slot; 2087d97e63b6SChris Mason int level = 1; 2088d97e63b6SChris Mason u64 blocknr; 2089e20d96d6SChris Mason struct buffer_head *c; 2090e20d96d6SChris Mason struct btrfs_node *c_node; 2091e20d96d6SChris Mason struct buffer_head *next = NULL; 2092d97e63b6SChris Mason 2093234b63a0SChris Mason while(level < BTRFS_MAX_LEVEL) { 2094d97e63b6SChris Mason if (!path->nodes[level]) 20950f70abe2SChris Mason return 1; 2096d97e63b6SChris Mason slot = path->slots[level] + 1; 2097d97e63b6SChris Mason c = path->nodes[level]; 2098e20d96d6SChris Mason c_node = btrfs_buffer_node(c); 2099e20d96d6SChris Mason if (slot >= btrfs_header_nritems(&c_node->header)) { 2100d97e63b6SChris Mason level++; 2101d97e63b6SChris Mason continue; 2102d97e63b6SChris Mason } 2103e20d96d6SChris Mason blocknr = btrfs_node_blockptr(c_node, slot); 2104cfaa7295SChris Mason if (next) 2105234b63a0SChris Mason btrfs_block_release(root, next); 21066702ed49SChris Mason if (path->reada) 21076702ed49SChris Mason reada_for_search(root, path, level, slot); 2108d97e63b6SChris Mason next = read_tree_block(root, blocknr); 2109d97e63b6SChris Mason break; 2110d97e63b6SChris Mason } 2111d97e63b6SChris Mason path->slots[level] = slot; 2112d97e63b6SChris Mason while(1) { 2113d97e63b6SChris Mason level--; 2114d97e63b6SChris Mason c = path->nodes[level]; 2115234b63a0SChris Mason btrfs_block_release(root, c); 2116d97e63b6SChris Mason path->nodes[level] = next; 2117d97e63b6SChris Mason path->slots[level] = 0; 2118d97e63b6SChris Mason if (!level) 2119d97e63b6SChris Mason break; 21206702ed49SChris Mason if (path->reada) 21216702ed49SChris Mason reada_for_search(root, path, level, slot); 21221d4f8a0cSChris Mason next = read_tree_block(root, 2123e20d96d6SChris Mason btrfs_node_blockptr(btrfs_buffer_node(next), 0)); 2124d97e63b6SChris Mason } 2125d97e63b6SChris Mason return 0; 2126d97e63b6SChris Mason } 2127