提交 5815341f 编写于 作者: L Li Nan 提交者: Jialin Zhang

md: fix sysfs duplicate file while adding rdev

hulk inclusion
category: bugfix
bugzilla: 188553, https://gitee.com/openeuler/kernel/issues/I6TNFX
CVE: NA

--------------------------------

rdev->del_work has not been queued to md_rdev_misc_wq and flush_workqueue
will not flush it if tow threads add and remove same device. sysfs might
WARN duplicate filename as below.

    //T1	             //T2
    mdadm write super
			     add success
			     remove
			      unbind_rdev_from_array

    md_ioctl
     flush_workqueue
			      INIT_WORK
                               queue_work
     md_add_new_disk
      duplicate filename dev-xxx

Check if there is any kobj with the same name, and return busy if true.

Fixes: 5792a285 ("md: avoid a deadlock when removing a device from an md array via sysfs")
Signed-off-by: NLi Nan <linan122@huawei.com>
Reviewed-by: NHou Tao <houtao1@huawei.com>
上级 ff461e2d
......@@ -2402,8 +2402,9 @@ EXPORT_SYMBOL(md_integrity_add_rdev);
static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
{
char b[BDEVNAME_SIZE];
char b[BDEVNAME_SIZE + 4];
struct kobject *ko;
struct kernfs_node *sysfs_rdev;
int err;
/* prevent duplicates */
......@@ -2454,7 +2455,8 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
mdname(mddev), mddev->max_disks);
return -EBUSY;
}
bdevname(rdev->bdev,b);
memcpy(b, "dev-", 4);
bdevname(rdev->bdev, b + 4);
strreplace(b, '/', '!');
rdev->mddev = mddev;
......@@ -2463,7 +2465,15 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
if (mddev->raid_disks)
mddev_create_serial_pool(mddev, rdev, false);
if ((err = kobject_add(&rdev->kobj, &mddev->kobj, "dev-%s", b)))
sysfs_rdev = sysfs_get_dirent_safe(mddev->kobj.sd, b);
if (sysfs_rdev) {
sysfs_put(sysfs_rdev);
err = -EBUSY;
goto fail;
}
err = kobject_add(&rdev->kobj, &mddev->kobj, b);
if (err)
goto fail;
ko = &part_to_dev(rdev->bdev->bd_part)->kobj;
......@@ -2484,7 +2494,7 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
return 0;
fail:
pr_warn("md: failed to register dev-%s for %s\n",
pr_warn("md: failed to register %s for %s\n",
b, mdname(mddev));
return err;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册