The latest kernel version will not report an error through mdadm set_disk_faulty. $ lsblk sdb 8:16 0 10G 0 disk └─md0 9:0 0 19.9G 0 raid0 sdc 8:32 0 10G 0 disk └─md0 9:0 0 19.9G 0 raid0 old kernel: ... $ mdadm /dev/md0 -f /dev/sdb mdadm: set device faulty failed for /dev/sdb: Device or resource busy ... latest kernel: ... $ mdadm /dev/md0 -f /dev/sdb mdadm: set /dev/sdb faulty in /dev/md0 ... The old kernel judges whether the Faulty flag is set in rdev->flags, and returns -EBUSY if not. And The latest kernel only return -EBUSY if the MD_BROKEN flag is set in mddev->flags. raid0 doesn't set error_handler, so MD_BROKEN will not be set, it will return 0. So if error_handler isn't set for a raid type, also return -EBUSY. Fixes: 9631abdbf406 ("md: Set MD_BROKEN for RAID1 and RAID10") Signed-off-by: Wu Guanghao <wuguanghao3@xxxxxxxxxx> --- drivers/md/md.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 927a43db5dfb..b1786ff60d97 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2928,10 +2928,10 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len) int err = -EINVAL; bool need_update_sb = false; - if (cmd_match(buf, "faulty") && rdev->mddev->pers) { - md_error(rdev->mddev, rdev); + if (cmd_match(buf, "faulty") && mddev->pers) { + md_error(mddev, rdev); - if (test_bit(MD_BROKEN, &rdev->mddev->flags)) + if (!mddev->pers->error_handler || test_bit(MD_BROKEN, &mddev->flags)) err = -EBUSY; else err = 0; @@ -7421,7 +7421,7 @@ static int set_disk_faulty(struct mddev *mddev, dev_t dev) err = -ENODEV; else { md_error(mddev, rdev); - if (test_bit(MD_BROKEN, &mddev->flags)) + if (!mddev->pers->error_handler || test_bit(MD_BROKEN, &mddev->flags)) err = -EBUSY; } rcu_read_unlock(); -- 2.27.0 .