/* do_mounts_dm.c
 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org>
 *                    All Rights Reserved.
 * Based on do_mounts_md.c
 *
 * This file is released under the GPL.
 */
#include <linux/device-mapper.h>
#include <linux/fs.h>
#include <linux/string.h>

#include "do_mounts.h"

#define DM_MAX_NAME 32
#define DM_MAX_UUID 129
#define DM_NO_UUID "none"

#define DM_MSG_PREFIX "init"

/* Separators used for parsing the dm= argument. */
#define DM_FIELD_SEP ' '
#define DM_LINE_SEP ','

/*
 * When the device-mapper and any targets are compiled into the kernel
 * (not a module), one target may be created and used as the root device at
 * boot time with the parameters given with the boot line dm=...
 * The code for that is here.
 */

struct dm_setup_target {
	sector_t begin;
	sector_t length;
	char *type;
	char *params;
	/* simple singly linked list */
	struct dm_setup_target *next;
};

static struct {
	int minor;
	int ro;
	char name[DM_MAX_NAME];
	char uuid[DM_MAX_UUID];
	char *targets;
	struct dm_setup_target *target;
	int target_count;
} dm_setup_args __initdata;

static __initdata int dm_early_setup;

static size_t __init get_dm_option(char *str, char **next, char sep)
{
	size_t len = 0;
	char *endp = NULL;

	if (!str)
		return 0;

	endp = strchr(str, sep);
	if (!endp) {  /* act like strchrnul */
		len = strlen(str);
		endp = str + len;
	} else {
		len = endp - str;
	}

	if (endp == str)
		return 0;

	if (!next)
		return len;

	if (*endp == 0) {
		/* Don't advance past the nul. */
		*next = endp;
	} else {
		*next = endp + 1;
	}
	return len;
}

static int __init dm_setup_args_init(void)
{
	dm_setup_args.minor = 0;
	dm_setup_args.ro = 0;
	dm_setup_args.target = NULL;
	dm_setup_args.target_count = 0;
	return 0;
}

static int __init dm_setup_cleanup(void)
{
	struct dm_setup_target *target = dm_setup_args.target;
	struct dm_setup_target *old_target = NULL;
	while (target) {
		kfree(target->type);
		kfree(target->params);
		old_target = target;
		target = target->next;
		kfree(old_target);
		dm_setup_args.target_count--;
	}
	BUG_ON(dm_setup_args.target_count);
	return 0;
}

static char * __init dm_setup_parse_device_args(char *str)
{
	char *next = NULL;
	size_t len = 0;

	/* Grab the logical name of the device to be exported to udev */
	len = get_dm_option(str, &next, DM_FIELD_SEP);
	if (!len) {
		DMERR("failed to parse device name");
		goto parse_fail;
	}
	len = min(len + 1, sizeof(dm_setup_args.name));
	strlcpy(dm_setup_args.name, str, len);  /* includes nul */
	str = skip_spaces(next);

	/* Grab the UUID value or "none" */
	len = get_dm_option(str, &next, DM_FIELD_SEP);
	if (!len) {
		DMERR("failed to parse device uuid");
		goto parse_fail;
	}
	len = min(len + 1, sizeof(dm_setup_args.uuid));
	strlcpy(dm_setup_args.uuid, str, len);
	str = skip_spaces(next);

	/* Determine if the table/device will be read only or read-write */
	if (!strncmp("ro,", str, 3)) {
		dm_setup_args.ro = 1;
	} else if (!strncmp("rw,", str, 3)) {
		dm_setup_args.ro = 0;
	} else {
		DMERR("failed to parse table mode");
		goto parse_fail;
	}
	str = skip_spaces(str + 3);

	return str;

parse_fail:
	return NULL;
}

static void __init dm_substitute_devices(char *str, size_t str_len)
{
	char *candidate = str;
	char *candidate_end = str;
	char old_char;
	size_t len = 0;
	dev_t dev;

	if (str_len < 3)
		return;

	while (str && *str) {
		candidate = strchr(str, '/');
		if (!candidate)
			break;

		/* Avoid embedded slashes */
		if (candidate != str && *(candidate - 1) != DM_FIELD_SEP) {
			str = strchr(candidate, DM_FIELD_SEP);
			continue;
		}

		len = get_dm_option(candidate, &candidate_end, DM_FIELD_SEP);
		str = skip_spaces(candidate_end);
		if (len < 3 || len > 37)  /* name_to_dev_t max; maj:mix min */
			continue;

		/* Temporarily terminate with a nul */
		candidate_end--;
		old_char = *candidate_end;
		*candidate_end = '\0';

		DMDEBUG("converting candidate device '%s' to dev_t", candidate);
		/* Use the boot-time specific device naming */
		dev = name_to_dev_t(candidate);
		*candidate_end = old_char;

		DMDEBUG(" -> %u", dev);
		/* No suitable replacement found */
		if (!dev)
			continue;

		/* Rewrite the /dev/path as a major:minor */
		len = snprintf(candidate, len, "%u:%u", MAJOR(dev), MINOR(dev));
		if (!len) {
			DMERR("error substituting device major/minor.");
			break;
		}
		candidate += len;
		/* Pad out with spaces (fixing our nul) */
		while (candidate < candidate_end)
			*(candidate++) = DM_FIELD_SEP;
	}
}

