aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c28
-rw-r--r--fs/btrfs/disk-io.c18
-rw-r--r--fs/btrfs/disk-io.h3
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/btrfs/extent_io.c4
-rw-r--r--fs/btrfs/ioctl.h4
-rw-r--r--fs/btrfs/scrub.c7
-rw-r--r--fs/btrfs/tree-log.c2
8 files changed, 47 insertions, 21 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index e801f226d7e0..4106264fbc65 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);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d0c969beaad4..a7ffc88a7dbe 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -323,7 +323,8 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
323 * in the wrong place. 323 * in the wrong place.
324 */ 324 */
325static int verify_parent_transid(struct extent_io_tree *io_tree, 325static int verify_parent_transid(struct extent_io_tree *io_tree,
326 struct extent_buffer *eb, u64 parent_transid) 326 struct extent_buffer *eb, u64 parent_transid,
327 int atomic)
327{ 328{
328 struct extent_state *cached_state = NULL; 329 struct extent_state *cached_state = NULL;
329 int ret; 330 int ret;
@@ -331,6 +332,9 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
331 if (!parent_transid || btrfs_header_generation(eb) == parent_transid) 332 if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
332 return 0; 333 return 0;
333 334
335 if (atomic)
336 return -EAGAIN;
337
334 lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, 338 lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
335 0, &cached_state); 339 0, &cached_state);
336 if (extent_buffer_uptodate(eb) && 340 if (extent_buffer_uptodate(eb) &&
@@ -372,7 +376,8 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
372 ret = read_extent_buffer_pages(io_tree, eb, start, 376 ret = read_extent_buffer_pages(io_tree, eb, start,
373 WAIT_COMPLETE, 377 WAIT_COMPLETE,
374 btree_get_extent, mirror_num); 378 btree_get_extent, mirror_num);
375 if (!ret && !verify_parent_transid(io_tree, eb, parent_transid)) 379 if (!ret && !verify_parent_transid(io_tree, eb,
380 parent_transid, 0))
376 break; 381 break;
377 382
378 /* 383 /*
@@ -1202,7 +1207,7 @@ static int __must_check find_and_setup_root(struct btrfs_root *tree_root,
1202 root->commit_root = NULL; 1207 root->commit_root = NULL;
1203 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 1208 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
1204 blocksize, generation); 1209 blocksize, generation);
1205 if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { 1210 if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) {
1206 free_extent_buffer(root->node); 1211 free_extent_buffer(root->node);
1207 root->node = NULL; 1212 root->node = NULL;
1208 return -EIO; 1213 return -EIO;
@@ -3143,7 +3148,8 @@ int close_ctree(struct btrfs_root *root)
3143 return 0; 3148 return 0;
3144} 3149}
3145 3150
3146int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) 3151int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
3152 int atomic)
3147{ 3153{
3148 int ret; 3154 int ret;
3149 struct inode *btree_inode = buf->pages[0]->mapping->host; 3155 struct inode *btree_inode = buf->pages[0]->mapping->host;
@@ -3153,7 +3159,9 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
3153 return ret; 3159 return ret;
3154 3160
3155 ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf, 3161 ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf,
3156 parent_transid); 3162 parent_transid, atomic);
3163 if (ret == -EAGAIN)
3164 return ret;
3157 return !ret; 3165 return !ret;
3158} 3166}
3159 3167
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index a7ace1a2dd12..ab1830aaf0ed 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -66,7 +66,8 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr);
66void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); 66void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr);
67void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); 67void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root);
68void btrfs_mark_buffer_dirty(struct extent_buffer *buf); 68void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
69int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid); 69int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
70 int atomic);
70int btrfs_set_buffer_uptodate(struct extent_buffer *buf); 71int btrfs_set_buffer_uptodate(struct extent_buffer *buf);
71int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); 72int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid);
72u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len); 73u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 6fc2e6f5aab8..49fd7b66d57b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -6568,7 +6568,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
6568 goto skip; 6568 goto skip;
6569 } 6569 }
6570 6570
6571 if (!btrfs_buffer_uptodate(next, generation)) { 6571 if (!btrfs_buffer_uptodate(next, generation, 0)) {
6572 btrfs_tree_unlock(next); 6572 btrfs_tree_unlock(next);
6573 free_extent_buffer(next); 6573 free_extent_buffer(next);
6574 next = NULL; 6574 next = NULL;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 198c2ba2fa40..c9018a05036e 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4120,6 +4120,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
4120 if (atomic_inc_not_zero(&exists->refs)) { 4120 if (atomic_inc_not_zero(&exists->refs)) {
4121 spin_unlock(&mapping->private_lock); 4121 spin_unlock(&mapping->private_lock);
4122 unlock_page(p); 4122 unlock_page(p);
4123 page_cache_release(p);
4123 mark_extent_buffer_accessed(exists); 4124 mark_extent_buffer_accessed(exists);
4124 goto free_eb; 4125 goto free_eb;
4125 } 4126 }
@@ -4199,8 +4200,7 @@ free_eb:
4199 unlock_page(eb->pages[i]); 4200 unlock_page(eb->pages[i]);
4200 } 4201 }
4201 4202
4202 if (!atomic_dec_and_test(&eb->refs)) 4203 WARN_ON(!atomic_dec_and_test(&eb->refs));
4203 return exists;
4204 btrfs_release_extent_buffer(eb); 4204 btrfs_release_extent_buffer(eb);
4205 return exists; 4205 return exists;
4206} 4206}
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 4f69028a68c4..086e6bdae1c4 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -252,7 +252,7 @@ struct btrfs_data_container {
252 252
253struct btrfs_ioctl_ino_path_args { 253struct btrfs_ioctl_ino_path_args {
254 __u64 inum; /* in */ 254 __u64 inum; /* in */
255 __u32 size; /* in */ 255 __u64 size; /* in */
256 __u64 reserved[4]; 256 __u64 reserved[4];
257 /* struct btrfs_data_container *fspath; out */ 257 /* struct btrfs_data_container *fspath; out */
258 __u64 fspath; /* out */ 258 __u64 fspath; /* out */
@@ -260,7 +260,7 @@ struct btrfs_ioctl_ino_path_args {
260 260
261struct btrfs_ioctl_logical_ino_args { 261struct btrfs_ioctl_logical_ino_args {
262 __u64 logical; /* in */ 262 __u64 logical; /* in */
263 __u32 size; /* in */ 263 __u64 size; /* in */
264 __u64 reserved[4]; 264 __u64 reserved[4];
265 /* struct btrfs_data_container *inodes; out */ 265 /* struct btrfs_data_container *inodes; out */
266 __u64 inodes; 266 __u64 inodes;
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 4f76fc3f8e89..2f3d6f917fb3 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -998,6 +998,7 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev,
998 page = sblock->pagev + page_index; 998 page = sblock->pagev + page_index;
999 page->logical = logical; 999 page->logical = logical;
1000 page->physical = bbio->stripes[mirror_index].physical; 1000 page->physical = bbio->stripes[mirror_index].physical;
1001 /* for missing devices, bdev is NULL */
1001 page->bdev = bbio->stripes[mirror_index].dev->bdev; 1002 page->bdev = bbio->stripes[mirror_index].dev->bdev;
1002 page->mirror_num = mirror_index + 1; 1003 page->mirror_num = mirror_index + 1;
1003 page->page = alloc_page(GFP_NOFS); 1004 page->page = alloc_page(GFP_NOFS);
@@ -1042,6 +1043,12 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
1042 struct scrub_page *page = sblock->pagev + page_num; 1043 struct scrub_page *page = sblock->pagev + page_num;
1043 DECLARE_COMPLETION_ONSTACK(complete); 1044 DECLARE_COMPLETION_ONSTACK(complete);
1044 1045
1046 if (page->bdev == NULL) {
1047 page->io_error = 1;
1048 sblock->no_io_error_seen = 0;
1049 continue;
1050 }
1051
1045 BUG_ON(!page->page); 1052 BUG_ON(!page->page);
1046 bio = bio_alloc(GFP_NOFS, 1); 1053 bio = bio_alloc(GFP_NOFS, 1);
1047 if (!bio) 1054 if (!bio)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index d017283ae6f5..eb1ae908582c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -279,7 +279,7 @@ static int process_one_buffer(struct btrfs_root *log,
279 log->fs_info->extent_root, 279 log->fs_info->extent_root,
280 eb->start, eb->len); 280 eb->start, eb->len);
281 281
282 if (btrfs_buffer_uptodate(eb, gen)) { 282 if (btrfs_buffer_uptodate(eb, gen, 0)) {
283 if (wc->write) 283 if (wc->write)
284 btrfs_write_tree_block(eb); 284 btrfs_write_tree_block(eb);
285 if (wc->wait) 285 if (wc->wait)