diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 14a72ed14ef7..993642199326 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -213,11 +213,19 @@ static struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root) | |||
213 | */ | 213 | */ |
214 | static void add_root_to_dirty_list(struct btrfs_root *root) | 214 | static void add_root_to_dirty_list(struct btrfs_root *root) |
215 | { | 215 | { |
216 | if (test_bit(BTRFS_ROOT_DIRTY, &root->state) || | ||
217 | !test_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state)) | ||
218 | return; | ||
219 | |||
216 | spin_lock(&root->fs_info->trans_lock); | 220 | spin_lock(&root->fs_info->trans_lock); |
217 | if (test_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state) && | 221 | if (!test_and_set_bit(BTRFS_ROOT_DIRTY, &root->state)) { |
218 | list_empty(&root->dirty_list)) { | 222 | /* Want the extent tree to be the last on the list */ |
219 | list_add(&root->dirty_list, | 223 | if (root->objectid == BTRFS_EXTENT_TREE_OBJECTID) |
220 | &root->fs_info->dirty_cowonly_roots); | 224 | list_move_tail(&root->dirty_list, |
225 | &root->fs_info->dirty_cowonly_roots); | ||
226 | else | ||
227 | list_move(&root->dirty_list, | ||
228 | &root->fs_info->dirty_cowonly_roots); | ||
221 | } | 229 | } |
222 | spin_unlock(&root->fs_info->trans_lock); | 230 | spin_unlock(&root->fs_info->trans_lock); |
223 | } | 231 | } |
@@ -1363,8 +1371,7 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct btrfs_path *path, | |||
1363 | 1371 | ||
1364 | if (tm->op == MOD_LOG_KEY_REMOVE_WHILE_FREEING) { | 1372 | if (tm->op == MOD_LOG_KEY_REMOVE_WHILE_FREEING) { |
1365 | BUG_ON(tm->slot != 0); | 1373 | BUG_ON(tm->slot != 0); |
1366 | eb_rewin = alloc_dummy_extent_buffer(eb->start, | 1374 | eb_rewin = alloc_dummy_extent_buffer(fs_info, eb->start); |
1367 | fs_info->tree_root->nodesize); | ||
1368 | if (!eb_rewin) { | 1375 | if (!eb_rewin) { |
1369 | btrfs_tree_read_unlock_blocking(eb); | 1376 | btrfs_tree_read_unlock_blocking(eb); |
1370 | free_extent_buffer(eb); | 1377 | free_extent_buffer(eb); |
@@ -1444,7 +1451,7 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1444 | } else if (old_root) { | 1451 | } else if (old_root) { |
1445 | btrfs_tree_read_unlock(eb_root); | 1452 | btrfs_tree_read_unlock(eb_root); |
1446 | free_extent_buffer(eb_root); | 1453 | free_extent_buffer(eb_root); |
1447 | eb = alloc_dummy_extent_buffer(logical, root->nodesize); | 1454 | eb = alloc_dummy_extent_buffer(root->fs_info, logical); |
1448 | } else { | 1455 | } else { |
1449 | btrfs_set_lock_blocking_rw(eb_root, BTRFS_READ_LOCK); | 1456 | btrfs_set_lock_blocking_rw(eb_root, BTRFS_READ_LOCK); |
1450 | eb = btrfs_clone_extent_buffer(eb_root); | 1457 | eb = btrfs_clone_extent_buffer(eb_root); |
@@ -2282,7 +2289,7 @@ static void reada_for_search(struct btrfs_root *root, | |||
2282 | if ((search <= target && target - search <= 65536) || | 2289 | if ((search <= target && target - search <= 65536) || |
2283 | (search > target && search - target <= 65536)) { | 2290 | (search > target && search - target <= 65536)) { |
2284 | gen = btrfs_node_ptr_generation(node, nr); | 2291 | gen = btrfs_node_ptr_generation(node, nr); |
2285 | readahead_tree_block(root, search, blocksize); | 2292 | readahead_tree_block(root, search); |
2286 | nread += blocksize; | 2293 | nread += blocksize; |
2287 | } | 2294 | } |
2288 | nscan++; | 2295 | nscan++; |
@@ -2301,7 +2308,6 @@ static noinline void reada_for_balance(struct btrfs_root *root, | |||
2301 | u64 gen; | 2308 | u64 gen; |
2302 | u64 block1 = 0; | 2309 | u64 block1 = 0; |
2303 | u64 block2 = 0; | 2310 | u64 block2 = 0; |
2304 | int blocksize; | ||
2305 | 2311 | ||
2306 | parent = path->nodes[level + 1]; | 2312 | parent = path->nodes[level + 1]; |
2307 | if (!parent) | 2313 | if (!parent) |
@@ -2309,7 +2315,6 @@ static noinline void reada_for_balance(struct btrfs_root *root, | |||
2309 | 2315 | ||
2310 | nritems = btrfs_header_nritems(parent); | 2316 | nritems = btrfs_header_nritems(parent); |
2311 | slot = path->slots[level + 1]; | 2317 | slot = path->slots[level + 1]; |
2312 | blocksize = root->nodesize; | ||
2313 | 2318 | ||
2314 | if (slot > 0) { | 2319 | if (slot > 0) { |
2315 | block1 = btrfs_node_blockptr(parent, slot - 1); | 2320 | block1 = btrfs_node_blockptr(parent, slot - 1); |
@@ -2334,9 +2339,9 @@ static noinline void reada_for_balance(struct btrfs_root *root, | |||
2334 | } | 2339 | } |
2335 | 2340 | ||
2336 | if (block1) | 2341 | if (block1) |
2337 | readahead_tree_block(root, block1, blocksize); | 2342 | readahead_tree_block(root, block1); |
2338 | if (block2) | 2343 | if (block2) |
2339 | readahead_tree_block(root, block2, blocksize); | 2344 | readahead_tree_block(root, block2); |
2340 | } | 2345 | } |
2341 | 2346 | ||
2342 | 2347 | ||
@@ -2609,32 +2614,24 @@ static int key_search(struct extent_buffer *b, struct btrfs_key *key, | |||
2609 | return 0; | 2614 | return 0; |
2610 | } | 2615 | } |
2611 | 2616 | ||
2612 | int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, | 2617 | int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path, |
2613 | u64 iobjectid, u64 ioff, u8 key_type, | 2618 | u64 iobjectid, u64 ioff, u8 key_type, |
2614 | struct btrfs_key *found_key) | 2619 | struct btrfs_key *found_key) |
2615 | { | 2620 | { |
2616 | int ret; | 2621 | int ret; |
2617 | struct btrfs_key key; | 2622 | struct btrfs_key key; |
2618 | struct extent_buffer *eb; | 2623 | struct extent_buffer *eb; |
2619 | struct btrfs_path *path; | 2624 | |
2625 | ASSERT(path); | ||
2626 | ASSERT(found_key); | ||
2620 | 2627 | ||
2621 | key.type = key_type; | 2628 | key.type = key_type; |
2622 | key.objectid = iobjectid; | 2629 | key.objectid = iobjectid; |
2623 | key.offset = ioff; | 2630 | key.offset = ioff; |
2624 | 2631 | ||
2625 | if (found_path == NULL) { | ||
2626 | path = btrfs_alloc_path(); | ||
2627 | if (!path) | ||
2628 | return -ENOMEM; | ||
2629 | } else | ||
2630 | path = found_path; | ||
2631 | |||
2632 | ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0); | 2632 | ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0); |
2633 | if ((ret < 0) || (found_key == NULL)) { | 2633 | if (ret < 0) |
2634 | if (path != found_path) | ||
2635 | btrfs_free_path(path); | ||
2636 | return ret; | 2634 | return ret; |
2637 | } | ||
2638 | 2635 | ||
2639 | eb = path->nodes[0]; | 2636 | eb = path->nodes[0]; |
2640 | if (ret && path->slots[0] >= btrfs_header_nritems(eb)) { | 2637 | if (ret && path->slots[0] >= btrfs_header_nritems(eb)) { |
@@ -3383,7 +3380,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, | |||
3383 | add_root_to_dirty_list(root); | 3380 | add_root_to_dirty_list(root); |
3384 | extent_buffer_get(c); | 3381 | extent_buffer_get(c); |
3385 | path->nodes[level] = c; | 3382 | path->nodes[level] = c; |
3386 | path->locks[level] = BTRFS_WRITE_LOCK; | 3383 | path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; |
3387 | path->slots[level] = 0; | 3384 | path->slots[level] = 0; |
3388 | return 0; | 3385 | return 0; |
3389 | } | 3386 | } |
@@ -4356,13 +4353,15 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, | |||
4356 | path->search_for_split = 1; | 4353 | path->search_for_split = 1; |
4357 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); | 4354 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); |
4358 | path->search_for_split = 0; | 4355 | path->search_for_split = 0; |
4356 | if (ret > 0) | ||
4357 | ret = -EAGAIN; | ||
4359 | if (ret < 0) | 4358 | if (ret < 0) |
4360 | goto err; | 4359 | goto err; |
4361 | 4360 | ||
4362 | ret = -EAGAIN; | 4361 | ret = -EAGAIN; |
4363 | leaf = path->nodes[0]; | 4362 | leaf = path->nodes[0]; |
4364 | /* if our item isn't there or got smaller, return now */ | 4363 | /* if our item isn't there, return now */ |
4365 | if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) | 4364 | if (item_size != btrfs_item_size_nr(leaf, path->slots[0])) |
4366 | goto err; | 4365 | goto err; |
4367 | 4366 | ||
4368 | /* the leaf has changed, it now has room. return now */ | 4367 | /* the leaf has changed, it now has room. return now */ |