aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c121
1 files changed, 44 insertions, 77 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 02fae7f7e42c..ed504607d8ec 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1089,7 +1089,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
1089 btrfs_set_node_ptr_generation(parent, parent_slot, 1089 btrfs_set_node_ptr_generation(parent, parent_slot,
1090 trans->transid); 1090 trans->transid);
1091 btrfs_mark_buffer_dirty(parent); 1091 btrfs_mark_buffer_dirty(parent);
1092 tree_mod_log_free_eb(root->fs_info, buf); 1092 if (last_ref)
1093 tree_mod_log_free_eb(root->fs_info, buf);
1093 btrfs_free_tree_block(trans, root, buf, parent_start, 1094 btrfs_free_tree_block(trans, root, buf, parent_start,
1094 last_ref); 1095 last_ref);
1095 } 1096 }
@@ -1161,8 +1162,8 @@ __tree_mod_log_oldest_root(struct btrfs_fs_info *fs_info,
1161 * time_seq). 1162 * time_seq).
1162 */ 1163 */
1163static void 1164static void
1164__tree_mod_log_rewind(struct extent_buffer *eb, u64 time_seq, 1165__tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
1165 struct tree_mod_elem *first_tm) 1166 u64 time_seq, struct tree_mod_elem *first_tm)
1166{ 1167{
1167 u32 n; 1168 u32 n;
1168 struct rb_node *next; 1169 struct rb_node *next;
@@ -1172,6 +1173,7 @@ __tree_mod_log_rewind(struct extent_buffer *eb, u64 time_seq,
1172 unsigned long p_size = sizeof(struct btrfs_key_ptr); 1173 unsigned long p_size = sizeof(struct btrfs_key_ptr);
1173 1174
1174 n = btrfs_header_nritems(eb); 1175 n = btrfs_header_nritems(eb);
1176 tree_mod_log_read_lock(fs_info);
1175 while (tm && tm->seq >= time_seq) { 1177 while (tm && tm->seq >= time_seq) {
1176 /* 1178 /*
1177 * all the operations are recorded with the operator used for 1179 * all the operations are recorded with the operator used for
@@ -1226,6 +1228,7 @@ __tree_mod_log_rewind(struct extent_buffer *eb, u64 time_seq,
1226 if (tm->index != first_tm->index) 1228 if (tm->index != first_tm->index)
1227 break; 1229 break;
1228 } 1230 }
1231 tree_mod_log_read_unlock(fs_info);
1229 btrfs_set_header_nritems(eb, n); 1232 btrfs_set_header_nritems(eb, n);
1230} 1233}
1231 1234
@@ -1268,13 +1271,12 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
1268 BUG_ON(!eb_rewin); 1271 BUG_ON(!eb_rewin);
1269 } 1272 }
1270 1273
1271 extent_buffer_get(eb_rewin);
1272 btrfs_tree_read_unlock(eb); 1274 btrfs_tree_read_unlock(eb);
1273 free_extent_buffer(eb); 1275 free_extent_buffer(eb);
1274 1276
1275 extent_buffer_get(eb_rewin); 1277 extent_buffer_get(eb_rewin);
1276 btrfs_tree_read_lock(eb_rewin); 1278 btrfs_tree_read_lock(eb_rewin);
1277 __tree_mod_log_rewind(eb_rewin, time_seq, tm); 1279 __tree_mod_log_rewind(fs_info, eb_rewin, time_seq, tm);
1278 WARN_ON(btrfs_header_nritems(eb_rewin) > 1280 WARN_ON(btrfs_header_nritems(eb_rewin) >
1279 BTRFS_NODEPTRS_PER_BLOCK(fs_info->tree_root)); 1281 BTRFS_NODEPTRS_PER_BLOCK(fs_info->tree_root));
1280 1282
@@ -1350,7 +1352,7 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
1350 btrfs_set_header_generation(eb, old_generation); 1352 btrfs_set_header_generation(eb, old_generation);
1351 } 1353 }
1352 if (tm) 1354 if (tm)
1353 __tree_mod_log_rewind(eb, time_seq, tm); 1355 __tree_mod_log_rewind(root->fs_info, eb, time_seq, tm);
1354 else 1356 else
1355 WARN_ON(btrfs_header_level(eb) != 0); 1357 WARN_ON(btrfs_header_level(eb) != 0);
1356 WARN_ON(btrfs_header_nritems(eb) > BTRFS_NODEPTRS_PER_BLOCK(root)); 1358 WARN_ON(btrfs_header_nritems(eb) > BTRFS_NODEPTRS_PER_BLOCK(root));
@@ -2178,12 +2180,8 @@ static void reada_for_search(struct btrfs_root *root,
2178 } 2180 }
2179} 2181}
2180 2182
2181/* 2183static noinline void reada_for_balance(struct btrfs_root *root,
2182 * returns -EAGAIN if it had to drop the path, or zero if everything was in 2184 struct btrfs_path *path, int level)
2183 * cache
2184 */
2185static noinline int reada_for_balance(struct btrfs_root *root,
2186 struct btrfs_path *path, int level)
2187{ 2185{
2188 int slot; 2186 int slot;
2189 int nritems; 2187 int nritems;
@@ -2192,12 +2190,11 @@ static noinline int reada_for_balance(struct btrfs_root *root,
2192 u64 gen; 2190 u64 gen;
2193 u64 block1 = 0; 2191 u64 block1 = 0;
2194 u64 block2 = 0; 2192 u64 block2 = 0;
2195 int ret = 0;
2196 int blocksize; 2193 int blocksize;
2197 2194
2198 parent = path->nodes[level + 1]; 2195 parent = path->nodes[level + 1];
2199 if (!parent) 2196 if (!parent)
2200 return 0; 2197 return;
2201 2198
2202 nritems = btrfs_header_nritems(parent); 2199 nritems = btrfs_header_nritems(parent);
2203 slot = path->slots[level + 1]; 2200 slot = path->slots[level + 1];
@@ -2224,28 +2221,11 @@ static noinline int reada_for_balance(struct btrfs_root *root,
2224 block2 = 0; 2221 block2 = 0;
2225 free_extent_buffer(eb); 2222 free_extent_buffer(eb);
2226 } 2223 }
2227 if (block1 || block2) {
2228 ret = -EAGAIN;
2229
2230 /* release the whole path */
2231 btrfs_release_path(path);
2232 2224
2233 /* read the blocks */ 2225 if (block1)
2234 if (block1) 2226 readahead_tree_block(root, block1, blocksize, 0);
2235 readahead_tree_block(root, block1, blocksize, 0); 2227 if (block2)
2236 if (block2) 2228 readahead_tree_block(root, block2, blocksize, 0);
2237 readahead_tree_block(root, block2, blocksize, 0);
2238
2239 if (block1) {
2240 eb = read_tree_block(root, block1, blocksize, 0);
2241 free_extent_buffer(eb);
2242 }
2243 if (block2) {
2244 eb = read_tree_block(root, block2, blocksize, 0);
2245 free_extent_buffer(eb);
2246 }
2247 }
2248 return ret;
2249} 2229}
2250 2230
2251 2231
@@ -2359,35 +2339,28 @@ read_block_for_search(struct btrfs_trans_handle *trans,
2359 tmp = btrfs_find_tree_block(root, blocknr, blocksize); 2339 tmp = btrfs_find_tree_block(root, blocknr, blocksize);
2360 if (tmp) { 2340 if (tmp) {
2361 /* first we do an atomic uptodate check */ 2341 /* first we do an atomic uptodate check */
2362 if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) { 2342 if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) {
2363 if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { 2343 *eb_ret = tmp;
2364 /* 2344 return 0;
2365 * we found an up to date block without 2345 }
2366 * sleeping, return
2367 * right away
2368 */
2369 *eb_ret = tmp;
2370 return 0;
2371 }
2372 /* the pages were up to date, but we failed
2373 * the generation number check. Do a full
2374 * read for the generation number that is correct.
2375 * We must do this without dropping locks so
2376 * we can trust our generation number
2377 */
2378 free_extent_buffer(tmp);
2379 btrfs_set_path_blocking(p);
2380 2346
2381 /* now we're allowed to do a blocking uptodate check */ 2347 /* the pages were up to date, but we failed
2382 tmp = read_tree_block(root, blocknr, blocksize, gen); 2348 * the generation number check. Do a full
2383 if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) { 2349 * read for the generation number that is correct.
2384 *eb_ret = tmp; 2350 * We must do this without dropping locks so
2385 return 0; 2351 * we can trust our generation number
2386 } 2352 */
2387 free_extent_buffer(tmp); 2353 btrfs_set_path_blocking(p);
2388 btrfs_release_path(p); 2354
2389 return -EIO; 2355 /* now we're allowed to do a blocking uptodate check */
2356 ret = btrfs_read_buffer(tmp, gen);
2357 if (!ret) {
2358 *eb_ret = tmp;
2359 return 0;
2390 } 2360 }
2361 free_extent_buffer(tmp);
2362 btrfs_release_path(p);
2363 return -EIO;
2391 } 2364 }
2392 2365
2393 /* 2366 /*
@@ -2448,11 +2421,8 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
2448 goto again; 2421 goto again;
2449 } 2422 }
2450 2423
2451 sret = reada_for_balance(root, p, level);
2452 if (sret)
2453 goto again;
2454
2455 btrfs_set_path_blocking(p); 2424 btrfs_set_path_blocking(p);
2425 reada_for_balance(root, p, level);
2456 sret = split_node(trans, root, p, level); 2426 sret = split_node(trans, root, p, level);
2457 btrfs_clear_path_blocking(p, NULL, 0); 2427 btrfs_clear_path_blocking(p, NULL, 0);
2458 2428
@@ -2472,11 +2442,8 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
2472 goto again; 2442 goto again;
2473 } 2443 }
2474 2444
2475 sret = reada_for_balance(root, p, level);
2476 if (sret)
2477 goto again;
2478
2479 btrfs_set_path_blocking(p); 2445 btrfs_set_path_blocking(p);
2446 reada_for_balance(root, p, level);
2480 sret = balance_level(trans, root, p, level); 2447 sret = balance_level(trans, root, p, level);
2481 btrfs_clear_path_blocking(p, NULL, 0); 2448 btrfs_clear_path_blocking(p, NULL, 0);
2482 2449
@@ -3143,7 +3110,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans,
3143 */ 3110 */
3144static noinline int insert_new_root(struct btrfs_trans_handle *trans, 3111static noinline int insert_new_root(struct btrfs_trans_handle *trans,
3145 struct btrfs_root *root, 3112 struct btrfs_root *root,
3146 struct btrfs_path *path, int level, int log_removal) 3113 struct btrfs_path *path, int level)
3147{ 3114{
3148 u64 lower_gen; 3115 u64 lower_gen;
3149 struct extent_buffer *lower; 3116 struct extent_buffer *lower;
@@ -3194,7 +3161,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
3194 btrfs_mark_buffer_dirty(c); 3161 btrfs_mark_buffer_dirty(c);
3195 3162
3196 old = root->node; 3163 old = root->node;
3197 tree_mod_log_set_root_pointer(root, c, log_removal); 3164 tree_mod_log_set_root_pointer(root, c, 0);
3198 rcu_assign_pointer(root->node, c); 3165 rcu_assign_pointer(root->node, c);
3199 3166
3200 /* the super has an extra ref to root->node */ 3167 /* the super has an extra ref to root->node */
@@ -3278,14 +3245,14 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
3278 /* 3245 /*
3279 * trying to split the root, lets make a new one 3246 * trying to split the root, lets make a new one
3280 * 3247 *
3281 * tree mod log: We pass 0 as log_removal parameter to 3248 * tree mod log: We don't log_removal old root in
3282 * insert_new_root, because that root buffer will be kept as a 3249 * insert_new_root, because that root buffer will be kept as a
3283 * normal node. We are going to log removal of half of the 3250 * normal node. We are going to log removal of half of the
3284 * elements below with tree_mod_log_eb_copy. We're holding a 3251 * elements below with tree_mod_log_eb_copy. We're holding a
3285 * tree lock on the buffer, which is why we cannot race with 3252 * tree lock on the buffer, which is why we cannot race with
3286 * other tree_mod_log users. 3253 * other tree_mod_log users.
3287 */ 3254 */
3288 ret = insert_new_root(trans, root, path, level + 1, 0); 3255 ret = insert_new_root(trans, root, path, level + 1);
3289 if (ret) 3256 if (ret)
3290 return ret; 3257 return ret;
3291 } else { 3258 } else {
@@ -3986,7 +3953,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
3986 return -EOVERFLOW; 3953 return -EOVERFLOW;
3987 3954
3988 /* first try to make some room by pushing left and right */ 3955 /* first try to make some room by pushing left and right */
3989 if (data_size) { 3956 if (data_size && path->nodes[1]) {
3990 wret = push_leaf_right(trans, root, path, data_size, 3957 wret = push_leaf_right(trans, root, path, data_size,
3991 data_size, 0, 0); 3958 data_size, 0, 0);
3992 if (wret < 0) 3959 if (wret < 0)
@@ -4005,7 +3972,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
4005 } 3972 }
4006 3973
4007 if (!path->nodes[1]) { 3974 if (!path->nodes[1]) {
4008 ret = insert_new_root(trans, root, path, 1, 1); 3975 ret = insert_new_root(trans, root, path, 1);
4009 if (ret) 3976 if (ret)
4010 return ret; 3977 return ret;
4011 } 3978 }
@@ -4430,7 +4397,7 @@ void btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
4430} 4397}
4431 4398
4432/* 4399/*
4433 * make the item pointed to by the path bigger, data_size is the new size. 4400 * make the item pointed to by the path bigger, data_size is the added size.
4434 */ 4401 */
4435void btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, 4402void btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
4436 u32 data_size) 4403 u32 data_size)