OSDN Git Service

btrfs: dev-replace: set result code of cancel by status of scrub
authorAnand Jain <anand.jain@oracle.com>
Sun, 11 Nov 2018 14:22:20 +0000 (22:22 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2019 08:20:21 +0000 (09:20 +0100)
[ Upstream commit b47dda2ef6d793b67fd5979032dcd106e3f0a5c9 ]

The device-replace needs to check the result code of the scrub workers
in btrfs_dev_replace_cancel and distinguish if successful cancel
operation and when the there was no operation running.

If btrfs_scrub_cancel() fails, return
BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED so that user can try
to cancel the replace again.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ update changelog ]
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/btrfs/dev-replace.c

index 23b13fb..9676380 100644 (file)
@@ -810,16 +810,23 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
                btrfs_dev_replace_write_unlock(dev_replace);
                break;
        case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
-               result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
                tgt_device = dev_replace->tgtdev;
                src_device = dev_replace->srcdev;
                btrfs_dev_replace_write_unlock(dev_replace);
-               btrfs_scrub_cancel(fs_info);
-               /* btrfs_dev_replace_finishing() will handle the cleanup part */
-               btrfs_info_in_rcu(fs_info,
-                       "dev_replace from %s (devid %llu) to %s canceled",
-                       btrfs_dev_name(src_device), src_device->devid,
-                       btrfs_dev_name(tgt_device));
+               ret = btrfs_scrub_cancel(fs_info);
+               if (ret < 0) {
+                       result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED;
+               } else {
+                       result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
+                       /*
+                        * btrfs_dev_replace_finishing() will handle the
+                        * cleanup part
+                        */
+                       btrfs_info_in_rcu(fs_info,
+                               "dev_replace from %s (devid %llu) to %s canceled",
+                               btrfs_dev_name(src_device), src_device->devid,
+                               btrfs_dev_name(tgt_device));
+               }
                break;
        case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
                /*