From: Li Nan <linan122@xxxxxxxxxx> Removing a device can trigger WARN_ON in bd_unlink_disk_holder() if creating symlink failed while adding device. WARNING: CPU: 0 PID: 742 at block/holder.c:145 bd_unlink_disk_holder+0x17b/0x1a0 Fix it by adding the flag 'SymlinkCreated', which only be set after creating symlink success. Signed-off-by: Li Nan <linan122@xxxxxxxxxx> --- drivers/md/md.h | 3 +++ drivers/md/md.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.h b/drivers/md/md.h index 8d881cc59799..427d17713a8c 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -207,6 +207,9 @@ enum flag_bits { * check if there is collision between raid1 * serial bios. */ + SymlinkCreated, /* This device has created the symlink + * with gendisk. + */ }; static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors, diff --git a/drivers/md/md.c b/drivers/md/md.c index e05858653a41..d6612b922c76 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2526,7 +2526,8 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev) sysfs_get_dirent_safe(rdev->kobj.sd, "bad_blocks"); list_add_rcu(&rdev->same_set, &mddev->disks); - bd_link_disk_holder(rdev->bdev, mddev->gendisk); + if (!bd_link_disk_holder(rdev->bdev, mddev->gendisk)) + set_bit(SymlinkCreated, &rdev->flags); /* May as well allow recovery to be retried once */ mddev->recovery_disabled++; @@ -2561,7 +2562,10 @@ static void md_kick_rdev_from_array(struct md_rdev *rdev) { struct mddev *mddev = rdev->mddev; - bd_unlink_disk_holder(rdev->bdev, rdev->mddev->gendisk); + if (test_bit(SymlinkCreated, &rdev->flags)) { + bd_unlink_disk_holder(rdev->bdev, rdev->mddev->gendisk); + clear_bit(SymlinkCreated, &rdev->flags); + } list_del_rcu(&rdev->same_set); pr_debug("md: unbind<%pg>\n", rdev->bdev); mddev_destroy_serial_pool(rdev->mddev, rdev); -- 2.39.2