mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 06:33:34 +00:00
md: refactor mddev_find_or_alloc
Allocate the new mddev first speculatively, which greatly simplifies the code flow. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Song Liu <song@kernel.org>
This commit is contained in:
parent
85c8c3c1f8
commit
d144fe6ff1
@ -784,57 +784,45 @@ static struct mddev *mddev_find(dev_t unit)
|
||||
|
||||
static struct mddev *mddev_find_or_alloc(dev_t unit)
|
||||
{
|
||||
struct mddev *mddev, *new = NULL;
|
||||
struct mddev *mddev = NULL, *new;
|
||||
|
||||
if (unit && MAJOR(unit) != MD_MAJOR)
|
||||
unit &= ~((1<<MdpMinorShift)-1);
|
||||
|
||||
retry:
|
||||
spin_lock(&all_mddevs_lock);
|
||||
|
||||
if (unit) {
|
||||
mddev = mddev_find_locked(unit);
|
||||
if (mddev) {
|
||||
mddev_get(mddev);
|
||||
spin_unlock(&all_mddevs_lock);
|
||||
kfree(new);
|
||||
return mddev;
|
||||
}
|
||||
|
||||
if (new) {
|
||||
list_add(&new->all_mddevs, &all_mddevs);
|
||||
spin_unlock(&all_mddevs_lock);
|
||||
new->hold_active = UNTIL_IOCTL;
|
||||
return new;
|
||||
}
|
||||
} else if (new) {
|
||||
new->unit = mddev_alloc_unit();
|
||||
if (!new->unit) {
|
||||
spin_unlock(&all_mddevs_lock);
|
||||
kfree(new);
|
||||
return NULL;
|
||||
}
|
||||
new->md_minor = MINOR(new->unit);
|
||||
new->hold_active = UNTIL_STOP;
|
||||
list_add(&new->all_mddevs, &all_mddevs);
|
||||
spin_unlock(&all_mddevs_lock);
|
||||
return new;
|
||||
}
|
||||
spin_unlock(&all_mddevs_lock);
|
||||
unit &= ~((1 << MdpMinorShift) - 1);
|
||||
|
||||
new = kzalloc(sizeof(*new), GFP_KERNEL);
|
||||
if (!new)
|
||||
return NULL;
|
||||
|
||||
new->unit = unit;
|
||||
if (MAJOR(unit) == MD_MAJOR)
|
||||
new->md_minor = MINOR(unit);
|
||||
else
|
||||
new->md_minor = MINOR(unit) >> MdpMinorShift;
|
||||
|
||||
mddev_init(new);
|
||||
|
||||
goto retry;
|
||||
spin_lock(&all_mddevs_lock);
|
||||
if (unit) {
|
||||
mddev = mddev_find_locked(unit);
|
||||
if (mddev) {
|
||||
mddev_get(mddev);
|
||||
goto out_free_new;
|
||||
}
|
||||
|
||||
new->unit = unit;
|
||||
if (MAJOR(unit) == MD_MAJOR)
|
||||
new->md_minor = MINOR(unit);
|
||||
else
|
||||
new->md_minor = MINOR(unit) >> MdpMinorShift;
|
||||
new->hold_active = UNTIL_IOCTL;
|
||||
} else {
|
||||
new->unit = mddev_alloc_unit();
|
||||
if (!new->unit)
|
||||
goto out_free_new;
|
||||
new->md_minor = MINOR(new->unit);
|
||||
new->hold_active = UNTIL_STOP;
|
||||
}
|
||||
|
||||
list_add(&new->all_mddevs, &all_mddevs);
|
||||
spin_unlock(&all_mddevs_lock);
|
||||
return new;
|
||||
out_free_new:
|
||||
spin_unlock(&all_mddevs_lock);
|
||||
kfree(new);
|
||||
return mddev;
|
||||
}
|
||||
|
||||
static struct attribute_group md_redundancy_group;
|
||||
|
Loading…
Reference in New Issue
Block a user