Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md: close race between removing and adding a device.

When we remove a device from an md array, the final removal of
the "dev-XX" sys entry is run asynchronously.
If we then re-add that device immediately before the worker thread
gets to run, we can end up trying to add the "dev-XX" sysfs entry back
before it has been removed.

So in both places where we add a device, call
flush_workqueue(md_misc_wq);
before taking the md lock (as holding the md lock can prevent removal
to complete).

Signed-off-by: NeilBrown <neilb@suse.de>

NeilBrown a7a3f08d 1f3c9907

+6
+6
drivers/md/md.c
··· 4752 4752 } 4753 4753 mddev_get(mddev); 4754 4754 spin_unlock(&all_mddevs_lock); 4755 + if (entry->store == new_dev_store) 4756 + flush_workqueue(md_misc_wq); 4755 4757 rv = mddev_lock(mddev); 4756 4758 if (!rv) { 4757 4759 rv = entry->store(mddev, page, length); ··· 6398 6396 err = set_disk_faulty(mddev, new_decode_dev(arg)); 6399 6397 goto abort; 6400 6398 } 6399 + 6400 + if (cmd == ADD_NEW_DISK) 6401 + /* need to ensure md_delayed_delete() has completed */ 6402 + flush_workqueue(md_misc_wq); 6401 6403 6402 6404 err = mddev_lock(mddev); 6403 6405 if (err) {