/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */
/*
 * Copyright (c) 2012 by Delphix. All rights reserved.
 */

/*
 * Common routines used by zfs and zpool property management.
 */

#include <sys/zio.h>
#include <sys/spa.h>
#include <sys/zfs_acl.h>
#include <sys/zfs_ioctl.h>
#include <sys/zfs_sysfs.h>
#include <sys/zfs_znode.h>
#include <sys/fs/zfs.h>

#include "zfs_prop.h"
#include "zfs_deleg.h"

#if defined(_KERNEL)
#include <linux/sort.h>
#define	qsort(base, num, size, cmp) \
    sort(base, num, size, cmp, NULL)
#else
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#endif

static zprop_desc_t *
zprop_get_proptable(zfs_type_t type)
{
	if (type == ZFS_TYPE_POOL)
		return (zpool_prop_get_table());
	else
		return (zfs_prop_get_table());
}

static int
zprop_get_numprops(zfs_type_t type)
{
	if (type == ZFS_TYPE_POOL)
		return (ZPOOL_NUM_PROPS);
	else
		return (ZFS_NUM_PROPS);
}

static boolean_t
zfs_mod_supported_prop(const char *name, zfs_type_t type)
{
/*
 * The zfs module spa_feature_table[], whether in-kernel or in libzpool,
 * always supports all the properties. libzfs needs to query the running
 * module, via sysfs, to determine which properties are supported.
 */
#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD)
	return (B_TRUE);
#else
	return (zfs_mod_supported(type == ZFS_TYPE_POOL ?
	    ZFS_SYSFS_POOL_PROPERTIES : ZFS_SYSFS_DATASET_PROPERTIES, name));
#endif
}

void
zprop_register_impl(int prop, const char *name, zprop_type_t type,
    uint64_t numdefault, const char *strdefault, zprop_attr_t attr,
    int objset_types, const char *values, const char *colname,
    boolean_t rightalign, boolean_t visible, const zprop_index_t *idx_tbl)
{
	zprop_desc_t *prop_tbl = zprop_get_proptable(objset_types);
	zprop_desc_t *pd;

	pd = &prop_tbl[prop];

	ASSERT(pd->pd_name == NULL || pd->pd_name == name);
	ASSERT(name != NULL);
	ASSERT(colname != NULL);

	pd->pd_name = name;
	pd->pd_propnum = prop;
	pd->pd_proptype = type;
	pd->pd_numdefault = numdefault;
	pd->pd_strdefault = strdefault;
	pd->pd_attr = attr;
	pd->pd_types = objset_types;
	pd->pd_values = values;
	pd->pd_colname = colname;
	pd->pd_rightalign = rightalign;
	pd->pd_visible = visible;
	pd->pd_zfs_mod_supported = zfs_mod_supported_prop(name, objset_types);
	pd->pd_table = idx_tbl;
	pd->pd_table_size = 0;
	while (idx_tbl && (idx_tbl++)->pi_name != NULL)
		pd->pd_table_size++;
}

void
zprop_register_string(int prop, const char *name, const char *def,
    zprop_attr_t attr, int objset_types, const char *values,
    const char *colname)
{
	zprop_register_impl(prop, name, PROP_TYPE_STRING, 0, def, attr,
	    objset_types, values, colname, B_FALSE, B_TRUE, NULL);

}

void
zprop_register_number(int prop, const char *name, uint64_t def,
    zprop_attr_t attr, int objset_types, const char *values,
    const char *colname)
{
	zprop_register_impl(prop, name, PROP_TYPE_NUMBER, def, NULL, attr,
	    objset_types, values, colname, B_TRUE, B_TRUE, NULL);
}

void
zprop_register_index(int prop, const char *name, uint64_t def,
    zprop_attr_t attr, int objset_types, const char *values,
    const char *colname, const zprop_index_t *idx_tbl)
{
	zprop_register_impl(prop, name, PROP_TYPE_INDEX, def, NULL, attr,
	    objset_types, values, colname, B_TRUE, B_TRUE, idx_tbl);
}

void
zprop_register_hidden(int prop, const char *name, zprop_type_t type,
    zprop_attr_t attr, int objset_types, const char *colname)
{
	zprop_register_impl(prop, name, type, 0, NULL, attr,
	    objset_types, NULL, colname,
	    type == PROP_TYPE_NUMBER, B_FALSE, NULL);
}


/*
 * A comparison function we can use to order indexes into property tables.
 */
