md/raid5: Cleanup setup_conf() error returns
Be more careful about the error returns. Most errors in this function are actually ENOMEM, but it forcibly returns EIO if conf has been allocated. Instead return ret and ensure it is set appropriately before each goto abort. Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Song Liu <song@kernel.org>
This commit is contained in:
parent
92d9aac92b
commit
8fbcba6b99
1 changed files with 11 additions and 7 deletions
|
@ -7163,7 +7163,7 @@ static struct r5conf *setup_conf(struct mddev *mddev)
|
||||||
int i;
|
int i;
|
||||||
int group_cnt;
|
int group_cnt;
|
||||||
struct r5worker_group *new_group;
|
struct r5worker_group *new_group;
|
||||||
int ret;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
if (mddev->new_level != 5
|
if (mddev->new_level != 5
|
||||||
&& mddev->new_level != 4
|
&& mddev->new_level != 4
|
||||||
|
@ -7222,6 +7222,7 @@ static struct r5conf *setup_conf(struct mddev *mddev)
|
||||||
spin_lock_init(&conf->device_lock);
|
spin_lock_init(&conf->device_lock);
|
||||||
seqcount_spinlock_init(&conf->gen_lock, &conf->device_lock);
|
seqcount_spinlock_init(&conf->gen_lock, &conf->device_lock);
|
||||||
mutex_init(&conf->cache_size_mutex);
|
mutex_init(&conf->cache_size_mutex);
|
||||||
|
|
||||||
init_waitqueue_head(&conf->wait_for_quiescent);
|
init_waitqueue_head(&conf->wait_for_quiescent);
|
||||||
init_waitqueue_head(&conf->wait_for_stripe);
|
init_waitqueue_head(&conf->wait_for_stripe);
|
||||||
init_waitqueue_head(&conf->wait_for_overlap);
|
init_waitqueue_head(&conf->wait_for_overlap);
|
||||||
|
@ -7299,11 +7300,13 @@ static struct r5conf *setup_conf(struct mddev *mddev)
|
||||||
|
|
||||||
conf->level = mddev->new_level;
|
conf->level = mddev->new_level;
|
||||||
conf->chunk_sectors = mddev->new_chunk_sectors;
|
conf->chunk_sectors = mddev->new_chunk_sectors;
|
||||||
if (raid5_alloc_percpu(conf) != 0)
|
ret = raid5_alloc_percpu(conf);
|
||||||
|
if (ret)
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
pr_debug("raid456: run(%s) called.\n", mdname(mddev));
|
pr_debug("raid456: run(%s) called.\n", mdname(mddev));
|
||||||
|
|
||||||
|
ret = -EIO;
|
||||||
rdev_for_each(rdev, mddev) {
|
rdev_for_each(rdev, mddev) {
|
||||||
raid_disk = rdev->raid_disk;
|
raid_disk = rdev->raid_disk;
|
||||||
if (raid_disk >= max_disks
|
if (raid_disk >= max_disks
|
||||||
|
@ -7367,6 +7370,7 @@ static struct r5conf *setup_conf(struct mddev *mddev)
|
||||||
if (grow_stripes(conf, conf->min_nr_stripes)) {
|
if (grow_stripes(conf, conf->min_nr_stripes)) {
|
||||||
pr_warn("md/raid:%s: couldn't allocate %dkB for buffers\n",
|
pr_warn("md/raid:%s: couldn't allocate %dkB for buffers\n",
|
||||||
mdname(mddev), memory);
|
mdname(mddev), memory);
|
||||||
|
ret = -ENOMEM;
|
||||||
goto abort;
|
goto abort;
|
||||||
} else
|
} else
|
||||||
pr_debug("md/raid:%s: allocated %dkB\n", mdname(mddev), memory);
|
pr_debug("md/raid:%s: allocated %dkB\n", mdname(mddev), memory);
|
||||||
|
@ -7380,7 +7384,8 @@ static struct r5conf *setup_conf(struct mddev *mddev)
|
||||||
conf->shrinker.count_objects = raid5_cache_count;
|
conf->shrinker.count_objects = raid5_cache_count;
|
||||||
conf->shrinker.batch = 128;
|
conf->shrinker.batch = 128;
|
||||||
conf->shrinker.flags = 0;
|
conf->shrinker.flags = 0;
|
||||||
if (register_shrinker(&conf->shrinker)) {
|
ret = register_shrinker(&conf->shrinker);
|
||||||
|
if (ret) {
|
||||||
pr_warn("md/raid:%s: couldn't register shrinker.\n",
|
pr_warn("md/raid:%s: couldn't register shrinker.\n",
|
||||||
mdname(mddev));
|
mdname(mddev));
|
||||||
goto abort;
|
goto abort;
|
||||||
|
@ -7391,17 +7396,16 @@ static struct r5conf *setup_conf(struct mddev *mddev)
|
||||||
if (!conf->thread) {
|
if (!conf->thread) {
|
||||||
pr_warn("md/raid:%s: couldn't allocate thread.\n",
|
pr_warn("md/raid:%s: couldn't allocate thread.\n",
|
||||||
mdname(mddev));
|
mdname(mddev));
|
||||||
|
ret = -ENOMEM;
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
if (conf) {
|
if (conf)
|
||||||
free_conf(conf);
|
free_conf(conf);
|
||||||
return ERR_PTR(-EIO);
|
return ERR_PTR(ret);
|
||||||
} else
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int only_parity(int raid_disk, int algo, int raid_disks, int max_degraded)
|
static int only_parity(int raid_disk, int algo, int raid_disks, int max_degraded)
|
||||||
|
|
Loading…
Add table
Reference in a new issue