Commit d144fe6f authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Song Liu
Browse files

md: refactor mddev_find_or_alloc



Allocate the new mddev first speculatively, which greatly simplifies
the code flow.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarSong Liu <song@kernel.org>
parent 85c8c3c1
Loading
Loading
Loading
Loading
+24 −36
Original line number Diff line number Diff line
@@ -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);
	new = kzalloc(sizeof(*new), GFP_KERNEL);
	if (!new)
		return NULL;
	mddev_init(new);

	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;
			goto out_free_new;
		}

		if (new) {
			list_add(&new->all_mddevs, &all_mddevs);
			spin_unlock(&all_mddevs_lock);
		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;
			return new;
		}
	} else if (new) {
	} else {
		new->unit = mddev_alloc_unit();
		if (!new->unit) {
			spin_unlock(&all_mddevs_lock);
			kfree(new);
			return NULL;
		}
		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);

	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;
	kfree(new);
	return mddev;
}

static struct attribute_group md_redundancy_group;