// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/init_syscalls.h>
#include <linux/raid/detect.h>
#include <linux/raid/md_u.h>
#include <linux/raid/md_p.h>
#include "md.h"

/*
 * When md (and any require personalities) are compiled into the kernel
 * (not a module), arrays can be assembles are boot time using with AUTODETECT
 * where specially marked partitions are registered with md_autodetect_dev(),
 * and with MD_BOOT where devices to be collected are given on the boot line
 * with md=.....
 * The code for that is here.
 */

#ifdef CONFIG_MD_AUTODETECT
static int __initdata raid_noautodetect;
#else
static int __initdata raid_noautodetect=1;
#endif
static int __initdata raid_autopart;

static struct md_setup_args {
	int minor;
	int partitioned;
	int level;
	int chunk;
	char *device_names;
} md_setup_args[256] __initdata;

static int md_setup_ents __initdata;

/*
 * Parse the command-line parameters given our kernel, but do not
 * actually try to invoke the MD device now; that is handled by
 * md_setup_drive after the low-level disk drivers have initialised.
 *
 * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
 *             assigns the task of parsing integer arguments to the
 *             invoked program now).  Added ability to initialise all
 *             the MD devices (by specifying multiple "md=" lines)
 *             instead of just one.  -- KTK
 * 18May2000: Added support for persistent-superblock arrays:
 *             md=n,0,factor,fault,device-list   uses RAID0 for device n
 *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
 *             md=n,device-list      reads a RAID superblock from the devices
 *             elements in device-list are read by name_to_kdev_t so can be
 *             a hex number or something like /dev/hda1 /dev/sdb
 * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
 *		Shifted name_to_kdev_t() and related operations to md_set_drive()
 *		for later execution. Rewrote section to make devfs compatible.
 */
static int __init md_setup(char *str)
{
	int minor, level, factor, fault, partitioned = 0;
	char *pername = "";
	char *str1;
	int ent;

	if (*str == 'd') {
		partitioned = 1;
		str++;
	}
	if (get_option(&str, &minor) != 2) {	/* MD Number */
		printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
		return 0;
	}
	str1 = str;
	for (ent=0 ; ent< md_setup_ents ; ent++)
		if (md_setup_args[ent].minor == minor &&
		    md_setup_args[ent].partitioned == partitioned) {
			printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
			       "Replacing previous definition.\n", partitioned?"d":"", minor);
			break;
		}
	if (ent >= ARRAY_SIZE(md_setup_args)) {
		printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
		return 0;
	}
	if (ent >= md_setup_ents)
		md_setup_ents++;
	switch (get_option(&str, &level)) {	/* RAID level */
	case 2: /* could be 0 or -1.. */
		if (level == 0 || level == LEVEL_LINEAR) {
			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
					get_option(&str, &fault) != 2) {
				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
				return 0;
			}
			md_setup_args[ent].level = level;
			md_setup_args[ent].chunk = 1 << (factor+12);
			if (level ==  LEVEL_LINEAR)
				pername = "linear";
			else
				pername = "raid0";
			break;
		}
		fallthrough;
	case 1: /* the first device is numeric */
		str = str1;
		fallthrough;
	case 0:
		md_setup_args[ent].level = LEVEL_NONE;
		pername="super-block";
	}

	printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
		minor, pername, str);
	md_setup_args[ent].device_names = str;
	md_setup_args[ent].partitioned = partitioned;
	md_setup_args[ent].minor = minor;

	return 1;
}

