summaryrefslogtreecommitdiff
path: root/usr/src/common/zfs
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/common/zfs')
-rw-r--r--usr/src/common/zfs/zfs_deleg.c121
-rw-r--r--usr/src/common/zfs/zfs_deleg.h4
-rw-r--r--usr/src/common/zfs/zfs_prop.c603
-rw-r--r--usr/src/common/zfs/zfs_prop.h10
4 files changed, 360 insertions, 378 deletions
diff --git a/usr/src/common/zfs/zfs_deleg.c b/usr/src/common/zfs/zfs_deleg.c
index d7c3046572..31ea16b29c 100644
--- a/usr/src/common/zfs/zfs_deleg.c
+++ b/usr/src/common/zfs/zfs_deleg.c
@@ -37,7 +37,9 @@
#include <libnvpair.h>
#include <ctype.h>
#endif
+/* XXX includes zfs_context.h, so why bother with the above? */
#include <sys/dsl_deleg.h>
+#include "zfs_prop.h"
#include "zfs_deleg.h"
#include "zfs_namecheck.h"
@@ -57,108 +59,84 @@ char *zfs_deleg_perm_tab[] = {
ZFS_DELEG_PERM_SHARE,
ZFS_DELEG_PERM_SEND,
ZFS_DELEG_PERM_RECEIVE,
- ZFS_DELEG_PERM_QUOTA,
- ZFS_DELEG_PERM_RESERVATION,
- ZFS_DELEG_PERM_VOLSIZE,
- ZFS_DELEG_PERM_RECORDSIZE,
- ZFS_DELEG_PERM_MOUNTPOINT,
- ZFS_DELEG_PERM_SHARENFS,
- ZFS_DELEG_PERM_CHECKSUM,
- ZFS_DELEG_PERM_COMPRESSION,
- ZFS_DELEG_PERM_ATIME,
- ZFS_DELEG_PERM_DEVICES,
- ZFS_DELEG_PERM_EXEC,
- ZFS_DELEG_PERM_SETUID,
- ZFS_DELEG_PERM_READONLY,
- ZFS_DELEG_PERM_ZONED,
- ZFS_DELEG_PERM_SNAPDIR,
- ZFS_DELEG_PERM_ACLMODE,
- ZFS_DELEG_PERM_ACLINHERIT,
ZFS_DELEG_PERM_ALLOW,
- ZFS_DELEG_PERM_CANMOUNT,
ZFS_DELEG_PERM_USERPROP,
- ZFS_DELEG_PERM_SHAREISCSI,
- ZFS_DELEG_PERM_XATTR,
- ZFS_DELEG_PERM_COPIES,
- ZFS_DELEG_PERM_VERSION,
NULL
};
-int
-zfs_deleg_type(char *name)
+static int
+zfs_valid_permission_name(const char *perm)
{
- return (name[0]);
+ if (zfs_deleg_canonicalize_perm(perm))
+ return (0);
+
+ return (permset_namecheck(perm, NULL, NULL));
}
-static int
-zfs_valid_permission_name(char *perm)
+const char *
+zfs_deleg_canonicalize_perm(const char *perm)
{
int i;
+ zfs_prop_t prop;
+
for (i = 0; zfs_deleg_perm_tab[i] != NULL; i++) {
if (strcmp(perm, zfs_deleg_perm_tab[i]) == 0)
- return (0);
+ return (perm);
}
- return (permset_namecheck(perm, NULL, NULL));
+ prop = zfs_name_to_prop(perm);
+ if (prop != ZFS_PROP_INVAL && zfs_prop_delegatable(prop))
+ return (zfs_prop_to_name(prop));
+ return (NULL);
+
}
static int
zfs_validate_who(char *who)
{
- int error = 0;
char *p;
- switch (zfs_deleg_type(who)) {
+ if (who[2] != ZFS_DELEG_FIELD_SEP_CHR)
+ return (-1);
+
+ switch (who[0]) {
case ZFS_DELEG_USER:
case ZFS_DELEG_GROUP:
case ZFS_DELEG_USER_SETS:
case ZFS_DELEG_GROUP_SETS:
- if ((who[1] != 'l' || who[1] != 'd') &&
- (who[2] != ZFS_DELEG_FIELD_SEP_CHR)) {
- error = -1;
- break;
- }
-
- for (p = &who[3]; p && *p; p++)
- if (!isdigit(*p)) {
- error = -1;
- }
+ if (who[1] != ZFS_DELEG_LOCAL && who[1] != ZFS_DELEG_DESCENDENT)
+ return (-1);
+ for (p = &who[3]; *p; p++)
+ if (!isdigit(*p))
+ return (-1);
break;
+
case ZFS_DELEG_NAMED_SET:
case ZFS_DELEG_NAMED_SET_SETS:
- error = permset_namecheck(&who[3], NULL, NULL);
- break;
+ if (who[1] != ZFS_DELEG_NA)
+ return (-1);
+ return (permset_namecheck(&who[3], NULL, NULL));
case ZFS_DELEG_CREATE:
case ZFS_DELEG_CREATE_SETS:
- case ZFS_DELEG_EVERYONE:
- case ZFS_DELEG_EVERYONE_SETS:
+ if (who[1] != ZFS_DELEG_NA)
+ return (-1);
if (who[3] != '\0')
- error = -1;
+ return (-1);
break;
- default:
- error = -1;
- }
- return (error);
-}
-
-static int
-zfs_validate_iflags(char *who)
-{
- switch (zfs_deleg_type(who)) {
- case ZFS_DELEG_NAMED_SET:
- case ZFS_DELEG_NAMED_SET_SETS:
- case ZFS_DELEG_CREATE:
- case ZFS_DELEG_CREATE_SETS:
- if (who[1] != '-')
+ case ZFS_DELEG_EVERYONE:
+ case ZFS_DELEG_EVERYONE_SETS:
+ if (who[1] != ZFS_DELEG_LOCAL && who[1] != ZFS_DELEG_DESCENDENT)
return (-1);
- break;
- default:
- if (who[1] != 'l' && who[1] != 'd')
+ if (who[3] != '\0')
return (-1);
break;
+
+ default:
+ return (-1);
}
+
return (0);
}
@@ -180,9 +158,6 @@ zfs_deleg_verify_nvlist(nvlist_t *nvp)
if (zfs_validate_who(nvpair_name(who)))
return (-1);
- if (zfs_validate_iflags(nvpair_name(who)))
- return (-1);
-
error = nvlist_lookup_nvlist(nvp, nvpair_name(who), &perms);
if (error && error != ENOENT)
@@ -197,9 +172,8 @@ zfs_deleg_verify_nvlist(nvlist_t *nvp)
do {
error = zfs_valid_permission_name(
nvpair_name(perm_name));
- if (error) {
+ if (error)
return (-1);
- }
} while (perm_name = nvlist_next_nvpair(perms, perm_name));
} while (who = nvlist_next_nvpair(nvp, who));
return (0);
@@ -220,7 +194,8 @@ zfs_deleg_verify_nvlist(nvlist_t *nvp)
* data - is either a permission set name or a 64 bit uid/gid.
*/
void
-zfs_deleg_whokey(char *attr, char type, char inheritchr, void *data)
+zfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type,
+ char inheritchr, void *data)
{
int len = ZFS_MAX_DELEG_NAME;
uint64_t *id = data;
@@ -243,8 +218,12 @@ zfs_deleg_whokey(char *attr, char type, char inheritchr, void *data)
(void) snprintf(attr, len, "%c-%c", type,
ZFS_DELEG_FIELD_SEP_CHR);
break;
- default:
+ case ZFS_DELEG_EVERYONE:
+ case ZFS_DELEG_EVERYONE_SETS:
(void) snprintf(attr, len, "%c%c%c", type, inheritchr,
ZFS_DELEG_FIELD_SEP_CHR);
+ break;
+ default:
+ ASSERT(!"bad zfs_deleg_who_type_t");
}
}
diff --git a/usr/src/common/zfs/zfs_deleg.h b/usr/src/common/zfs/zfs_deleg.h
index 9a5daf2438..ef6b53473b 100644
--- a/usr/src/common/zfs/zfs_deleg.h
+++ b/usr/src/common/zfs/zfs_deleg.h
@@ -47,11 +47,11 @@ extern "C" {
#define ZFS_DELEG_NA '-'
extern char *zfs_deleg_perm_tab[];
-int zfs_deleg_type(char *attr);
int zfs_deleg_verify_nvlist(nvlist_t *nvlist);
-void zfs_deleg_whokey(char *attr, char type,
+void zfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type,
char checkflag, void *data);
+const char *zfs_deleg_canonicalize_perm(const char *perm);
#ifdef __cplusplus
}
diff --git a/usr/src/common/zfs/zfs_prop.c b/usr/src/common/zfs/zfs_prop.c
index d772baa470..408ec4be09 100644
--- a/usr/src/common/zfs/zfs_prop.c
+++ b/usr/src/common/zfs/zfs_prop.c
@@ -25,28 +25,6 @@
#pragma ident "%Z%%M% %I% %E% SMI"
-/*
- * Master property table.
- *
- * This table keeps track of all the properties supported by ZFS, and their
- * various attributes. Not all of these are needed by the kernel, and several
- * are only used by a single libzfs client. But having them here centralizes
- * all property information in one location.
- *
- * name The human-readable string representing this property
- * proptype Basic type (string, boolean, number)
- * default Default value for the property. Sadly, C only allows
- * you to initialize the first member of a union, so we
- * have two default members for each property.
- * attr Attributes (readonly, inheritable) for the property
- * types Valid dataset types to which this applies
- * values String describing acceptable values for the property
- * colname The column header for 'zfs list'
- * colfmt The column formatting for 'zfs list'
- *
- * This table must match the order of property types in libzfs.h.
- */
-
#include <sys/zio.h>
#include <sys/spa.h>
#include <sys/zfs_acl.h>
@@ -66,156 +44,280 @@
#endif
typedef enum {
- prop_default,
- prop_readonly,
- prop_inherit
+ PROP_DEFAULT,
+ PROP_READONLY,
+ PROP_INHERIT
} prop_attr_t;
+typedef struct zfs_index {
+ const char *name;
+ uint64_t index;
+} zfs_index_t;
+
typedef struct {
- const char *pd_name;
- zfs_proptype_t pd_proptype;
- uint64_t pd_numdefault;
- const char *pd_strdefault;
- prop_attr_t pd_attr;
- int pd_types;
- const char *pd_values;
- const char *pd_colname;
- boolean_t pd_rightalign;
- boolean_t pd_visible;
- const char *pd_perm;
+ const char *pd_name; /* human-readable property name */
+ zfs_proptype_t pd_proptype; /* string, boolean, index, number */
+ const char *pd_strdefault; /* default for strings */
+ uint64_t pd_numdefault; /* for boolean / index / number */
+ prop_attr_t pd_attr; /* default, readonly, inherit */
+ int pd_types; /* bitfield of valid dataset types */
+ /* fs | vol | snap; or pool */
+ const char *pd_values; /* string telling acceptable values */
+ const char *pd_colname; /* column header for "zfs list" */
+ boolean_t pd_rightalign; /* column alignment for "zfs list" */
+ boolean_t pd_visible; /* do we list this property with the */
+ /* "zfs get" help message */
+ const zfs_index_t *pd_table; /* for index properties, a table */
+ /* defining the possible values */
} prop_desc_t;
-static prop_desc_t zfs_prop_table[] = {
- { "type", prop_type_string, 0, NULL, prop_readonly,
- ZFS_TYPE_ANY, "filesystem | volume | snapshot", "TYPE", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_NONE },
- { "creation", prop_type_number, 0, NULL, prop_readonly,
- ZFS_TYPE_ANY, "<date>", "CREATION", B_FALSE, B_TRUE,
- ZFS_DELEG_PERM_NONE },
- { "used", prop_type_number, 0, NULL, prop_readonly,
- ZFS_TYPE_ANY, "<size>", "USED", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_NONE },
- { "available", prop_type_number, 0, NULL, prop_readonly,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_NONE },
- { "referenced", prop_type_number, 0, NULL, prop_readonly,
- ZFS_TYPE_ANY,
- "<size>", "REFER", B_TRUE, B_TRUE, ZFS_DELEG_PERM_NONE },
- { "compressratio", prop_type_number, 0, NULL, prop_readonly,
- ZFS_TYPE_ANY, "<1.00x or higher if compressed>", "RATIO", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_NONE },
- { "mounted", prop_type_boolean, 0, NULL, prop_readonly,
- ZFS_TYPE_FILESYSTEM, "yes | no | -", "MOUNTED", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_NONE },
- { "origin", prop_type_string, 0, NULL, prop_readonly,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN",
- B_FALSE, B_TRUE, ZFS_DELEG_PERM_NONE },
- { "quota", prop_type_number, 0, NULL, prop_default,
- ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_QUOTA },
- { "reservation", prop_type_number, 0, NULL, prop_default,
+static prop_desc_t zfs_prop_table[ZFS_NUM_PROPS];
+
+static void
+register_impl(zfs_prop_t prop, const char *name, zfs_proptype_t type,
+ uint64_t numdefault, const char *strdefault, prop_attr_t attr,
+ int objset_types, const char *values, const char *colname,
+ boolean_t rightalign, boolean_t visible, const zfs_index_t *table)
+{
+ prop_desc_t *pd = &zfs_prop_table[prop];
+
+ ASSERT(pd->pd_name == NULL || pd->pd_name == name);
+
+ pd->pd_name = name;
+ 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_table = table;
+}
+
+static void
+register_string(zfs_prop_t prop, const char *name, const char *def,
+ prop_attr_t attr, int objset_types, const char *values,
+ const char *colname)
+{
+ register_impl(prop, name, PROP_TYPE_STRING, 0, def, attr,
+ objset_types, values, colname, B_FALSE, B_TRUE, NULL);
+
+}
+
+static void
+register_number(zfs_prop_t prop, const char *name, uint64_t def,
+ prop_attr_t attr, int objset_types, const char *values, const char *colname)
+{
+ register_impl(prop, name, PROP_TYPE_NUMBER, def, NULL, attr,
+ objset_types, values, colname, B_TRUE, B_TRUE, NULL);
+}
+
+static void
+register_boolean(zfs_prop_t prop, const char *name, uint64_t def,
+ prop_attr_t attr, int objset_types, const char *values, const char *colname)
+{
+ register_impl(prop, name, PROP_TYPE_BOOLEAN, def, NULL, attr,
+ objset_types, values, colname, B_TRUE, B_TRUE, NULL);
+}
+
+static void
+register_index(zfs_prop_t prop, const char *name, uint64_t def,
+ int objset_types, const char *values, const char *colname,
+ const zfs_index_t *table)
+{
+ register_impl(prop, name, PROP_TYPE_INDEX, def, NULL, PROP_INHERIT,
+ objset_types, values, colname, B_TRUE, B_TRUE, table);
+}
+
+static void
+register_hidden(zfs_prop_t prop, const char *name, zfs_proptype_t type,
+ prop_attr_t attr, int objset_types, const char *colname)
+{
+ register_impl(prop, name, type, 0, NULL, attr,
+ objset_types, NULL, colname, B_FALSE, B_FALSE, NULL);
+}
+
+void
+zfs_prop_init(void)
+{
+ static zfs_index_t checksum_table[] = {
+ { "on", ZIO_CHECKSUM_ON },
+ { "off", ZIO_CHECKSUM_OFF },
+ { "fletcher2", ZIO_CHECKSUM_FLETCHER_2 },
+ { "fletcher4", ZIO_CHECKSUM_FLETCHER_4 },
+ { "sha256", ZIO_CHECKSUM_SHA256 },
+ { NULL }
+ };
+
+ static zfs_index_t compress_table[] = {
+ { "on", ZIO_COMPRESS_ON },
+ { "off", ZIO_COMPRESS_OFF },
+ { "lzjb", ZIO_COMPRESS_LZJB },
+ { "gzip", ZIO_COMPRESS_GZIP_6 }, /* gzip default */
+ { "gzip-1", ZIO_COMPRESS_GZIP_1 },
+ { "gzip-2", ZIO_COMPRESS_GZIP_2 },
+ { "gzip-3", ZIO_COMPRESS_GZIP_3 },
+ { "gzip-4", ZIO_COMPRESS_GZIP_4 },
+ { "gzip-5", ZIO_COMPRESS_GZIP_5 },
+ { "gzip-6", ZIO_COMPRESS_GZIP_6 },
+ { "gzip-7", ZIO_COMPRESS_GZIP_7 },
+ { "gzip-8", ZIO_COMPRESS_GZIP_8 },
+ { "gzip-9", ZIO_COMPRESS_GZIP_9 },
+ { NULL }
+ };
+
+ static zfs_index_t snapdir_table[] = {
+ { "hidden", ZFS_SNAPDIR_HIDDEN },
+ { "visible", ZFS_SNAPDIR_VISIBLE },
+ { NULL }
+ };
+
+ static zfs_index_t acl_mode_table[] = {
+ { "discard", ZFS_ACL_DISCARD },
+ { "groupmask", ZFS_ACL_GROUPMASK },
+ { "passthrough", ZFS_ACL_PASSTHROUGH },
+ { NULL }
+ };
+
+ static zfs_index_t acl_inherit_table[] = {
+ { "discard", ZFS_ACL_DISCARD },
+ { "noallow", ZFS_ACL_NOALLOW },
+ { "secure", ZFS_ACL_SECURE },
+ { "passthrough", ZFS_ACL_PASSTHROUGH },
+ { NULL }
+ };
+
+ static zfs_index_t copies_table[] = {
+ { "1", 1 },
+ { "2", 2 },
+ { "3", 3 },
+ { NULL }
+ };
+
+ static zfs_index_t version_table[] = {
+ { "1", 1 },
+ { "2", 2 },
+ { "current", ZPL_VERSION },
+ { NULL }
+ };
+
+ /* inherit index properties */
+ register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
- "<size> | none", "RESERV", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_RESERVATION },
- { "volsize", prop_type_number, 0, NULL, prop_default,
- ZFS_TYPE_VOLUME, "<size>", "VOLSIZE", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_VOLSIZE },
- { "volblocksize", prop_type_number, 8192, NULL, prop_readonly,
- ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_NONE },
- { "recordsize", prop_type_number, SPA_MAXBLOCKSIZE, NULL,
- prop_inherit,
- ZFS_TYPE_FILESYSTEM,
- "512 to 128k, power of 2", "RECSIZE", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_RECORDSIZE },
- { "mountpoint", prop_type_string, 0, "/", prop_inherit,
- ZFS_TYPE_FILESYSTEM,
- "<path> | legacy | none", "MOUNTPOINT", B_FALSE, B_TRUE,
- ZFS_DELEG_PERM_MOUNTPOINT },
- { "sharenfs", prop_type_string, 0, "off", prop_inherit,
+ "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM",
+ checksum_table);
+ register_index(ZFS_PROP_COMPRESSION, "compression",
+ ZIO_COMPRESS_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+ "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", compress_table);
+ register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
+ ZFS_TYPE_FILESYSTEM, "hidden | visible", "SNAPDIR", snapdir_table);
+ register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK,
+ ZFS_TYPE_FILESYSTEM, "discard | groupmask | passthrough", "ACLMODE",
+ acl_mode_table);
+ register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_SECURE,
ZFS_TYPE_FILESYSTEM,
- "on | off | share(1M) options", "SHARENFS", B_FALSE, B_TRUE,
- ZFS_DELEG_PERM_SHARENFS },
- { "checksum", prop_type_index, ZIO_CHECKSUM_DEFAULT, "on",
- prop_inherit, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
- "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_CHECKSUM },
- { "compression", prop_type_index, ZIO_COMPRESS_DEFAULT, "off",
- prop_inherit, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
- "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_COMPRESSION },
- { "atime", prop_type_boolean, 1, NULL, prop_inherit,
- ZFS_TYPE_FILESYSTEM,
- "on | off", "ATIME", B_TRUE, B_TRUE, ZFS_DELEG_PERM_ATIME },
- { "devices", prop_type_boolean, 1, NULL, prop_inherit,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
- "on | off", "DEVICES", B_TRUE, B_TRUE, ZFS_DELEG_PERM_DEVICES },
- { "exec", prop_type_boolean, 1, NULL, prop_inherit,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
- "on | off", "EXEC", B_TRUE, B_TRUE, ZFS_DELEG_PERM_EXEC },
- { "setuid", prop_type_boolean, 1, NULL, prop_inherit,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
- B_TRUE, B_TRUE, ZFS_DELEG_PERM_SETUID },
- { "readonly", prop_type_boolean, 0, NULL, prop_inherit,
+ "discard | noallow | secure | passthrough", "ACLINHERIT",
+ acl_inherit_table);
+ register_index(ZFS_PROP_COPIES, "copies", 1,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
- "on | off", "RDONLY", B_TRUE, B_TRUE, ZFS_DELEG_PERM_READONLY },
- { "zoned", prop_type_boolean, 0, NULL, prop_inherit,
- ZFS_TYPE_FILESYSTEM,
- "on | off", "ZONED", B_TRUE, B_TRUE, ZFS_DELEG_PERM_ZONED },
- { "snapdir", prop_type_index, ZFS_SNAPDIR_HIDDEN, "hidden",
- prop_inherit,
- ZFS_TYPE_FILESYSTEM,
- "hidden | visible", "SNAPDIR", B_TRUE, B_TRUE,
- ZFS_DELEG_PERM_SNAPDIR },
- { "aclmode", prop_type_index, ZFS_ACL_GROUPMASK, "groupmask",
- prop_inherit, ZFS_TYPE_FILESYSTEM,
- "discard | groupmask | passthrough", "ACLMODE", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_ACLMODE },
- { "aclinherit", prop_type_index, ZFS_ACL_SECURE, "secure",
- prop_inherit, ZFS_TYPE_FILESYSTEM,
- "discard | noallow | secure | passthrough", "ACLINHERIT", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_ACLINHERIT },
- { "createtxg", prop_type_number, 0, NULL, prop_readonly,
- ZFS_TYPE_ANY, NULL, NULL, B_FALSE, B_FALSE, ZFS_DELEG_PERM_NONE },
- { "name", prop_type_string, 0, NULL, prop_readonly,
- ZFS_TYPE_ANY, NULL, "NAME", B_FALSE, B_FALSE, ZFS_DELEG_PERM_NONE },
- { "canmount", prop_type_boolean, 1, NULL, prop_default,
- ZFS_TYPE_FILESYSTEM,
- "on | off", "CANMOUNT", B_TRUE, B_TRUE, ZFS_DELEG_PERM_CANMOUNT },
- { "shareiscsi", prop_type_string, 0, "off", prop_inherit,
- ZFS_TYPE_ANY,
- "on | off | type=<type>", "SHAREISCSI", B_FALSE, B_TRUE,
- ZFS_DELEG_PERM_SHAREISCSI },
- { "iscsioptions", prop_type_string, 0, NULL, prop_inherit,
- ZFS_TYPE_VOLUME, NULL, "ISCSIOPTIONS", B_FALSE, B_FALSE,
- ZFS_DELEG_PERM_NONE },
- { "xattr", prop_type_boolean, 1, NULL, prop_inherit,
+ "1 | 2 | 3", "COPIES", copies_table);
+ register_index(ZFS_PROP_VERSION, "version", 0,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
- "on | off", "XATTR", B_TRUE, B_TRUE, ZFS_DELEG_PERM_XATTR },
- { "numclones", prop_type_number, 0, NULL, prop_readonly,
- ZFS_TYPE_SNAPSHOT, NULL, NULL, B_FALSE, B_FALSE,
- ZFS_DELEG_PERM_NONE },
- { "copies", prop_type_index, 1, "1", prop_inherit,
+ "1 | 2 | current", "VERSION", version_table);
+
+ /* string properties */
+ register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
+ register_string(ZPOOL_PROP_BOOTFS, "bootfs", NULL, PROP_DEFAULT,
+ ZFS_TYPE_POOL, "<filesystem>", "BOOTFS");
+ register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", "MOUNTPOINT");
+ register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", "SHARENFS");
+ register_string(ZFS_PROP_SHAREISCSI, "shareiscsi", "off", PROP_INHERIT,
+ ZFS_TYPE_ANY, "on | off | type=<type>", "SHAREISCSI");
+ register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY,
+ ZFS_TYPE_ANY, "filesystem | volume | snapshot", "TYPE");
+
+ /* readonly number properties */
+ register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
+ ZFS_TYPE_ANY, "<size>", "USED");
+ register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
- "1 | 2 | 3", "COPIES", B_TRUE, B_TRUE, ZFS_DELEG_PERM_COPIES },
- { "bootfs", prop_type_string, 0, NULL, prop_default,
- ZFS_TYPE_POOL, "<filesystem>", "BOOTFS", B_FALSE,
- B_TRUE, ZFS_DELEG_PERM_NONE },
- { "autoreplace", prop_type_boolean, 0, NULL, prop_default,
- ZFS_TYPE_POOL, "on | off", "REPLACE", B_FALSE, B_TRUE,
- ZFS_DELEG_PERM_NONE },
- { "delegation", prop_type_boolean, 1, NULL, prop_default,
- ZFS_TYPE_POOL, "on | off", "DELEGATION", B_TRUE,
- B_TRUE, ZFS_DELEG_PERM_NONE },
- { "version", prop_type_index, 0, NULL, prop_default,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "1 | 2 | current",
- "VERSION", B_TRUE, B_TRUE, ZFS_DELEG_PERM_VERSION },
-};
-
-#define ZFS_PROP_COUNT ((sizeof (zfs_prop_table))/(sizeof (prop_desc_t)))
+ "<size>", "AVAIL");
+ register_number(ZFS_PROP_REFERENCED, "referenced", 0, PROP_READONLY,
+ ZFS_TYPE_ANY, "<size>", "REFER");
+ register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
+ PROP_READONLY, ZFS_TYPE_ANY,
+ "<1.00x or higher if compressed>", "RATIO");
+ register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192,
+ PROP_READONLY,
+ ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK");
+
+ /* default number properties */
+ register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
+ ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
+ register_number(ZFS_PROP_RESERVATION, "reservation", 0, PROP_DEFAULT,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "RESERV");
+ register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
+ ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
+
+ /* inherit number properties */
+ register_number(ZFS_PROP_RECORDSIZE, "recordsize", SPA_MAXBLOCKSIZE,
+ PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE");
+
+ /* readonly boolean properties */
+ register_boolean(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
+ ZFS_TYPE_FILESYSTEM, "yes | no | -", "MOUNTED");
+
+ /* default boolean properties */
+ register_boolean(ZFS_PROP_CANMOUNT, "canmount", 1, PROP_DEFAULT,
+ ZFS_TYPE_FILESYSTEM, "on | off", "CANMOUNT");
+ register_boolean(ZPOOL_PROP_DELEGATION, "delegation", 1, PROP_DEFAULT,
+ ZFS_TYPE_POOL, "on | off", "DELEGATION");
+ register_boolean(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0, PROP_DEFAULT,
+ ZFS_TYPE_POOL, "on | off", "REPLACE");
+
+ /* inherit boolean properties */
+ register_boolean(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM, "on | off", "ATIME");
+ register_boolean(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES");
+ register_boolean(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC");
+ register_boolean(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID");
+ register_boolean(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY");
+ register_boolean(ZFS_PROP_ZONED, "zoned", 0, PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM, "on | off", "ZONED");
+ register_boolean(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR");
+
+ /* hidden properties */
+ register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER,
+ PROP_READONLY, ZFS_TYPE_ANY, NULL);
+ register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
+ PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL);
+ register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
+ PROP_READONLY, ZFS_TYPE_ANY, "NAME");
+ register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING,
+ PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS");
+ register_hidden(ZPOOL_PROP_NAME, "zpoolname", PROP_TYPE_STRING,
+ PROP_READONLY, ZFS_TYPE_POOL, NULL);
+
+ /* oddball properties */
+ register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL,
+ PROP_READONLY, ZFS_TYPE_ANY,
+ "<date>", "CREATION", B_FALSE, B_TRUE, NULL);
+}
+
/*
- * Returns TRUE if the property applies to the given dataset types.
+ * Returns TRUE if the property applies to any of the given dataset types.
*/
int
zfs_prop_valid_for_type(zfs_prop_t prop, int types)
@@ -240,28 +342,21 @@ zfs_prop_is_visible(zfs_prop_t prop)
* zfs_prop_table[]
*/
static int
-zfs_prop_compare(const void *p1, const void *p2)
+zfs_prop_compare(const void *arg1, const void *arg2)
{
- int i, j;
- prop_attr_t iattr, jattr;
+ const zfs_prop_t *p1 = arg1;
+ const zfs_prop_t *p2 = arg2;
+ boolean_t p1ro, p2ro;
- i = *((int *)p1);
- j = *((int *)p2);
+ p1ro = (zfs_prop_table[*p1].pd_attr == PROP_READONLY);
+ p2ro = (zfs_prop_table[*p2].pd_attr == PROP_READONLY);
- iattr = zfs_prop_table[i].pd_attr;
- jattr = zfs_prop_table[j].pd_attr;
-
- /* first, sort by whether the property is readonly or not */
- if (iattr != prop_readonly &&
- jattr == prop_readonly)
- return (1);
- if (iattr == prop_readonly &&
- jattr != prop_readonly)
- return (-1);
+ if (p1ro == p2ro) {
+ return (strcmp(zfs_prop_table[*p1].pd_name,
+ zfs_prop_table[*p2].pd_name));
+ }
- /* otherwise, sort by the property name */
- return (strcmp(zfs_prop_table[i].pd_name,
- zfs_prop_table[j].pd_name));
+ return (p1ro ? -1 : 1);
}
/*
@@ -275,19 +370,18 @@ zfs_prop_iter_common(zfs_prop_f func, void *cb, zfs_type_t type,
boolean_t show_all, boolean_t ordered)
{
int i;
- int order[ZFS_PROP_COUNT];
+ zfs_prop_t order[ZFS_NUM_PROPS];
- for (int j = 0; j < ZFS_PROP_COUNT; j++) {
+ for (int j = 0; j < ZFS_NUM_PROPS; j++)
order[j] = j;
- }
if (ordered) {
- qsort((void *)order, ZFS_PROP_COUNT, sizeof (zfs_prop_t),
+ qsort((void *)order, ZFS_NUM_PROPS, sizeof (zfs_prop_t),
zfs_prop_compare);
}
- for (i = 0; i < ZFS_PROP_COUNT; i++) {
+ for (i = 0; i < ZFS_NUM_PROPS; i++) {
if (zfs_prop_valid_for_type(order[i], type) &&
(zfs_prop_is_visible(order[i]) || show_all)) {
if (func(order[i], cb) != ZFS_PROP_CONT)
@@ -298,23 +392,21 @@ zfs_prop_iter_common(zfs_prop_f func, void *cb, zfs_type_t type,
}
zfs_prop_t
-zfs_prop_iter(zfs_prop_f func, void *cb, boolean_t show_all)
+zfs_prop_iter(zfs_prop_f func, void *cb)
{
- return (zfs_prop_iter_common(func, cb, ZFS_TYPE_ANY, show_all,
- B_FALSE));
+ return (zfs_prop_iter_common(func, cb, ZFS_TYPE_ANY, B_FALSE, B_FALSE));
}
zfs_prop_t
-zfs_prop_iter_ordered(zfs_prop_f func, void *cb, boolean_t show_all)
+zfs_prop_iter_ordered(zfs_prop_f func, void *cb)
{
- return (zfs_prop_iter_common(func, cb, ZFS_TYPE_ANY, show_all,
- B_TRUE));
+ return (zfs_prop_iter_common(func, cb, ZFS_TYPE_ANY, B_FALSE, B_TRUE));
}
zpool_prop_t
-zpool_prop_iter(zpool_prop_f func, void *cb, boolean_t show_all)
+zpool_prop_iter(zpool_prop_f func, void *cb)
{
- return (zfs_prop_iter_common(func, cb, ZFS_TYPE_POOL, show_all,
+ return (zfs_prop_iter_common(func, cb, ZFS_TYPE_POOL, B_FALSE,
B_FALSE));
}
@@ -337,9 +429,7 @@ propname_match(const char *p, zfs_prop_t prop, size_t len)
#ifndef _KERNEL
const char *colname = zfs_prop_table[prop].pd_colname;
int c;
-#endif
-#ifndef _KERNEL
if (colname == NULL)
return (B_FALSE);
#endif
@@ -367,9 +457,8 @@ zfs_name_to_prop_cb(zfs_prop_t prop, void *cb_data)
{
const char *propname = cb_data;
- if (propname_match(propname, prop, strlen(propname))) {
+ if (propname_match(propname, prop, strlen(propname)))
return (prop);
- }
return (ZFS_PROP_CONT);
}
@@ -405,10 +494,11 @@ zpool_name_to_prop(const char *propname)
return (zfs_name_to_prop_common(propname, ZFS_TYPE_POOL));
}
-const char *
-zfs_prop_perm(zfs_prop_t prop)
+boolean_t
+zfs_prop_delegatable(zfs_prop_t prop)
{
- return (zfs_prop_table[prop].pd_perm);
+ prop_desc_t *pd = &zfs_prop_table[prop];
+ return (pd->pd_attr != PROP_READONLY && pd->pd_types != ZFS_TYPE_POOL);
}
/*
@@ -480,7 +570,7 @@ zpool_prop_default_numeric(zpool_prop_t prop)
int
zfs_prop_readonly(zfs_prop_t prop)
{
- return (zfs_prop_table[prop].pd_attr == prop_readonly);
+ return (zfs_prop_table[prop].pd_attr == PROP_READONLY);
}
/*
@@ -509,96 +599,7 @@ zpool_prop_to_name(zpool_prop_t prop)
int
zfs_prop_inheritable(zfs_prop_t prop)
{
- return (zfs_prop_table[prop].pd_attr == prop_inherit);
-}
-
-typedef struct zfs_index {
- const char *name;
- uint64_t index;
-} zfs_index_t;
-
-static zfs_index_t checksum_table[] = {
- { "on", ZIO_CHECKSUM_ON },
- { "off", ZIO_CHECKSUM_OFF },
- { "fletcher2", ZIO_CHECKSUM_FLETCHER_2 },
- { "fletcher4", ZIO_CHECKSUM_FLETCHER_4 },
- { "sha256", ZIO_CHECKSUM_SHA256 },
- { NULL }
-};
-
-static zfs_index_t compress_table[] = {
- { "on", ZIO_COMPRESS_ON },
- { "off", ZIO_COMPRESS_OFF },
- { "lzjb", ZIO_COMPRESS_LZJB },
- { "gzip", ZIO_COMPRESS_GZIP_6 }, /* the default gzip level */
- { "gzip-1", ZIO_COMPRESS_GZIP_1 },
- { "gzip-2", ZIO_COMPRESS_GZIP_2 },
- { "gzip-3", ZIO_COMPRESS_GZIP_3 },
- { "gzip-4", ZIO_COMPRESS_GZIP_4 },
- { "gzip-5", ZIO_COMPRESS_GZIP_5 },
- { "gzip-6", ZIO_COMPRESS_GZIP_6 },
- { "gzip-7", ZIO_COMPRESS_GZIP_7 },
- { "gzip-8", ZIO_COMPRESS_GZIP_8 },
- { "gzip-9", ZIO_COMPRESS_GZIP_9 },
- { NULL }
-};
-
-static zfs_index_t snapdir_table[] = {
- { "hidden", ZFS_SNAPDIR_HIDDEN },
- { "visible", ZFS_SNAPDIR_VISIBLE },
- { NULL }
-};
-
-static zfs_index_t acl_mode_table[] = {
- { "discard", ZFS_ACL_DISCARD },
- { "groupmask", ZFS_ACL_GROUPMASK },
- { "passthrough", ZFS_ACL_PASSTHROUGH },
- { NULL }
-};
-
-static zfs_index_t acl_inherit_table[] = {
- { "discard", ZFS_ACL_DISCARD },
- { "noallow", ZFS_ACL_NOALLOW },
- { "secure", ZFS_ACL_SECURE },
- { "passthrough", ZFS_ACL_PASSTHROUGH },
- { NULL }
-};
-
-static zfs_index_t copies_table[] = {
- { "1", 1 },
- { "2", 2 },
- { "3", 3 },
- { NULL }
-};
-
-static zfs_index_t version_table[] = {
- { "1", 1 },
- { "2", 2 },
- { "current", ZPL_VERSION },
- { NULL }
-};
-
-static zfs_index_t *
-zfs_prop_index_table(zfs_prop_t prop)
-{
- switch (prop) {
- case ZFS_PROP_CHECKSUM:
- return (checksum_table);
- case ZFS_PROP_COMPRESSION:
- return (compress_table);
- case ZFS_PROP_SNAPDIR:
- return (snapdir_table);
- case ZFS_PROP_ACLMODE:
- return (acl_mode_table);
- case ZFS_PROP_ACLINHERIT:
- return (acl_inherit_table);
- case ZFS_PROP_COPIES:
- return (copies_table);
- case ZFS_PROP_VERSION:
- return (version_table);
- default:
- return (NULL);
- }
+ return (zfs_prop_table[prop].pd_attr == PROP_INHERIT);
}
/*
@@ -608,10 +609,10 @@ zfs_prop_index_table(zfs_prop_t prop)
int
zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
{
- zfs_index_t *table;
+ const zfs_index_t *table;
int i;
- if ((table = zfs_prop_index_table(prop)) == NULL)
+ if ((table = zfs_prop_table[prop].pd_table) == NULL)
return (-1);
for (i = 0; table[i].name != NULL; i++) {
@@ -627,10 +628,10 @@ zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
int
zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string)
{
- zfs_index_t *table;
+ const zfs_index_t *table;
int i;
- if ((table = zfs_prop_index_table(prop)) == NULL)
+ if ((table = zfs_prop_table[prop].pd_table) == NULL)
return (-1);
for (i = 0; table[i].name != NULL; i++) {
@@ -679,8 +680,8 @@ zpool_prop_values(zfs_prop_t prop)
int
zfs_prop_is_string(zfs_prop_t prop)
{
- return (zfs_prop_table[prop].pd_proptype == prop_type_string ||
- zfs_prop_table[prop].pd_proptype == prop_type_index);
+ return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING ||
+ zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX);
}
/*
@@ -711,7 +712,7 @@ size_t
zfs_prop_width(zfs_prop_t prop, boolean_t *fixed)
{
prop_desc_t *pd = &zfs_prop_table[prop];
- zfs_index_t *idx;
+ const zfs_index_t *idx;
size_t ret;
int i;
@@ -727,7 +728,7 @@ zfs_prop_width(zfs_prop_t prop, boolean_t *fixed)
* any possible value.
*/
switch (pd->pd_proptype) {
- case prop_type_number:
+ case PROP_TYPE_NUMBER:
/*
* The maximum length of a human-readable number is 5 characters
* ("20.4M", for example).
@@ -741,7 +742,7 @@ zfs_prop_width(zfs_prop_t prop, boolean_t *fixed)
if (prop == ZFS_PROP_CREATION)
*fixed = B_FALSE;
break;
- case prop_type_boolean:
+ case PROP_TYPE_BOOLEAN:
/*
* The maximum length of a boolean value is 3 characters, for
* "off".
@@ -749,15 +750,15 @@ zfs_prop_width(zfs_prop_t prop, boolean_t *fixed)
if (ret < 3)
ret = 3;
break;
- case prop_type_index:
- idx = zfs_prop_index_table(prop);
+ case PROP_TYPE_INDEX:
+ idx = zfs_prop_table[prop].pd_table;
for (i = 0; idx[i].name != NULL; i++) {
if (strlen(idx[i].name) > ret)
ret = strlen(idx[i].name);
}
break;
- case prop_type_string:
+ case PROP_TYPE_STRING:
*fixed = B_FALSE;
break;
}
diff --git a/usr/src/common/zfs/zfs_prop.h b/usr/src/common/zfs/zfs_prop.h
index 3b18ec561f..a0cc65534d 100644
--- a/usr/src/common/zfs/zfs_prop.h
+++ b/usr/src/common/zfs/zfs_prop.h
@@ -40,15 +40,17 @@ extern "C" {
* in the kernel, but the string value in userland.
*/
typedef enum {
- prop_type_number, /* numeric value */
- prop_type_string, /* string value */
- prop_type_boolean, /* boolean value */
- prop_type_index /* numeric value indexed by string */
+ PROP_TYPE_NUMBER, /* numeric value */
+ PROP_TYPE_STRING, /* string value */
+ PROP_TYPE_BOOLEAN, /* boolean value */
+ PROP_TYPE_INDEX /* numeric value indexed by string */
} zfs_proptype_t;
zfs_proptype_t zfs_prop_get_type(zfs_prop_t);
zfs_proptype_t zpool_prop_get_type(zpool_prop_t);
size_t zfs_prop_width(zfs_prop_t, boolean_t *);
+boolean_t zfs_prop_delegatable(zfs_prop_t prop);
+void zfs_prop_init(void);
#ifdef __cplusplus
}