// SPDX-License-Identifier: GPL-2.0

/*
 * dm-init.c
 * Copyright (C) 2017 The Chromium OS Authors <chromium-os-dev@chromium.org>
 *
 * This file is released under the GPLv2.
 */

#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/device-mapper.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/moduleparam.h>

#define DM_MSG_PREFIX "init"
#define DM_MAX_DEVICES 256
#define DM_MAX_TARGETS 256
#define DM_MAX_STR_SIZE 4096

static char *create;

/*
 * Format: dm-mod.create=<name>,<uuid>,<minor>,<flags>,<table>[,<table>+][;<name>,<uuid>,<minor>,<flags>,<table>[,<table>+]+]
 * Table format: <start_sector> <num_sectors> <target_type> <target_args>
 *
 * See Documentation/device-mapper/dm-init.txt for dm-mod.create="..." format
 * details.
 */

struct dm_device {
	struct dm_ioctl dmi;
	struct dm_target_spec *table[DM_MAX_TARGETS];
	char *target_args_array[DM_MAX_TARGETS];
	struct list_head list;
};

const char * const dm_allowed_targets[] __initconst = {
	"crypt",
	"delay",
	"linear",
	"snapshot-origin",
	"striped",
	"verity",
};

static int __init dm_verify_target_type(const char *target)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(dm_allowed_targets); i++) {
		if (!strcmp(dm_allowed_targets[i], target))
			return 0;
	}
	return -EINVAL;
}

static void __init dm_setup_cleanup(struct list_head *devices)
{
	struct dm_device *dev, *tmp;
	unsigned int i;

	list_for_each_entry_safe(dev, tmp, devices, list) {
		list_del(&dev->list);
		for (i = 0; i < dev->dmi.target_count; i++) {
			kfree(dev->table[i]);
			kfree(dev->target_args_array[i]);
		}
		kfree(dev);
	}
}

/**
 * str_field_delimit - delimit a string based on a separator char.
 * @str: the pointer to the string to delimit.
 * @separator: char that delimits the field
 *
 * Find a @separator and replace it by '\0'.
 * Remove leading and trailing spaces.
 * Return the remainder string after the @separator.
 */
static char __init *str_field_delimit(char **str, char separator)
{
	char *s;

	/* TODO: add support for escaped characters */
	*str = skip_spaces(*str);
	s = strchr(*str, separator);
	/* Delimit the field and remove trailing spaces */
	if (s)
		*s = '\0';
	*str = strim(*str);
	return s ? ++s : NULL;
}

/**
 * dm_parse_table_entry - parse a table entry
 * @dev: device to store the parsed information.
 * @str: the pointer to a string with the format:
 *	<start_sector> <num_sectors> <target_type> <target_args>[, ...]
 *
 * Return the remainder string after the table entry, i.e, after the comma which
 * delimits the entry or NULL if reached the end of the string.
 */
static char __init *dm_parse_table_entry(struct dm_device *dev, char *str)
{
	const unsigned int n = dev->dmi.target_count - 1;
	struct dm_target_spec *sp;
	unsigned int i;
	/* fields:  */
	char *field[4];
	char *next;

	field[0] = str;
	/* Delimit first 3 fields that are separated by space */
	for (i = 0; i < ARRAY_SIZE(field) - 1; i++) {
		field[i + 1] = str_field_delimit(&field[i], ' ');
		if (!field[i + 1])
			return ERR_PTR(-EINVAL);
	}
	/* Delimit last field that can be terminated by comma */
	next = str_field_delimit(&field[i], ',');

	sp = kzalloc(sizeof(*sp), GFP_KERNEL);
	if (!sp)
		return ERR_PTR(-ENOMEM);
	dev->table[n] = sp;

	/* start_sector */
	if (kstrtoull(field[0], 0, &sp->sector_start))
		return ERR_PTR(-EINVAL);
	/* num_sector */
	if (kstrtoull(field[1], 0, &sp->length))
		return ERR_PTR(-EINVAL);
	/* target_type */
	strscpy(sp->target_type, field[2], sizeof(sp->target_type));
	if (dm_verify_target_type(sp->target_type)) {
		DMERR("invalid type \"%s\"", sp->target_type);
		return ERR_PTR(-EINVAL);
	}
	/* target_args */
	dev->target_args_array[n] = kstrndup(field[3], GFP_KERNEL,
					     DM_MAX_STR_SIZE);
	if (!dev->target_args_array[n])
		return ERR_PTR(-ENOMEM);

	return next;
}

/**
 * dm_parse_table - parse "dm-mod.create=" table field
 * @dev: device to store the parsed information.
 * @str: the pointer to a string with the format:
 *	<table>[,<table>+]
 */
