/* 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"
#include "../drivers/md/dm.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 */
		if (*candidate_end)
			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;
	}

	dm_lock_md_type(md);
	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;
	}

	if (dm_get_md_type(md) == DM_TYPE_NONE) {
		dm_set_md_type(md, dm_table_get_type(table));
		if (dm_setup_md_queue(md)) {
			DMWARN("unable to set up device queue for new table.");
			goto setup_md_queue_fail;
		}
	} else if (dm_get_md_type(md) != dm_table_get_type(table)) {
		DMWARN("can't change device type after initial table load.");
		goto setup_md_queue_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_unlock_md_type(md);
	dm_setup_cleanup();
	return;

export_fail:
resume_fail:
table_bind_fail:
suspend_fail:
setup_md_queue_fail:
table_complete_fail:
add_target_fail:
	dm_unlock_md_type(md);
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();
}
