Commit ff461e2d authored by Li Nan's avatar Li Nan Committed by Jialin Zhang
Browse files

md: replace invalid function flush_rdev_wq() with flush_workqueue()

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


CVE: NA

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

If we want to remove a device, first we delete it from mddev->disks list,
then init rdev->del_work to put it (see unbind_rdev_from_array()).

flush_rdev_wq() traverses mddev->disks to check if there is any pending
rdev->del_work, if so, flush it. Howerver, rdev will not be in the list of
mddev->disks if rdev->del_work exists, and flush_workqueue() will never be
executed.

Replace it with flush_workqueue() to ensure del_work has been completed
when adding devices.

Fixes: cc1ffe61 ("md: add new workqueue for delete rdev")
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
Reviewed-by: default avatarHou Tao <houtao1@huawei.com>
parent 5fa41917
Loading
Loading
Loading
Loading
+2 −16
Original line number Diff line number Diff line
@@ -4592,20 +4592,6 @@ null_show(struct mddev *mddev, char *page)
	return -EINVAL;
}

/* need to ensure rdev_delayed_delete() has completed */
static void flush_rdev_wq(struct mddev *mddev)
{
	struct md_rdev *rdev;

	rcu_read_lock();
	rdev_for_each_rcu(rdev, mddev)
		if (work_pending(&rdev->del_work)) {
			flush_workqueue(md_rdev_misc_wq);
			break;
		}
	rcu_read_unlock();
}

static ssize_t
new_dev_store(struct mddev *mddev, const char *buf, size_t len)
{
@@ -4633,7 +4619,7 @@ new_dev_store(struct mddev *mddev, const char *buf, size_t len)
	    minor != MINOR(dev))
		return -EOVERFLOW;

	flush_rdev_wq(mddev);
	flush_workqueue(md_rdev_misc_wq);
	err = mddev_lock(mddev);
	if (err)
		return err;
@@ -7647,7 +7633,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
	}

	if (cmd == ADD_NEW_DISK || cmd == HOT_ADD_DISK)
		flush_rdev_wq(mddev);
		flush_workqueue(md_rdev_misc_wq);

	if (cmd == HOT_REMOVE_DISK)
		/* need to ensure recovery thread has run */