It panics when reshaping from raid0 to other raid levels. raid0 sets mddev->private to NULL. It's the reason that causes the problem. Function level_store finds new pers and create new conf, then it calls oldpers->free. In oldpers->free, raid0 sets mddev->private to NULL again. And __md_stop is the right position to set mddev->private to NULL. And this patch also deletes double free memory codes. io_acct_set is free in pers->free. Fixes: 0c031fd37f69 (md: Move alloc/free acct bioset in to personality) Reported-by: Fine Fan <ffan@xxxxxxxxxx> Signed-off-by: Xiao Ni <xni@xxxxxxxxxx> --- drivers/md/md.c | 4 ---- drivers/md/raid0.c | 1 - 2 files changed, 5 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 707e802..55b6412e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5598,8 +5598,6 @@ static void md_free(struct kobject *ko) bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); - if (mddev->level != 1 && mddev->level != 10) - bioset_exit(&mddev->io_acct_set); kfree(mddev); } @@ -6285,8 +6283,6 @@ void md_stop(struct mddev *mddev) __md_stop(mddev); bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); - if (mddev->level != 1 && mddev->level != 10) - bioset_exit(&mddev->io_acct_set); } EXPORT_SYMBOL_GPL(md_stop); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e11701e..5fa0d40 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -362,7 +362,6 @@ static void free_conf(struct mddev *mddev, struct r0conf *conf) kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); - mddev->private = NULL; } static void raid0_free(struct mddev *mddev, void *priv) -- 2.7.5