static void __init md_setup_drive(struct md_setup_args *args)
{
	char *devname = args->device_names;
	dev_t devices[MD_SB_DISKS + 1], mdev;
	struct mdu_array_info_s ainfo = { };
	struct mddev *mddev;
	int err = 0, i;
	char name[16];

	if (args->partitioned) {
		mdev = MKDEV(mdp_major, args->minor << MdpMinorShift);
		sprintf(name, "md_d%d", args->minor);
	} else {
		mdev = MKDEV(MD_MAJOR, args->minor);
		sprintf(name, "md%d", args->minor);
	}

	for (i = 0; i < MD_SB_DISKS && devname != NULL; i++) {
		struct kstat stat;
		char *p;
		char comp_name[64];
		dev_t dev;

		p = strchr(devname, ',');
		if (p)
			*p++ = 0;

		if (early_lookup_bdev(devname, &dev))
			dev = 0;
		if (strncmp(devname, "/dev/", 5) == 0)
			devname += 5;
		snprintf(comp_name, 63, "/dev/%s", devname);
		if (init_stat(comp_name, &stat, 0) == 0 && S_ISBLK(stat.mode))
			dev = new_decode_dev(stat.rdev);
		if (!dev) {
			pr_warn("md: Unknown device name: %s\n", devname);
			break;
		}

		devices[i] = dev;
		devname = p;
	}
	devices[i] = 0;

	if (!i)
		return;

	pr_info("md: Loading %s: %s\n", name, args->device_names);

	mddev = md_alloc(mdev, name);
	if (IS_ERR(mddev)) {
		pr_err("md: md_alloc failed - cannot start array %s\n", name);
		return;
	}

	err = mddev_suspend_and_lock(mddev);
	if (err) {
		pr_err("md: failed to lock array %s\n", name);
		goto out_mddev_put;
	}

	if (!list_empty(&mddev->disks) || mddev->raid_disks) {
		pr_warn("md: Ignoring %s, already autodetected. (Use raid=noautodetect)\n",
		       name);
		goto out_unlock;
	}

	if (args->level != LEVEL_NONE) {
		/* non-persistent */
		ainfo.level = args->level;
		ainfo.md_minor = args->minor;
		ainfo.not_persistent = 1;
		ainfo.state = (1 << MD_SB_CLEAN);
		ainfo.chunk_size = args->chunk;
		while (devices[ainfo.raid_disks])
			ainfo.raid_disks++;
	}

	err = md_set_array_info(mddev, &ainfo);

	for (i = 0; i <= MD_SB_DISKS && devices[i]; i++) {
		struct mdu_disk_info_s dinfo = {
			.major	= MAJOR(devices[i]),
			.minor	= MINOR(devices[i]),
		};

		if (args->level != LEVEL_NONE) {
			dinfo.number = i;
			dinfo.raid_disk = i;
			dinfo.state =
				(1 << MD_DISK_ACTIVE) | (1 << MD_DISK_SYNC);
		}

		md_add_new_disk(mddev, &dinfo);
	}

	if (!err)
		err = do_md_run(mddev);
	if (err)
		pr_warn("md: starting %s failed\n", name);
out_unlock:
	mddev_unlock_and_resume(mddev);
out_mddev_put:
	mddev_put(mddev);
}

static int __init raid_setup(char *str)
{
	int len, pos;

	len = strlen(str) + 1;
	pos = 0;

	while (pos < len) {
		char *comma = strchr(str+pos, ',');
		int wlen;
		if (comma)
			wlen = (comma-str)-pos;
		else	wlen = (len-1)-pos;

		if (!strncmp(str, "noautodetect", wlen))
			raid_noautodetect = 1;
		if (!strncmp(str, "autodetect", wlen))
			raid_noautodetect = 0;
		if (strncmp(str, "partitionable", wlen)==0)
			raid_autopart = 1;
		if (strncmp(str, "part", wlen)==0)
			raid_autopart = 1;
		pos += wlen+1;
	}
	return 1;
}

__setup("raid=", raid_setup);
__setup("md=", md_setup);

static void __init autodetect_raid(void)
{
	/*
	 * Since we don't want to detect and use half a raid array, we need to
	 * wait for the known devices to complete their probing
	 */
	printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
	printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");

	wait_for_device_probe();
	md_autostart_arrays(raid_autopart);
}

void __init md_run_setup(void)
{
	int ent;

	if (raid_noautodetect)
		printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=autodetect will force)\n");
	else
		autodetect_raid();

	for (ent = 0; ent < md_setup_ents; ent++)
		md_setup_drive(&md_setup_args[ent]);
}
