aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c18
1 files changed, 13 insertions, 5 deletions
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