static int __init dm_setup_parse_targets(char *str)
{
	char *next = NULL;
	size_t len = 0;
	struct dm_setup_target **target = NULL;

	/* Targets are defined as per the table format but with a
	 * comma as a newline separator. */
	target = &dm_setup_args.target;
	while (str && *str) {
		*target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL);
		if (!*target) {
			DMERR("failed to allocate memory for target %d",
			      dm_setup_args.target_count);
			goto parse_fail;
		}
		dm_setup_args.target_count++;

		(*target)->begin = simple_strtoull(str, &next, 10);
		if (!next || *next != DM_FIELD_SEP) {
			DMERR("failed to parse starting sector for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next + 1);

		(*target)->length = simple_strtoull(str, &next, 10);
		if (!next || *next != DM_FIELD_SEP) {
			DMERR("failed to parse length for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next + 1);

		len = get_dm_option(str, &next, DM_FIELD_SEP);
		if (!len ||
		    !((*target)->type = kstrndup(str, len, GFP_KERNEL))) {
			DMERR("failed to parse type for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next);

		len = get_dm_option(str, &next, DM_LINE_SEP);
		if (!len ||
		    !((*target)->params = kstrndup(str, len, GFP_KERNEL))) {
			DMERR("failed to parse params for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next);

		/* Before moving on, walk through the copied target and
		 * attempt to replace all /dev/xxx with the major:minor number.
		 * It may not be possible to resolve them traditionally at
		 * boot-time. */
		dm_substitute_devices((*target)->params, len);

		target = &((*target)->next);
	}
	DMDEBUG("parsed %d targets", dm_setup_args.target_count);

	return 0;

parse_fail:
	return 1;
}

/*
 * Parse the command-line parameters given our kernel, but do not
 * actually try to invoke the DM device now; that is handled by
 * dm_setup_drive after the low-level disk drivers have initialised.
 * dm format is as follows:
 *  dm="name uuid fmode,[table line 1],[table line 2],..."
 * May be used with root=/dev/dm-0 as it always uses the first dm minor.
 */

static int __init dm_setup(char *str)
{
	dm_setup_args_init();

	str = dm_setup_parse_device_args(str);
	if (!str) {
		DMDEBUG("str is NULL");
		goto parse_fail;
	}

	/* Target parsing is delayed until we have dynamic memory */
	dm_setup_args.targets = str;

	printk(KERN_INFO "dm: will configure '%s' on dm-%d\n",
	       dm_setup_args.name, dm_setup_args.minor);

	dm_early_setup = 1;
	return 1;

parse_fail:
	printk(KERN_WARNING "dm: Invalid arguments supplied to dm=.\n");
	return 0;
}


static void __init dm_setup_drive(void)
{
	struct mapped_device *md = NULL;
	struct dm_table *table = NULL;
	struct dm_setup_target *target;
	char *uuid = dm_setup_args.uuid;
	fmode_t fmode = FMODE_READ;

	/* Finish parsing the targets. */
	if (dm_setup_parse_targets(dm_setup_args.targets))
		goto parse_fail;

	if (dm_create(dm_setup_args.minor, &md)) {
		DMDEBUG("failed to create the device");
		goto dm_create_fail;
	}
	DMDEBUG("created device '%s'", dm_device_name(md));

	/* In addition to flagging the table below, the disk must be
	 * set explicitly ro/rw. */
	set_disk_ro(dm_disk(md), dm_setup_args.ro);

	if (!dm_setup_args.ro)
		fmode |= FMODE_WRITE;
	if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) {
		DMDEBUG("failed to create the table");
		goto dm_table_create_fail;
	}

	target = dm_setup_args.target;
	while (target) {
		DMINFO("adding target '%llu %llu %s %s'",
		       (unsigned long long) target->begin,
		       (unsigned long long) target->length, target->type,
		       target->params);
		if (dm_table_add_target(table, target->type, target->begin,
					target->length, target->params)) {
			DMDEBUG("failed to add the target to the table");
			goto add_target_fail;
		}
		target = target->next;
	}

	if (dm_table_complete(table)) {
		DMDEBUG("failed to complete the table");
		goto table_complete_fail;
	}

	/* Suspend the device so that we can bind it to the table. */
	if (dm_suspend(md, 0)) {
		DMDEBUG("failed to suspend the device pre-bind");
		goto suspend_fail;
	}

	/* Bind the table to the device. This is the only way to associate
	 * md->map with the table and set the disk capacity directly. */
	if (dm_swap_table(md, table)) {  /* should return NULL. */
		DMDEBUG("failed to bind the device to the table");
		goto table_bind_fail;
	}

	/* Finally, resume and the device should be ready. */
	if (dm_resume(md)) {
		DMDEBUG("failed to resume the device");
		goto resume_fail;
	}

	/* Export the dm device via the ioctl interface */
	if (!strcmp(DM_NO_UUID, dm_setup_args.uuid))
		uuid = NULL;
	if (dm_ioctl_export(md, dm_setup_args.name, uuid)) {
		DMDEBUG("failed to export device with given name and uuid");
		goto export_fail;
	}
	printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor);

	dm_setup_cleanup();
	return;

export_fail:
resume_fail:
table_bind_fail:
suspend_fail:
table_complete_fail:
add_target_fail:
dm_table_create_fail:
	dm_put(md);
dm_create_fail:
	dm_setup_cleanup();
parse_fail:
	printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n",
	       dm_setup_args.minor, dm_setup_args.name);
}

__setup("dm=", dm_setup);

void __init dm_run_setup(void)
{
	if (!dm_early_setup)
		return;
	printk(KERN_INFO "dm: attempting early device configuration.\n");
	dm_setup_drive();
}
