device replace could fail due to another running scrub process or any other errors btrfs_scrub_dev() may hit, but this failure doesn't get returned to userspace. The following steps could reproduce this issue mkfs -t btrfs -f /dev/sdb1 /dev/sdb2 mount /dev/sdb1 /mnt/btrfs while true; do btrfs scrub start -B /mnt/btrfs >/dev/null 2>&1; done & btrfs replace start -Bf /dev/sdb2 /dev/sdb3 /mnt/btrfs # if this replace succeeded, do the following and repeat until # you see this log in dmesg # BTRFS: btrfs_scrub_dev(/dev/sdb2, 2, /dev/sdb3) failed -115 #btrfs replace start -Bf /dev/sdb3 /dev/sdb2 /mnt/btrfs # once you see the error log in dmesg, check return value of # replace echo $? Introduce a new dev replace result BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS to catch -EINPROGRESS explicitly and return other errors directly to userspace.
Showing the changes to include/uapi/linux (1 of 2 files). Show all
Unified · Split
| @@ -157,6 +157,7 @@ struct btrfs_ioctl_dev_replace_status_params { · 156 unmodified lines | |||
| 157 | #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR 0 | 157 | #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR 0 |
| 158 | #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED 1 | 158 | #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED 1 |
| 159 | #define BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED 2 | 159 | #define BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED 2 |
| 160 | #define BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS 3 | ||
| 160 | struct btrfs_ioctl_dev_replace_args { | 161 | struct btrfs_ioctl_dev_replace_args { |
| 161 | __u64 cmd; /* in */ | 162 | __u64 cmd; /* in */ |
| 162 | __u64 result; /* out */ | 163 | __u64 result; /* out */ |