btrfs-progs: replace: properly enqueue if there's another replace running

Enqueuing allows to let some operations to wait until the current one
finishes. This usually means that it's waiting for another one, but in
case of replace there's a check that does not allow the enqueuing to
take place, as reported.

Move it before that check.

Issue: #645
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2023-07-15 00:01:31 +02:00
parent fedd4cc596
commit c77f2f9f0d
1 changed files with 8 additions and 9 deletions

View File

@ -197,6 +197,14 @@ static int cmd_replace_start(const struct cmd_struct *cmd,
}
zoned = (feature_flags.incompat_flags & BTRFS_FEATURE_INCOMPAT_ZONED);
ret = check_running_fs_exclop(fdmnt, BTRFS_EXCLOP_DEV_REPLACE, enqueue);
if (ret != 0) {
if (ret < 0)
error("unable to check status of exclusive operation: %m");
close_file_or_dir(fdmnt, dirstream);
goto leave_with_error;
}
/* check for possible errors before backgrounding */
status_args.cmd = BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS;
status_args.result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_RESULT;
@ -287,15 +295,6 @@ static int cmd_replace_start(const struct cmd_struct *cmd,
goto leave_with_error;
}
/* Check status before any potentially destructive operation */
ret = check_running_fs_exclop(fdmnt, BTRFS_EXCLOP_DEV_REPLACE, enqueue);
if (ret != 0) {
if (ret < 0)
error("unable to check status of exclusive operation: %m");
close_file_or_dir(fdmnt, dirstream);
goto leave_with_error;
}
strncpy((char *)start_args.start.tgtdev_name, dstdev,
BTRFS_DEVICE_PATH_NAME_MAX);
ret = btrfs_prepare_device(fddstdev, dstdev, &dstdev_block_count, 0,