diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/btrfs/ctree.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 305 |
1 files changed, 98 insertions, 207 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index c3df14ce2cc2..2e667868e0d2 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -38,18 +38,11 @@ static int balance_node_right(struct btrfs_trans_handle *trans, | |||
38 | struct extent_buffer *src_buf); | 38 | struct extent_buffer *src_buf); |
39 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 39 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
40 | struct btrfs_path *path, int level, int slot); | 40 | struct btrfs_path *path, int level, int slot); |
41 | static int setup_items_for_insert(struct btrfs_trans_handle *trans, | ||
42 | struct btrfs_root *root, struct btrfs_path *path, | ||
43 | struct btrfs_key *cpu_key, u32 *data_size, | ||
44 | u32 total_data, u32 total_size, int nr); | ||
45 | |||
46 | 41 | ||
47 | struct btrfs_path *btrfs_alloc_path(void) | 42 | struct btrfs_path *btrfs_alloc_path(void) |
48 | { | 43 | { |
49 | struct btrfs_path *path; | 44 | struct btrfs_path *path; |
50 | path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); | 45 | path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); |
51 | if (path) | ||
52 | path->reada = 1; | ||
53 | return path; | 46 | return path; |
54 | } | 47 | } |
55 | 48 | ||
@@ -105,7 +98,9 @@ noinline void btrfs_clear_path_blocking(struct btrfs_path *p, | |||
105 | /* this also releases the path */ | 98 | /* this also releases the path */ |
106 | void btrfs_free_path(struct btrfs_path *p) | 99 | void btrfs_free_path(struct btrfs_path *p) |
107 | { | 100 | { |
108 | btrfs_release_path(NULL, p); | 101 | if (!p) |
102 | return; | ||
103 | btrfs_release_path(p); | ||
109 | kmem_cache_free(btrfs_path_cachep, p); | 104 | kmem_cache_free(btrfs_path_cachep, p); |
110 | } | 105 | } |
111 | 106 | ||
@@ -115,7 +110,7 @@ void btrfs_free_path(struct btrfs_path *p) | |||
115 | * | 110 | * |
116 | * It is safe to call this on paths that no locks or extent buffers held. | 111 | * It is safe to call this on paths that no locks or extent buffers held. |
117 | */ | 112 | */ |
118 | noinline void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) | 113 | noinline void btrfs_release_path(struct btrfs_path *p) |
119 | { | 114 | { |
120 | int i; | 115 | int i; |
121 | 116 | ||
@@ -145,10 +140,11 @@ noinline void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) | |||
145 | struct extent_buffer *btrfs_root_node(struct btrfs_root *root) | 140 | struct extent_buffer *btrfs_root_node(struct btrfs_root *root) |
146 | { | 141 | { |
147 | struct extent_buffer *eb; | 142 | struct extent_buffer *eb; |
148 | spin_lock(&root->node_lock); | 143 | |
149 | eb = root->node; | 144 | rcu_read_lock(); |
145 | eb = rcu_dereference(root->node); | ||
150 | extent_buffer_get(eb); | 146 | extent_buffer_get(eb); |
151 | spin_unlock(&root->node_lock); | 147 | rcu_read_unlock(); |
152 | return eb; | 148 | return eb; |
153 | } | 149 | } |
154 | 150 | ||
@@ -163,14 +159,8 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root) | |||
163 | while (1) { | 159 | while (1) { |
164 | eb = btrfs_root_node(root); | 160 | eb = btrfs_root_node(root); |
165 | btrfs_tree_lock(eb); | 161 | btrfs_tree_lock(eb); |
166 | 162 | if (eb == root->node) | |
167 | spin_lock(&root->node_lock); | ||
168 | if (eb == root->node) { | ||
169 | spin_unlock(&root->node_lock); | ||
170 | break; | 163 | break; |
171 | } | ||
172 | spin_unlock(&root->node_lock); | ||
173 | |||
174 | btrfs_tree_unlock(eb); | 164 | btrfs_tree_unlock(eb); |
175 | free_extent_buffer(eb); | 165 | free_extent_buffer(eb); |
176 | } | 166 | } |
@@ -200,7 +190,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
200 | struct extent_buffer **cow_ret, u64 new_root_objectid) | 190 | struct extent_buffer **cow_ret, u64 new_root_objectid) |
201 | { | 191 | { |
202 | struct extent_buffer *cow; | 192 | struct extent_buffer *cow; |
203 | u32 nritems; | ||
204 | int ret = 0; | 193 | int ret = 0; |
205 | int level; | 194 | int level; |
206 | struct btrfs_disk_key disk_key; | 195 | struct btrfs_disk_key disk_key; |
@@ -210,7 +199,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
210 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); | 199 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); |
211 | 200 | ||
212 | level = btrfs_header_level(buf); | 201 | level = btrfs_header_level(buf); |
213 | nritems = btrfs_header_nritems(buf); | ||
214 | if (level == 0) | 202 | if (level == 0) |
215 | btrfs_item_key(buf, &disk_key, 0); | 203 | btrfs_item_key(buf, &disk_key, 0); |
216 | else | 204 | else |
@@ -458,10 +446,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
458 | else | 446 | else |
459 | parent_start = 0; | 447 | parent_start = 0; |
460 | 448 | ||
461 | spin_lock(&root->node_lock); | ||
462 | root->node = cow; | ||
463 | extent_buffer_get(cow); | 449 | extent_buffer_get(cow); |
464 | spin_unlock(&root->node_lock); | 450 | rcu_assign_pointer(root->node, cow); |
465 | 451 | ||
466 | btrfs_free_tree_block(trans, root, buf, parent_start, | 452 | btrfs_free_tree_block(trans, root, buf, parent_start, |
467 | last_ref); | 453 | last_ref); |
@@ -542,6 +528,9 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
542 | 528 | ||
543 | ret = __btrfs_cow_block(trans, root, buf, parent, | 529 | ret = __btrfs_cow_block(trans, root, buf, parent, |
544 | parent_slot, cow_ret, search_start, 0); | 530 | parent_slot, cow_ret, search_start, 0); |
531 | |||
532 | trace_btrfs_cow_block(root, buf, *cow_ret); | ||
533 | |||
545 | return ret; | 534 | return ret; |
546 | } | 535 | } |
547 | 536 | ||
@@ -686,6 +675,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
686 | if (!cur) { | 675 | if (!cur) { |
687 | cur = read_tree_block(root, blocknr, | 676 | cur = read_tree_block(root, blocknr, |
688 | blocksize, gen); | 677 | blocksize, gen); |
678 | if (!cur) | ||
679 | return -EIO; | ||
689 | } else if (!uptodate) { | 680 | } else if (!uptodate) { |
690 | btrfs_read_buffer(cur, gen); | 681 | btrfs_read_buffer(cur, gen); |
691 | } | 682 | } |
@@ -732,122 +723,6 @@ static inline unsigned int leaf_data_end(struct btrfs_root *root, | |||
732 | return btrfs_item_offset_nr(leaf, nr - 1); | 723 | return btrfs_item_offset_nr(leaf, nr - 1); |
733 | } | 724 | } |
734 | 725 | ||
735 | /* | ||
736 | * extra debugging checks to make sure all the items in a key are | ||
737 | * well formed and in the proper order | ||
738 | */ | ||
739 | static int check_node(struct btrfs_root *root, struct btrfs_path *path, | ||
740 | int level) | ||
741 | { | ||
742 | struct extent_buffer *parent = NULL; | ||
743 | struct extent_buffer *node = path->nodes[level]; | ||
744 | struct btrfs_disk_key parent_key; | ||
745 | struct btrfs_disk_key node_key; | ||
746 | int parent_slot; | ||
747 | int slot; | ||
748 | struct btrfs_key cpukey; | ||
749 | u32 nritems = btrfs_header_nritems(node); | ||
750 | |||
751 | if (path->nodes[level + 1]) | ||
752 | parent = path->nodes[level + 1]; | ||
753 | |||
754 | slot = path->slots[level]; | ||
755 | BUG_ON(nritems == 0); | ||
756 | if (parent) { | ||
757 | parent_slot = path->slots[level + 1]; | ||
758 | btrfs_node_key(parent, &parent_key, parent_slot); | ||
759 | btrfs_node_key(node, &node_key, 0); | ||
760 | BUG_ON(memcmp(&parent_key, &node_key, | ||
761 | sizeof(struct btrfs_disk_key))); | ||
762 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != | ||
763 | btrfs_header_bytenr(node)); | ||
764 | } | ||
765 | BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); | ||
766 | if (slot != 0) { | ||
767 | btrfs_node_key_to_cpu(node, &cpukey, slot - 1); | ||
768 | btrfs_node_key(node, &node_key, slot); | ||
769 | BUG_ON(comp_keys(&node_key, &cpukey) <= 0); | ||
770 | } | ||
771 | if (slot < nritems - 1) { | ||
772 | btrfs_node_key_to_cpu(node, &cpukey, slot + 1); | ||
773 | btrfs_node_key(node, &node_key, slot); | ||
774 | BUG_ON(comp_keys(&node_key, &cpukey) >= 0); | ||
775 | } | ||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | /* | ||
780 | * extra checking to make sure all the items in a leaf are | ||
781 | * well formed and in the proper order | ||
782 | */ | ||
783 | static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, | ||
784 | int level) | ||
785 | { | ||
786 | struct extent_buffer *leaf = path->nodes[level]; | ||
787 | struct extent_buffer *parent = NULL; | ||
788 | int parent_slot; | ||
789 | struct btrfs_key cpukey; | ||
790 | struct btrfs_disk_key parent_key; | ||
791 | struct btrfs_disk_key leaf_key; | ||
792 | int slot = path->slots[0]; | ||
793 | |||
794 | u32 nritems = btrfs_header_nritems(leaf); | ||
795 | |||
796 | if (path->nodes[level + 1]) | ||
797 | parent = path->nodes[level + 1]; | ||
798 | |||
799 | if (nritems == 0) | ||
800 | return 0; | ||
801 | |||
802 | if (parent) { | ||
803 | parent_slot = path->slots[level + 1]; | ||
804 | btrfs_node_key(parent, &parent_key, parent_slot); | ||
805 | btrfs_item_key(leaf, &leaf_key, 0); | ||
806 | |||
807 | BUG_ON(memcmp(&parent_key, &leaf_key, | ||
808 | sizeof(struct btrfs_disk_key))); | ||
809 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != | ||
810 | btrfs_header_bytenr(leaf)); | ||
811 | } | ||
812 | if (slot != 0 && slot < nritems - 1) { | ||
813 | btrfs_item_key(leaf, &leaf_key, slot); | ||
814 | btrfs_item_key_to_cpu(leaf, &cpukey, slot - 1); | ||
815 | if (comp_keys(&leaf_key, &cpukey) <= 0) { | ||
816 | btrfs_print_leaf(root, leaf); | ||
817 | printk(KERN_CRIT "slot %d offset bad key\n", slot); | ||
818 | BUG_ON(1); | ||
819 | } | ||
820 | if (btrfs_item_offset_nr(leaf, slot - 1) != | ||
821 | btrfs_item_end_nr(leaf, slot)) { | ||
822 | btrfs_print_leaf(root, leaf); | ||
823 | printk(KERN_CRIT "slot %d offset bad\n", slot); | ||
824 | BUG_ON(1); | ||
825 | } | ||
826 | } | ||
827 | if (slot < nritems - 1) { | ||
828 | btrfs_item_key(leaf, &leaf_key, slot); | ||
829 | btrfs_item_key_to_cpu(leaf, &cpukey, slot + 1); | ||
830 | BUG_ON(comp_keys(&leaf_key, &cpukey) >= 0); | ||
831 | if (btrfs_item_offset_nr(leaf, slot) != | ||
832 | btrfs_item_end_nr(leaf, slot + 1)) { | ||
833 | btrfs_print_leaf(root, leaf); | ||
834 | printk(KERN_CRIT "slot %d offset bad\n", slot); | ||
835 | BUG_ON(1); | ||
836 | } | ||
837 | } | ||
838 | BUG_ON(btrfs_item_offset_nr(leaf, 0) + | ||
839 | btrfs_item_size_nr(leaf, 0) != BTRFS_LEAF_DATA_SIZE(root)); | ||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | static noinline int check_block(struct btrfs_root *root, | ||
844 | struct btrfs_path *path, int level) | ||
845 | { | ||
846 | return 0; | ||
847 | if (level == 0) | ||
848 | return check_leaf(root, path, level); | ||
849 | return check_node(root, path, level); | ||
850 | } | ||
851 | 726 | ||
852 | /* | 727 | /* |
853 | * search for key in the extent_buffer. The items start at offset p, | 728 | * search for key in the extent_buffer. The items start at offset p, |
@@ -1008,7 +883,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1008 | int wret; | 883 | int wret; |
1009 | int pslot; | 884 | int pslot; |
1010 | int orig_slot = path->slots[level]; | 885 | int orig_slot = path->slots[level]; |
1011 | int err_on_enospc = 0; | ||
1012 | u64 orig_ptr; | 886 | u64 orig_ptr; |
1013 | 887 | ||
1014 | if (level == 0) | 888 | if (level == 0) |
@@ -1047,9 +921,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1047 | goto enospc; | 921 | goto enospc; |
1048 | } | 922 | } |
1049 | 923 | ||
1050 | spin_lock(&root->node_lock); | 924 | rcu_assign_pointer(root->node, child); |
1051 | root->node = child; | ||
1052 | spin_unlock(&root->node_lock); | ||
1053 | 925 | ||
1054 | add_root_to_dirty_list(root); | 926 | add_root_to_dirty_list(root); |
1055 | btrfs_tree_unlock(child); | 927 | btrfs_tree_unlock(child); |
@@ -1071,8 +943,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1071 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) | 943 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) |
1072 | return 0; | 944 | return 0; |
1073 | 945 | ||
1074 | if (btrfs_header_nritems(mid) < 2) | 946 | btrfs_header_nritems(mid); |
1075 | err_on_enospc = 1; | ||
1076 | 947 | ||
1077 | left = read_node_slot(root, parent, pslot - 1); | 948 | left = read_node_slot(root, parent, pslot - 1); |
1078 | if (left) { | 949 | if (left) { |
@@ -1103,8 +974,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1103 | wret = push_node_left(trans, root, left, mid, 1); | 974 | wret = push_node_left(trans, root, left, mid, 1); |
1104 | if (wret < 0) | 975 | if (wret < 0) |
1105 | ret = wret; | 976 | ret = wret; |
1106 | if (btrfs_header_nritems(mid) < 2) | 977 | btrfs_header_nritems(mid); |
1107 | err_on_enospc = 1; | ||
1108 | } | 978 | } |
1109 | 979 | ||
1110 | /* | 980 | /* |
@@ -1191,7 +1061,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1191 | } | 1061 | } |
1192 | } | 1062 | } |
1193 | /* double check we haven't messed things up */ | 1063 | /* double check we haven't messed things up */ |
1194 | check_block(root, path, level); | ||
1195 | if (orig_ptr != | 1064 | if (orig_ptr != |
1196 | btrfs_node_blockptr(path->nodes[level], path->slots[level])) | 1065 | btrfs_node_blockptr(path->nodes[level], path->slots[level])) |
1197 | BUG(); | 1066 | BUG(); |
@@ -1224,14 +1093,12 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
1224 | int wret; | 1093 | int wret; |
1225 | int pslot; | 1094 | int pslot; |
1226 | int orig_slot = path->slots[level]; | 1095 | int orig_slot = path->slots[level]; |
1227 | u64 orig_ptr; | ||
1228 | 1096 | ||
1229 | if (level == 0) | 1097 | if (level == 0) |
1230 | return 1; | 1098 | return 1; |
1231 | 1099 | ||
1232 | mid = path->nodes[level]; | 1100 | mid = path->nodes[level]; |
1233 | WARN_ON(btrfs_header_generation(mid) != trans->transid); | 1101 | WARN_ON(btrfs_header_generation(mid) != trans->transid); |
1234 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); | ||
1235 | 1102 | ||
1236 | if (level < BTRFS_MAX_LEVEL - 1) | 1103 | if (level < BTRFS_MAX_LEVEL - 1) |
1237 | parent = path->nodes[level + 1]; | 1104 | parent = path->nodes[level + 1]; |
@@ -1355,11 +1222,13 @@ static void reada_for_search(struct btrfs_root *root, | |||
1355 | u64 search; | 1222 | u64 search; |
1356 | u64 target; | 1223 | u64 target; |
1357 | u64 nread = 0; | 1224 | u64 nread = 0; |
1225 | u64 gen; | ||
1358 | int direction = path->reada; | 1226 | int direction = path->reada; |
1359 | struct extent_buffer *eb; | 1227 | struct extent_buffer *eb; |
1360 | u32 nr; | 1228 | u32 nr; |
1361 | u32 blocksize; | 1229 | u32 blocksize; |
1362 | u32 nscan = 0; | 1230 | u32 nscan = 0; |
1231 | bool map = true; | ||
1363 | 1232 | ||
1364 | if (level != 1) | 1233 | if (level != 1) |
1365 | return; | 1234 | return; |
@@ -1381,7 +1250,19 @@ static void reada_for_search(struct btrfs_root *root, | |||
1381 | 1250 | ||
1382 | nritems = btrfs_header_nritems(node); | 1251 | nritems = btrfs_header_nritems(node); |
1383 | nr = slot; | 1252 | nr = slot; |
1253 | if (node->map_token || path->skip_locking) | ||
1254 | map = false; | ||
1255 | |||
1384 | while (1) { | 1256 | while (1) { |
1257 | if (map && !node->map_token) { | ||
1258 | unsigned long offset = btrfs_node_key_ptr_offset(nr); | ||
1259 | map_private_extent_buffer(node, offset, | ||
1260 | sizeof(struct btrfs_key_ptr), | ||
1261 | &node->map_token, | ||
1262 | &node->kaddr, | ||
1263 | &node->map_start, | ||
1264 | &node->map_len, KM_USER1); | ||
1265 | } | ||
1385 | if (direction < 0) { | 1266 | if (direction < 0) { |
1386 | if (nr == 0) | 1267 | if (nr == 0) |
1387 | break; | 1268 | break; |
@@ -1399,14 +1280,23 @@ static void reada_for_search(struct btrfs_root *root, | |||
1399 | search = btrfs_node_blockptr(node, nr); | 1280 | search = btrfs_node_blockptr(node, nr); |
1400 | if ((search <= target && target - search <= 65536) || | 1281 | if ((search <= target && target - search <= 65536) || |
1401 | (search > target && search - target <= 65536)) { | 1282 | (search > target && search - target <= 65536)) { |
1402 | readahead_tree_block(root, search, blocksize, | 1283 | gen = btrfs_node_ptr_generation(node, nr); |
1403 | btrfs_node_ptr_generation(node, nr)); | 1284 | if (map && node->map_token) { |
1285 | unmap_extent_buffer(node, node->map_token, | ||
1286 | KM_USER1); | ||
1287 | node->map_token = NULL; | ||
1288 | } | ||
1289 | readahead_tree_block(root, search, blocksize, gen); | ||
1404 | nread += blocksize; | 1290 | nread += blocksize; |
1405 | } | 1291 | } |
1406 | nscan++; | 1292 | nscan++; |
1407 | if ((nread > 65536 || nscan > 32)) | 1293 | if ((nread > 65536 || nscan > 32)) |
1408 | break; | 1294 | break; |
1409 | } | 1295 | } |
1296 | if (map && node->map_token) { | ||
1297 | unmap_extent_buffer(node, node->map_token, KM_USER1); | ||
1298 | node->map_token = NULL; | ||
1299 | } | ||
1410 | } | 1300 | } |
1411 | 1301 | ||
1412 | /* | 1302 | /* |
@@ -1454,7 +1344,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, | |||
1454 | ret = -EAGAIN; | 1344 | ret = -EAGAIN; |
1455 | 1345 | ||
1456 | /* release the whole path */ | 1346 | /* release the whole path */ |
1457 | btrfs_release_path(root, path); | 1347 | btrfs_release_path(path); |
1458 | 1348 | ||
1459 | /* read the blocks */ | 1349 | /* read the blocks */ |
1460 | if (block1) | 1350 | if (block1) |
@@ -1577,13 +1467,33 @@ read_block_for_search(struct btrfs_trans_handle *trans, | |||
1577 | blocksize = btrfs_level_size(root, level - 1); | 1467 | blocksize = btrfs_level_size(root, level - 1); |
1578 | 1468 | ||
1579 | tmp = btrfs_find_tree_block(root, blocknr, blocksize); | 1469 | tmp = btrfs_find_tree_block(root, blocknr, blocksize); |
1580 | if (tmp && btrfs_buffer_uptodate(tmp, gen)) { | 1470 | if (tmp) { |
1581 | /* | 1471 | if (btrfs_buffer_uptodate(tmp, 0)) { |
1582 | * we found an up to date block without sleeping, return | 1472 | if (btrfs_buffer_uptodate(tmp, gen)) { |
1583 | * right away | 1473 | /* |
1584 | */ | 1474 | * we found an up to date block without |
1585 | *eb_ret = tmp; | 1475 | * sleeping, return |
1586 | return 0; | 1476 | * right away |
1477 | */ | ||
1478 | *eb_ret = tmp; | ||
1479 | return 0; | ||
1480 | } | ||
1481 | /* the pages were up to date, but we failed | ||
1482 | * the generation number check. Do a full | ||
1483 | * read for the generation number that is correct. | ||
1484 | * We must do this without dropping locks so | ||
1485 | * we can trust our generation number | ||
1486 | */ | ||
1487 | free_extent_buffer(tmp); | ||
1488 | tmp = read_tree_block(root, blocknr, blocksize, gen); | ||
1489 | if (tmp && btrfs_buffer_uptodate(tmp, gen)) { | ||
1490 | *eb_ret = tmp; | ||
1491 | return 0; | ||
1492 | } | ||
1493 | free_extent_buffer(tmp); | ||
1494 | btrfs_release_path(p); | ||
1495 | return -EIO; | ||
1496 | } | ||
1587 | } | 1497 | } |
1588 | 1498 | ||
1589 | /* | 1499 | /* |
@@ -1596,12 +1506,11 @@ read_block_for_search(struct btrfs_trans_handle *trans, | |||
1596 | btrfs_unlock_up_safe(p, level + 1); | 1506 | btrfs_unlock_up_safe(p, level + 1); |
1597 | btrfs_set_path_blocking(p); | 1507 | btrfs_set_path_blocking(p); |
1598 | 1508 | ||
1599 | if (tmp) | 1509 | free_extent_buffer(tmp); |
1600 | free_extent_buffer(tmp); | ||
1601 | if (p->reada) | 1510 | if (p->reada) |
1602 | reada_for_search(root, p, level, slot, key->objectid); | 1511 | reada_for_search(root, p, level, slot, key->objectid); |
1603 | 1512 | ||
1604 | btrfs_release_path(NULL, p); | 1513 | btrfs_release_path(p); |
1605 | 1514 | ||
1606 | ret = -EAGAIN; | 1515 | ret = -EAGAIN; |
1607 | tmp = read_tree_block(root, blocknr, blocksize, 0); | 1516 | tmp = read_tree_block(root, blocknr, blocksize, 0); |
@@ -1670,7 +1579,7 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans, | |||
1670 | } | 1579 | } |
1671 | b = p->nodes[level]; | 1580 | b = p->nodes[level]; |
1672 | if (!b) { | 1581 | if (!b) { |
1673 | btrfs_release_path(NULL, p); | 1582 | btrfs_release_path(p); |
1674 | goto again; | 1583 | goto again; |
1675 | } | 1584 | } |
1676 | BUG_ON(btrfs_header_nritems(b) == 1); | 1585 | BUG_ON(btrfs_header_nritems(b) == 1); |
@@ -1760,9 +1669,6 @@ again: | |||
1760 | } | 1669 | } |
1761 | cow_done: | 1670 | cow_done: |
1762 | BUG_ON(!cow && ins_len); | 1671 | BUG_ON(!cow && ins_len); |
1763 | if (level != btrfs_header_level(b)) | ||
1764 | WARN_ON(1); | ||
1765 | level = btrfs_header_level(b); | ||
1766 | 1672 | ||
1767 | p->nodes[level] = b; | 1673 | p->nodes[level] = b; |
1768 | if (!p->skip_locking) | 1674 | if (!p->skip_locking) |
@@ -1784,12 +1690,6 @@ cow_done: | |||
1784 | if (!cow) | 1690 | if (!cow) |
1785 | btrfs_unlock_up_safe(p, level + 1); | 1691 | btrfs_unlock_up_safe(p, level + 1); |
1786 | 1692 | ||
1787 | ret = check_block(root, p, level); | ||
1788 | if (ret) { | ||
1789 | ret = -1; | ||
1790 | goto done; | ||
1791 | } | ||
1792 | |||
1793 | ret = bin_search(b, key, level, &slot); | 1693 | ret = bin_search(b, key, level, &slot); |
1794 | 1694 | ||
1795 | if (level != 0) { | 1695 | if (level != 0) { |
@@ -1866,7 +1766,7 @@ done: | |||
1866 | if (!p->leave_spinning) | 1766 | if (!p->leave_spinning) |
1867 | btrfs_set_path_blocking(p); | 1767 | btrfs_set_path_blocking(p); |
1868 | if (ret < 0) | 1768 | if (ret < 0) |
1869 | btrfs_release_path(root, p); | 1769 | btrfs_release_path(p); |
1870 | return ret; | 1770 | return ret; |
1871 | } | 1771 | } |
1872 | 1772 | ||
@@ -2116,10 +2016,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, | |||
2116 | 2016 | ||
2117 | btrfs_mark_buffer_dirty(c); | 2017 | btrfs_mark_buffer_dirty(c); |
2118 | 2018 | ||
2119 | spin_lock(&root->node_lock); | ||
2120 | old = root->node; | 2019 | old = root->node; |
2121 | root->node = c; | 2020 | rcu_assign_pointer(root->node, c); |
2122 | spin_unlock(&root->node_lock); | ||
2123 | 2021 | ||
2124 | /* the super has an extra ref to root->node */ | 2022 | /* the super has an extra ref to root->node */ |
2125 | free_extent_buffer(old); | 2023 | free_extent_buffer(old); |
@@ -2502,6 +2400,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2502 | btrfs_assert_tree_locked(path->nodes[1]); | 2400 | btrfs_assert_tree_locked(path->nodes[1]); |
2503 | 2401 | ||
2504 | right = read_node_slot(root, upper, slot + 1); | 2402 | right = read_node_slot(root, upper, slot + 1); |
2403 | if (right == NULL) | ||
2404 | return 1; | ||
2405 | |||
2505 | btrfs_tree_lock(right); | 2406 | btrfs_tree_lock(right); |
2506 | btrfs_set_lock_blocking(right); | 2407 | btrfs_set_lock_blocking(right); |
2507 | 2408 | ||
@@ -2548,7 +2449,6 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, | |||
2548 | { | 2449 | { |
2549 | struct btrfs_disk_key disk_key; | 2450 | struct btrfs_disk_key disk_key; |
2550 | struct extent_buffer *right = path->nodes[0]; | 2451 | struct extent_buffer *right = path->nodes[0]; |
2551 | int slot; | ||
2552 | int i; | 2452 | int i; |
2553 | int push_space = 0; | 2453 | int push_space = 0; |
2554 | int push_items = 0; | 2454 | int push_items = 0; |
@@ -2560,8 +2460,6 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, | |||
2560 | u32 this_item_size; | 2460 | u32 this_item_size; |
2561 | u32 old_left_item_size; | 2461 | u32 old_left_item_size; |
2562 | 2462 | ||
2563 | slot = path->slots[1]; | ||
2564 | |||
2565 | if (empty) | 2463 | if (empty) |
2566 | nr = min(right_nritems, max_slot); | 2464 | nr = min(right_nritems, max_slot); |
2567 | else | 2465 | else |
@@ -2755,6 +2653,9 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2755 | btrfs_assert_tree_locked(path->nodes[1]); | 2653 | btrfs_assert_tree_locked(path->nodes[1]); |
2756 | 2654 | ||
2757 | left = read_node_slot(root, path->nodes[1], slot - 1); | 2655 | left = read_node_slot(root, path->nodes[1], slot - 1); |
2656 | if (left == NULL) | ||
2657 | return 1; | ||
2658 | |||
2758 | btrfs_tree_lock(left); | 2659 | btrfs_tree_lock(left); |
2759 | btrfs_set_lock_blocking(left); | 2660 | btrfs_set_lock_blocking(left); |
2760 | 2661 | ||
@@ -3138,7 +3039,7 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, | |||
3138 | struct btrfs_file_extent_item); | 3039 | struct btrfs_file_extent_item); |
3139 | extent_len = btrfs_file_extent_num_bytes(leaf, fi); | 3040 | extent_len = btrfs_file_extent_num_bytes(leaf, fi); |
3140 | } | 3041 | } |
3141 | btrfs_release_path(root, path); | 3042 | btrfs_release_path(path); |
3142 | 3043 | ||
3143 | path->keep_locks = 1; | 3044 | path->keep_locks = 1; |
3144 | path->search_for_split = 1; | 3045 | path->search_for_split = 1; |
@@ -3328,9 +3229,7 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
3328 | struct btrfs_path *path, | 3229 | struct btrfs_path *path, |
3329 | u32 new_size, int from_end) | 3230 | u32 new_size, int from_end) |
3330 | { | 3231 | { |
3331 | int ret = 0; | ||
3332 | int slot; | 3232 | int slot; |
3333 | int slot_orig; | ||
3334 | struct extent_buffer *leaf; | 3233 | struct extent_buffer *leaf; |
3335 | struct btrfs_item *item; | 3234 | struct btrfs_item *item; |
3336 | u32 nritems; | 3235 | u32 nritems; |
@@ -3340,7 +3239,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
3340 | unsigned int size_diff; | 3239 | unsigned int size_diff; |
3341 | int i; | 3240 | int i; |
3342 | 3241 | ||
3343 | slot_orig = path->slots[0]; | ||
3344 | leaf = path->nodes[0]; | 3242 | leaf = path->nodes[0]; |
3345 | slot = path->slots[0]; | 3243 | slot = path->slots[0]; |
3346 | 3244 | ||
@@ -3428,12 +3326,11 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
3428 | btrfs_set_item_size(leaf, item, new_size); | 3326 | btrfs_set_item_size(leaf, item, new_size); |
3429 | btrfs_mark_buffer_dirty(leaf); | 3327 | btrfs_mark_buffer_dirty(leaf); |
3430 | 3328 | ||
3431 | ret = 0; | ||
3432 | if (btrfs_leaf_free_space(root, leaf) < 0) { | 3329 | if (btrfs_leaf_free_space(root, leaf) < 0) { |
3433 | btrfs_print_leaf(root, leaf); | 3330 | btrfs_print_leaf(root, leaf); |
3434 | BUG(); | 3331 | BUG(); |
3435 | } | 3332 | } |
3436 | return ret; | 3333 | return 0; |
3437 | } | 3334 | } |
3438 | 3335 | ||
3439 | /* | 3336 | /* |
@@ -3443,9 +3340,7 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
3443 | struct btrfs_root *root, struct btrfs_path *path, | 3340 | struct btrfs_root *root, struct btrfs_path *path, |
3444 | u32 data_size) | 3341 | u32 data_size) |
3445 | { | 3342 | { |
3446 | int ret = 0; | ||
3447 | int slot; | 3343 | int slot; |
3448 | int slot_orig; | ||
3449 | struct extent_buffer *leaf; | 3344 | struct extent_buffer *leaf; |
3450 | struct btrfs_item *item; | 3345 | struct btrfs_item *item; |
3451 | u32 nritems; | 3346 | u32 nritems; |
@@ -3454,7 +3349,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
3454 | unsigned int old_size; | 3349 | unsigned int old_size; |
3455 | int i; | 3350 | int i; |
3456 | 3351 | ||
3457 | slot_orig = path->slots[0]; | ||
3458 | leaf = path->nodes[0]; | 3352 | leaf = path->nodes[0]; |
3459 | 3353 | ||
3460 | nritems = btrfs_header_nritems(leaf); | 3354 | nritems = btrfs_header_nritems(leaf); |
@@ -3510,12 +3404,11 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
3510 | btrfs_set_item_size(leaf, item, old_size + data_size); | 3404 | btrfs_set_item_size(leaf, item, old_size + data_size); |
3511 | btrfs_mark_buffer_dirty(leaf); | 3405 | btrfs_mark_buffer_dirty(leaf); |
3512 | 3406 | ||
3513 | ret = 0; | ||
3514 | if (btrfs_leaf_free_space(root, leaf) < 0) { | 3407 | if (btrfs_leaf_free_space(root, leaf) < 0) { |
3515 | btrfs_print_leaf(root, leaf); | 3408 | btrfs_print_leaf(root, leaf); |
3516 | BUG(); | 3409 | BUG(); |
3517 | } | 3410 | } |
3518 | return ret; | 3411 | return 0; |
3519 | } | 3412 | } |
3520 | 3413 | ||
3521 | /* | 3414 | /* |
@@ -3675,11 +3568,10 @@ out: | |||
3675 | * to save stack depth by doing the bulk of the work in a function | 3568 | * to save stack depth by doing the bulk of the work in a function |
3676 | * that doesn't call btrfs_search_slot | 3569 | * that doesn't call btrfs_search_slot |
3677 | */ | 3570 | */ |
3678 | static noinline_for_stack int | 3571 | int setup_items_for_insert(struct btrfs_trans_handle *trans, |
3679 | setup_items_for_insert(struct btrfs_trans_handle *trans, | 3572 | struct btrfs_root *root, struct btrfs_path *path, |
3680 | struct btrfs_root *root, struct btrfs_path *path, | 3573 | struct btrfs_key *cpu_key, u32 *data_size, |
3681 | struct btrfs_key *cpu_key, u32 *data_size, | 3574 | u32 total_data, u32 total_size, int nr) |
3682 | u32 total_data, u32 total_size, int nr) | ||
3683 | { | 3575 | { |
3684 | struct btrfs_item *item; | 3576 | struct btrfs_item *item; |
3685 | int i; | 3577 | int i; |
@@ -3763,7 +3655,6 @@ setup_items_for_insert(struct btrfs_trans_handle *trans, | |||
3763 | 3655 | ||
3764 | ret = 0; | 3656 | ret = 0; |
3765 | if (slot == 0) { | 3657 | if (slot == 0) { |
3766 | struct btrfs_disk_key disk_key; | ||
3767 | btrfs_cpu_key_to_disk(&disk_key, cpu_key); | 3658 | btrfs_cpu_key_to_disk(&disk_key, cpu_key); |
3768 | ret = fixup_low_keys(trans, root, path, &disk_key, 1); | 3659 | ret = fixup_low_keys(trans, root, path, &disk_key, 1); |
3769 | } | 3660 | } |
@@ -3787,7 +3678,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, | |||
3787 | struct btrfs_key *cpu_key, u32 *data_size, | 3678 | struct btrfs_key *cpu_key, u32 *data_size, |
3788 | int nr) | 3679 | int nr) |
3789 | { | 3680 | { |
3790 | struct extent_buffer *leaf; | ||
3791 | int ret = 0; | 3681 | int ret = 0; |
3792 | int slot; | 3682 | int slot; |
3793 | int i; | 3683 | int i; |
@@ -3804,7 +3694,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, | |||
3804 | if (ret < 0) | 3694 | if (ret < 0) |
3805 | goto out; | 3695 | goto out; |
3806 | 3696 | ||
3807 | leaf = path->nodes[0]; | ||
3808 | slot = path->slots[0]; | 3697 | slot = path->slots[0]; |
3809 | BUG_ON(slot < 0); | 3698 | BUG_ON(slot < 0); |
3810 | 3699 | ||
@@ -3829,7 +3718,8 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
3829 | unsigned long ptr; | 3718 | unsigned long ptr; |
3830 | 3719 | ||
3831 | path = btrfs_alloc_path(); | 3720 | path = btrfs_alloc_path(); |
3832 | BUG_ON(!path); | 3721 | if (!path) |
3722 | return -ENOMEM; | ||
3833 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); | 3723 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); |
3834 | if (!ret) { | 3724 | if (!ret) { |
3835 | leaf = path->nodes[0]; | 3725 | leaf = path->nodes[0]; |
@@ -4066,7 +3956,7 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
4066 | else | 3956 | else |
4067 | return 1; | 3957 | return 1; |
4068 | 3958 | ||
4069 | btrfs_release_path(root, path); | 3959 | btrfs_release_path(path); |
4070 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 3960 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
4071 | if (ret < 0) | 3961 | if (ret < 0) |
4072 | return ret; | 3962 | return ret; |
@@ -4190,7 +4080,7 @@ find_next_key: | |||
4190 | sret = btrfs_find_next_key(root, path, min_key, level, | 4080 | sret = btrfs_find_next_key(root, path, min_key, level, |
4191 | cache_only, min_trans); | 4081 | cache_only, min_trans); |
4192 | if (sret == 0) { | 4082 | if (sret == 0) { |
4193 | btrfs_release_path(root, path); | 4083 | btrfs_release_path(path); |
4194 | goto again; | 4084 | goto again; |
4195 | } else { | 4085 | } else { |
4196 | goto out; | 4086 | goto out; |
@@ -4206,6 +4096,7 @@ find_next_key: | |||
4206 | } | 4096 | } |
4207 | btrfs_set_path_blocking(path); | 4097 | btrfs_set_path_blocking(path); |
4208 | cur = read_node_slot(root, cur, slot); | 4098 | cur = read_node_slot(root, cur, slot); |
4099 | BUG_ON(!cur); | ||
4209 | 4100 | ||
4210 | btrfs_tree_lock(cur); | 4101 | btrfs_tree_lock(cur); |
4211 | 4102 | ||
@@ -4268,7 +4159,7 @@ next: | |||
4268 | btrfs_node_key_to_cpu(c, &cur_key, slot); | 4159 | btrfs_node_key_to_cpu(c, &cur_key, slot); |
4269 | 4160 | ||
4270 | orig_lowest = path->lowest_level; | 4161 | orig_lowest = path->lowest_level; |
4271 | btrfs_release_path(root, path); | 4162 | btrfs_release_path(path); |
4272 | path->lowest_level = level; | 4163 | path->lowest_level = level; |
4273 | ret = btrfs_search_slot(NULL, root, &cur_key, path, | 4164 | ret = btrfs_search_slot(NULL, root, &cur_key, path, |
4274 | 0, 0); | 4165 | 0, 0); |
@@ -4345,7 +4236,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
4345 | again: | 4236 | again: |
4346 | level = 1; | 4237 | level = 1; |
4347 | next = NULL; | 4238 | next = NULL; |
4348 | btrfs_release_path(root, path); | 4239 | btrfs_release_path(path); |
4349 | 4240 | ||
4350 | path->keep_locks = 1; | 4241 | path->keep_locks = 1; |
4351 | 4242 | ||
@@ -4401,7 +4292,7 @@ again: | |||
4401 | goto again; | 4292 | goto again; |
4402 | 4293 | ||
4403 | if (ret < 0) { | 4294 | if (ret < 0) { |
4404 | btrfs_release_path(root, path); | 4295 | btrfs_release_path(path); |
4405 | goto done; | 4296 | goto done; |
4406 | } | 4297 | } |
4407 | 4298 | ||
@@ -4440,7 +4331,7 @@ again: | |||
4440 | goto again; | 4331 | goto again; |
4441 | 4332 | ||
4442 | if (ret < 0) { | 4333 | if (ret < 0) { |
4443 | btrfs_release_path(root, path); | 4334 | btrfs_release_path(path); |
4444 | goto done; | 4335 | goto done; |
4445 | } | 4336 | } |
4446 | 4337 | ||