summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/dev-replace.c
diff options
context:
space:
mode:
authorNikolay Borisov <nborisov@suse.com>2019-05-14 06:54:41 -0400
committerDavid Sterba <dsterba@suse.com>2019-07-01 07:34:54 -0400
commite1e0eb43ce1fd7bbdd9590715623cb3799896434 (patch)
tree95ada1ff7ea829e189ae386955b9acdc392db0a9 /fs/btrfs/dev-replace.c
parent419684b2c217d2eba6a4a4cf0548c346be7879d7 (diff)
btrfs: Ensure btrfs_init_dev_replace_tgtdev sees up to date values
btrfs_init_dev_replace_tgtdev reads certain values from the source device (such as commit_total_bytes) which are updated during transaction commit. Currently this function is called before committing any pending transaction, leading to possibly reading outdated values. Fix this by moving the function below the transaction commit, at this point the EXCL_OP bit it set hence once transaction is complete the total size of the device cannot be changed (it's usually changed by resize/remove ops which are blocked). Fixes: 9e271ae27e44 ("Btrfs: kernel operation should come after user input has been verified") Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r--fs/btrfs/dev-replace.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index eb8b5cb2c40d..149e6139182b 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -414,11 +414,6 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
414 return -ETXTBSY; 414 return -ETXTBSY;
415 } 415 }
416 416
417 ret = btrfs_init_dev_replace_tgtdev(fs_info, tgtdev_name,
418 src_device, &tgt_device);
419 if (ret)
420 return ret;
421
422 /* 417 /*
423 * Here we commit the transaction to make sure commit_total_bytes 418 * Here we commit the transaction to make sure commit_total_bytes
424 * of all the devices are updated. 419 * of all the devices are updated.
@@ -432,6 +427,11 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
432 return PTR_ERR(trans); 427 return PTR_ERR(trans);
433 } 428 }
434 429
430 ret = btrfs_init_dev_replace_tgtdev(fs_info, tgtdev_name,
431 src_device, &tgt_device);
432 if (ret)
433 return ret;
434
435 need_unlock = true; 435 need_unlock = true;
436 down_write(&dev_replace->rwsem); 436 down_write(&dev_replace->rwsem);
437 switch (dev_replace->replace_state) { 437 switch (dev_replace->replace_state) {