aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/dev-replace.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2018-03-20 14:51:04 -0400
committerDavid Sterba <dsterba@suse.com>2018-05-28 12:07:24 -0400
commit010a47bde94201d9abdab7ff04bedc17b6e8c357 (patch)
treec47bd9d3bd18895b0e894a8303eb0f73cbd74a6b /fs/btrfs/dev-replace.c
parenta17c95df4cc8ade4e0e7276a04c0cc89505c74d7 (diff)
btrfs: add proper safety check before resuming dev-replace
The device replace is paused by unmount or read only remount, and resumed on next mount or write remount. The exclusive status should be checked properly as it's a global invariant and we must not allow 2 operations run. In this case, the balance can be also paused and resumed under same conditions. It's always checked first so dev-replace could see the EXCL_OP already taken, BUT, the ioctl would never let start both at the same time. Replace the WARN_ON with message and return 0, indicating no error as this is purely theoretical and the user will be informed. Resolving that manually should be possible by waiting for the other operation to finish or cancel the paused state. Reviewed-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: Nikolay Borisov <nborisov@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.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 8531b5dae777..9fe7be7fdbef 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -896,7 +896,17 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
896 } 896 }
897 btrfs_dev_replace_write_unlock(dev_replace); 897 btrfs_dev_replace_write_unlock(dev_replace);
898 898
899 WARN_ON(test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)); 899 /*
900 * This could collide with a paused balance, but the exclusive op logic
901 * should never allow both to start and pause. We don't want to allow
902 * dev-replace to start anyway.
903 */
904 if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
905 btrfs_info(fs_info,
906 "cannot resume dev-replace, other exclusive operation running");
907 return 0;
908 }
909
900 task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl"); 910 task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl");
901 return PTR_ERR_OR_ZERO(task); 911 return PTR_ERR_OR_ZERO(task);
902} 912}