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.c55
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 */
214static void add_root_to_dirty_list(struct btrfs_root *root) 214static 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
2612int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, 2617int 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 */