On Mon, Jun 4, 2018 at 12:04 PM Kent Overstreet <kent.overstreet@xxxxxxxxx> wrote: > > However, that's not correct as is because mddev_delayed_put() calls > kobject_put(), and the kobject isn't initialized when the mddev is first > allocated, it's initialized when the gendisk is allocated... that isn't hard to > fix but that's getting into real refactoring that I'll need to put actual work > into testing. Well, it also removes the bioset_exit() calls entirely. How about just the attached? It simply does it as two different cases, and adds the bioset_exit() calls to mddev_delayed_delete(). Hmm? Linus
drivers/md/md.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index fc692b7128bb..6a2494065ab2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -510,11 +510,6 @@ static void mddev_delayed_delete(struct work_struct *ws); static void mddev_put(struct mddev *mddev) { - struct bio_set bs, sync_bs; - - memset(&bs, 0, sizeof(bs)); - memset(&sync_bs, 0, sizeof(sync_bs)); - if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) return; if (!mddev->raid_disks && list_empty(&mddev->disks) && @@ -522,10 +517,6 @@ static void mddev_put(struct mddev *mddev) /* Array is not configured at all, and not held active, * so destroy it */ list_del_init(&mddev->all_mddevs); - bs = mddev->bio_set; - sync_bs = mddev->sync_set; - memset(&mddev->bio_set, 0, sizeof(mddev->bio_set)); - memset(&mddev->sync_set, 0, sizeof(mddev->sync_set)); if (mddev->gendisk) { /* We did a probe so need to clean up. Call * queue_work inside the spinlock so that @@ -534,12 +525,15 @@ static void mddev_put(struct mddev *mddev) */ INIT_WORK(&mddev->del_work, mddev_delayed_delete); queue_work(md_misc_wq, &mddev->del_work); - } else - kfree(mddev); + spin_unlock(&all_mddevs_lock); + return; + } } spin_unlock(&all_mddevs_lock); - bioset_exit(&bs); - bioset_exit(&sync_bs); + + bioset_exit(&mddev->bio_set); + bioset_exit(&mddev->sync_set); + kfree(mddev); } static void md_safemode_timeout(struct timer_list *t); @@ -5234,6 +5228,9 @@ static void mddev_delayed_delete(struct work_struct *ws) { struct mddev *mddev = container_of(ws, struct mddev, del_work); + bioset_exit(&mddev->bio_set); + bioset_exit(&mddev->sync_set); + sysfs_remove_group(&mddev->kobj, &md_bitmap_group); kobject_del(&mddev->kobj); kobject_put(&mddev->kobj);