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.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index e801f226d7e..4106264fbc6 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -220,10 +220,12 @@ struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
220 */ 220 */
221static void add_root_to_dirty_list(struct btrfs_root *root) 221static void add_root_to_dirty_list(struct btrfs_root *root)
222{ 222{
223 spin_lock(&root->fs_info->trans_lock);
223 if (root->track_dirty && list_empty(&root->dirty_list)) { 224 if (root->track_dirty && list_empty(&root->dirty_list)) {
224 list_add(&root->dirty_list, 225 list_add(&root->dirty_list,
225 &root->fs_info->dirty_cowonly_roots); 226 &root->fs_info->dirty_cowonly_roots);
226 } 227 }
228 spin_unlock(&root->fs_info->trans_lock);
227} 229}
228 230
229/* 231/*
@@ -723,7 +725,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
723 725
724 cur = btrfs_find_tree_block(root, blocknr, blocksize); 726 cur = btrfs_find_tree_block(root, blocknr, blocksize);
725 if (cur) 727 if (cur)
726 uptodate = btrfs_buffer_uptodate(cur, gen); 728 uptodate = btrfs_buffer_uptodate(cur, gen, 0);
727 else 729 else
728 uptodate = 0; 730 uptodate = 0;
729 if (!cur || !uptodate) { 731 if (!cur || !uptodate) {
@@ -1358,7 +1360,12 @@ static noinline int reada_for_balance(struct btrfs_root *root,
1358 block1 = btrfs_node_blockptr(parent, slot - 1); 1360 block1 = btrfs_node_blockptr(parent, slot - 1);
1359 gen = btrfs_node_ptr_generation(parent, slot - 1); 1361 gen = btrfs_node_ptr_generation(parent, slot - 1);
1360 eb = btrfs_find_tree_block(root, block1, blocksize); 1362 eb = btrfs_find_tree_block(root, block1, blocksize);
1361 if (eb && btrfs_buffer_uptodate(eb, gen)) 1363 /*
1364 * if we get -eagain from btrfs_buffer_uptodate, we
1365 * don't want to return eagain here. That will loop
1366 * forever
1367 */
1368 if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
1362 block1 = 0; 1369 block1 = 0;
1363 free_extent_buffer(eb); 1370 free_extent_buffer(eb);
1364 } 1371 }
@@ -1366,7 +1373,7 @@ static noinline int reada_for_balance(struct btrfs_root *root,
1366 block2 = btrfs_node_blockptr(parent, slot + 1); 1373 block2 = btrfs_node_blockptr(parent, slot + 1);
1367 gen = btrfs_node_ptr_generation(parent, slot + 1); 1374 gen = btrfs_node_ptr_generation(parent, slot + 1);
1368 eb = btrfs_find_tree_block(root, block2, blocksize); 1375 eb = btrfs_find_tree_block(root, block2, blocksize);
1369 if (eb && btrfs_buffer_uptodate(eb, gen)) 1376 if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
1370 block2 = 0; 1377 block2 = 0;
1371 free_extent_buffer(eb); 1378 free_extent_buffer(eb);
1372 } 1379 }
@@ -1504,8 +1511,9 @@ read_block_for_search(struct btrfs_trans_handle *trans,
1504 1511
1505 tmp = btrfs_find_tree_block(root, blocknr, blocksize); 1512 tmp = btrfs_find_tree_block(root, blocknr, blocksize);
1506 if (tmp) { 1513 if (tmp) {
1507 if (btrfs_buffer_uptodate(tmp, 0)) { 1514 /* first we do an atomic uptodate check */
1508 if (btrfs_buffer_uptodate(tmp, gen)) { 1515 if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) {
1516 if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) {
1509 /* 1517 /*
1510 * we found an up to date block without 1518 * we found an up to date block without
1511 * sleeping, return 1519 * sleeping, return
@@ -1523,8 +1531,9 @@ read_block_for_search(struct btrfs_trans_handle *trans,
1523 free_extent_buffer(tmp); 1531 free_extent_buffer(tmp);
1524 btrfs_set_path_blocking(p); 1532 btrfs_set_path_blocking(p);
1525 1533
1534 /* now we're allowed to do a blocking uptodate check */
1526 tmp = read_tree_block(root, blocknr, blocksize, gen); 1535 tmp = read_tree_block(root, blocknr, blocksize, gen);
1527 if (tmp && btrfs_buffer_uptodate(tmp, gen)) { 1536 if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) {
1528 *eb_ret = tmp; 1537 *eb_ret = tmp;
1529 return 0; 1538 return 0;
1530 } 1539 }
@@ -1559,7 +1568,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
1559 * and give up so that our caller doesn't loop forever 1568 * and give up so that our caller doesn't loop forever
1560 * on our EAGAINs. 1569 * on our EAGAINs.
1561 */ 1570 */
1562 if (!btrfs_buffer_uptodate(tmp, 0)) 1571 if (!btrfs_buffer_uptodate(tmp, 0, 0))
1563 ret = -EIO; 1572 ret = -EIO;
1564 free_extent_buffer(tmp); 1573 free_extent_buffer(tmp);
1565 } 1574 }
@@ -4043,7 +4052,7 @@ again:
4043 tmp = btrfs_find_tree_block(root, blockptr, 4052 tmp = btrfs_find_tree_block(root, blockptr,
4044 btrfs_level_size(root, level - 1)); 4053 btrfs_level_size(root, level - 1));
4045 4054
4046 if (tmp && btrfs_buffer_uptodate(tmp, gen)) { 4055 if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) {
4047 free_extent_buffer(tmp); 4056 free_extent_buffer(tmp);
4048 break; 4057 break;
4049 } 4058 }
@@ -4166,7 +4175,8 @@ next:
4166 struct extent_buffer *cur; 4175 struct extent_buffer *cur;
4167 cur = btrfs_find_tree_block(root, blockptr, 4176 cur = btrfs_find_tree_block(root, blockptr,
4168 btrfs_level_size(root, level - 1)); 4177 btrfs_level_size(root, level - 1));
4169 if (!cur || !btrfs_buffer_uptodate(cur, gen)) { 4178 if (!cur ||
4179 btrfs_buffer_uptodate(cur, gen, 1) <= 0) {
4170 slot++; 4180 slot++;
4171 if (cur) 4181 if (cur)
4172 free_extent_buffer(cur); 4182 free_extent_buffer(cur);