static int
zprop_compare(const void *arg1, const void *arg2)
{
	const zprop_desc_t *p1 = *((zprop_desc_t **)arg1);
	const zprop_desc_t *p2 = *((zprop_desc_t **)arg2);
	boolean_t p1ro, p2ro;

	p1ro = (p1->pd_attr == PROP_READONLY);
	p2ro = (p2->pd_attr == PROP_READONLY);

	if (p1ro == p2ro)
		return (strcmp(p1->pd_name, p2->pd_name));

	return (p1ro ? -1 : 1);
}

/*
 * Iterate over all properties in the given property table, calling back
 * into the specified function for each property. We will continue to
 * iterate until we either reach the end or the callback function returns
 * something other than ZPROP_CONT.
 */
int
zprop_iter_common(zprop_func func, void *cb, boolean_t show_all,
    boolean_t ordered, zfs_type_t type)
{
	int i, num_props, size, prop;
	zprop_desc_t *prop_tbl;
	zprop_desc_t **order;

	prop_tbl = zprop_get_proptable(type);
	num_props = zprop_get_numprops(type);
	size = num_props * sizeof (zprop_desc_t *);

#if defined(_KERNEL)
	order = kmem_alloc(size, KM_SLEEP);
#else
	if ((order = malloc(size)) == NULL)
		return (ZPROP_CONT);
#endif

	for (int j = 0; j < num_props; j++)
		order[j] = &prop_tbl[j];

	if (ordered) {
		qsort((void *)order, num_props, sizeof (zprop_desc_t *),
		    zprop_compare);
	}

	prop = ZPROP_CONT;
	for (i = 0; i < num_props; i++) {
		if ((order[i]->pd_visible || show_all) &&
		    order[i]->pd_zfs_mod_supported &&
		    (func(order[i]->pd_propnum, cb) != ZPROP_CONT)) {
			prop = order[i]->pd_propnum;
			break;
		}
	}

#if defined(_KERNEL)
	kmem_free(order, size);
#else
	free(order);
#endif
	return (prop);
}

static boolean_t
propname_match(const char *p, size_t len, zprop_desc_t *prop_entry)
{
	const char *propname = prop_entry->pd_name;
#ifndef _KERNEL
	const char *colname = prop_entry->pd_colname;
	int c;
#endif

	if (len == strlen(propname) &&
	    strncmp(p, propname, len) == 0)
		return (B_TRUE);

#ifndef _KERNEL
	if (colname == NULL || len != strlen(colname))
		return (B_FALSE);

	for (c = 0; c < len; c++)
		if (p[c] != tolower(colname[c]))
			break;

	return (colname[c] == '\0');
#else
	return (B_FALSE);
#endif
}

typedef struct name_to_prop_cb {
	const char *propname;
	zprop_desc_t *prop_tbl;
} name_to_prop_cb_t;

static int
zprop_name_to_prop_cb(int prop, void *cb_data)
{
	name_to_prop_cb_t *data = cb_data;

	if (propname_match(data->propname, strlen(data->propname),
	    &data->prop_tbl[prop]))
		return (prop);

	return (ZPROP_CONT);
}

int
zprop_name_to_prop(const char *propname, zfs_type_t type)
{
	int prop;
	name_to_prop_cb_t cb_data;

	cb_data.propname = propname;
	cb_data.prop_tbl = zprop_get_proptable(type);

	prop = zprop_iter_common(zprop_name_to_prop_cb, &cb_data,
	    B_TRUE, B_FALSE, type);

	return (prop == ZPROP_CONT ? ZPROP_INVAL : prop);
}

int
zprop_string_to_index(int prop, const char *string, uint64_t *index,
    zfs_type_t type)
{
	zprop_desc_t *prop_tbl;
	const zprop_index_t *idx_tbl;
	int i;

	if (prop == ZPROP_INVAL || prop == ZPROP_CONT)
		return (-1);

	ASSERT(prop < zprop_get_numprops(type));
	prop_tbl = zprop_get_proptable(type);
	if ((idx_tbl = prop_tbl[prop].pd_table) == NULL)
		return (-1);

	for (i = 0; idx_tbl[i].pi_name != NULL; i++) {
		if (strcmp(string, idx_tbl[i].pi_name) == 0) {
			*index = idx_tbl[i].pi_value;
			return (0);
		}
	}

	return (-1);
}

int
zprop_index_to_string(int prop, uint64_t index, const char **string,
    zfs_type_t type)
{
	zprop_desc_t *prop_tbl;
	const zprop_index_t *idx_tbl;
	int i;

	if (prop == ZPROP_INVAL || prop == ZPROP_CONT)
		return (-1);

	ASSERT(prop < zprop_get_numprops(type));
	prop_tbl = zprop_get_proptable(type);
	if ((idx_tbl = prop_tbl[prop].pd_table) == NULL)
		return (-1);

	for (i = 0; idx_tbl[i].pi_name != NULL; i++) {
		if (idx_tbl[i].pi_value == index) {
			*string = idx_tbl[i].pi_name;
			return (0);
		}
	}

	return (-1);
}