static int __init dm_parse_table(struct dm_device *dev, char *str)
{
	char *table_entry = str;

	while (table_entry) {
		DMDEBUG("parsing table \"%s\"", str);
		if (++dev->dmi.target_count >= DM_MAX_TARGETS) {
			DMERR("too many targets %u > %d",
			      dev->dmi.target_count, DM_MAX_TARGETS);
			return -EINVAL;
		}
		table_entry = dm_parse_table_entry(dev, table_entry);
		if (IS_ERR(table_entry)) {
			DMERR("couldn't parse table");
			return PTR_ERR(table_entry);
		}
	}

	return 0;
}

/**
 * dm_parse_device_entry - parse a device entry
 * @dev: device to store the parsed information.
 * @str: the pointer to a string with the format:
 *	name,uuid,minor,flags,table[; ...]
 *
 * Return the remainder string after the table entry, i.e, after the semi-colon
 * which delimits the entry or NULL if reached the end of the string.
 */
static char __init *dm_parse_device_entry(struct dm_device *dev, char *str)
{
	/* There are 5 fields: name,uuid,minor,flags,table; */
	char *field[5];
	unsigned int i;
	char *next;

	field[0] = str;
	/* Delimit first 4 fields that are separated by comma */
	for (i = 0; i < ARRAY_SIZE(field) - 1; i++) {
		field[i+1] = str_field_delimit(&field[i], ',');
		if (!field[i+1])
			return ERR_PTR(-EINVAL);
	}
	/* Delimit last field that can be delimited by semi-colon */
	next = str_field_delimit(&field[i], ';');

	/* name */
	strscpy(dev->dmi.name, field[0], sizeof(dev->dmi.name));
	/* uuid */
	strscpy(dev->dmi.uuid, field[1], sizeof(dev->dmi.uuid));
	/* minor */
	if (strlen(field[2])) {
		if (kstrtoull(field[2], 0, &dev->dmi.dev))
			return ERR_PTR(-EINVAL);
		dev->dmi.flags |= DM_PERSISTENT_DEV_FLAG;
	}
	/* flags */
	if (!strcmp(field[3], "ro"))
		dev->dmi.flags |= DM_READONLY_FLAG;
	else if (strcmp(field[3], "rw"))
		return ERR_PTR(-EINVAL);
	/* table */
	if (dm_parse_table(dev, field[4]))
		return ERR_PTR(-EINVAL);

	return next;
}

/**
 * dm_parse_devices - parse "dm-mod.create=" argument
 * @devices: list of struct dm_device to store the parsed information.
 * @str: the pointer to a string with the format:
 *	<device>[;<device>+]
 */
static int __init dm_parse_devices(struct list_head *devices, char *str)
{
	unsigned long ndev = 0;
	struct dm_device *dev;
	char *device = str;

	DMDEBUG("parsing \"%s\"", str);
	while (device) {
		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev)
			return -ENOMEM;
		list_add_tail(&dev->list, devices);

		if (++ndev >= DM_MAX_DEVICES) {
			DMERR("too many targets %u > %d",
			      dev->dmi.target_count, DM_MAX_TARGETS);
			return -EINVAL;
		}

		device = dm_parse_device_entry(dev, device);
		if (IS_ERR(device)) {
			DMERR("couldn't parse device");
			return PTR_ERR(device);
		}
	}

	return 0;
}

/**
 * dm_init_init - parse "dm-mod.create=" argument and configure drivers
 */
static int __init dm_init_init(void)
{
	struct dm_device *dev;
	LIST_HEAD(devices);
	char *str;
	int r;

	if (!create)
		return 0;

	if (strlen(create) >= DM_MAX_STR_SIZE) {
		DMERR("Argument is too big. Limit is %d\n", DM_MAX_STR_SIZE);
		return -EINVAL;
	}
	str = kstrndup(create, GFP_KERNEL, DM_MAX_STR_SIZE);
	if (!str)
		return -ENOMEM;

	r = dm_parse_devices(&devices, str);
	if (r)
		goto out;

	DMINFO("waiting for all devices to be available before creating mapped devices\n");
	wait_for_device_probe();

	list_for_each_entry(dev, &devices, list) {
		if (dm_early_create(&dev->dmi, dev->table,
				    dev->target_args_array))
			break;
	}
out:
	kfree(str);
	dm_setup_cleanup(&devices);
	return r;
}

late_initcall(dm_init_init);

module_param(create, charp, 0);
MODULE_PARM_DESC(create, "Create a mapped device in early boot");