/*
 * Return a random valid property value.  Used by ztest.
 */
uint64_t
zprop_random_value(int prop, uint64_t seed, zfs_type_t type)
{
	zprop_desc_t *prop_tbl;
	const zprop_index_t *idx_tbl;

	ASSERT((uint_t)prop < zprop_get_numprops(type));
	prop_tbl = zprop_get_proptable(type);
	idx_tbl = prop_tbl[prop].pd_table;

	if (idx_tbl == NULL)
		return (seed);

	return (idx_tbl[seed % prop_tbl[prop].pd_table_size].pi_value);
}

const char *
zprop_values(int prop, zfs_type_t type)
{
	zprop_desc_t *prop_tbl;

	ASSERT(prop != ZPROP_INVAL && prop != ZPROP_CONT);
	ASSERT(prop < zprop_get_numprops(type));

	prop_tbl = zprop_get_proptable(type);

	return (prop_tbl[prop].pd_values);
}

/*
 * Returns TRUE if the property applies to any of the given dataset types.
 *
 * If headcheck is set, the check is being made against the head dataset
 * type of a snapshot which requires to return B_TRUE when the property
 * is only valid for snapshots.
 */
boolean_t
zprop_valid_for_type(int prop, zfs_type_t type, boolean_t headcheck)
{
	zprop_desc_t *prop_tbl;

	if (prop == ZPROP_INVAL || prop == ZPROP_CONT)
		return (B_FALSE);

	ASSERT(prop < zprop_get_numprops(type));
	prop_tbl = zprop_get_proptable(type);
	if (headcheck && prop_tbl[prop].pd_types == ZFS_TYPE_SNAPSHOT)
		return (B_TRUE);
	return ((prop_tbl[prop].pd_types & type) != 0);
}

#ifndef _KERNEL

/*
 * Determines the minimum width for the column, and indicates whether it's fixed
 * or not.  Only string columns are non-fixed.
 */
size_t
zprop_width(int prop, boolean_t *fixed, zfs_type_t type)
{
	zprop_desc_t *prop_tbl, *pd;
	const zprop_index_t *idx;
	size_t ret;
	int i;

	ASSERT(prop != ZPROP_INVAL && prop != ZPROP_CONT);
	ASSERT(prop < zprop_get_numprops(type));

	prop_tbl = zprop_get_proptable(type);
	pd = &prop_tbl[prop];

	*fixed = B_TRUE;

	/*
	 * Start with the width of the column name.
	 */
	ret = strlen(pd->pd_colname);

	/*
	 * For fixed-width values, make sure the width is large enough to hold
	 * any possible value.
	 */
	switch (pd->pd_proptype) {
	case PROP_TYPE_NUMBER:
		/*
		 * The maximum length of a human-readable number is 5 characters
		 * ("20.4M", for example).
		 */
		if (ret < 5)
			ret = 5;
		/*
		 * 'creation' is handled specially because it's a number
		 * internally, but displayed as a date string.
		 */
		if (prop == ZFS_PROP_CREATION)
			*fixed = B_FALSE;
		/*
		 * 'health' is handled specially because it's a number
		 * internally, but displayed as a fixed 8 character string.
		 */
		if (prop == ZPOOL_PROP_HEALTH)
			ret = 8;
		break;
	case PROP_TYPE_INDEX:
		idx = prop_tbl[prop].pd_table;
		for (i = 0; idx[i].pi_name != NULL; i++) {
			if (strlen(idx[i].pi_name) > ret)
				ret = strlen(idx[i].pi_name);
		}
		break;

	case PROP_TYPE_STRING:
		*fixed = B_FALSE;
		break;
	}

	return (ret);
}

#endif

#if defined(_KERNEL)
/* Common routines to initialize property tables */
EXPORT_SYMBOL(zprop_register_impl);
EXPORT_SYMBOL(zprop_register_string);
EXPORT_SYMBOL(zprop_register_number);
EXPORT_SYMBOL(zprop_register_index);
EXPORT_SYMBOL(zprop_register_hidden);

/* Common routines for zfs and zpool property management */
EXPORT_SYMBOL(zprop_iter_common);
EXPORT_SYMBOL(zprop_name_to_prop);
EXPORT_SYMBOL(zprop_string_to_index);
EXPORT_SYMBOL(zprop_index_to_string);
EXPORT_SYMBOL(zprop_random_value);
EXPORT_SYMBOL(zprop_values);
EXPORT_SYMBOL(zprop_valid_for_type);
#endif
