Home | History | Annotate | Line # | Download | only in zfs
zfs_prop.c revision 1.1.1.3
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     23  * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
     24  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
     25  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
     26  * Copyright (c) 2014 Integros [integros.com]
     27  */
     28 
     29 /* Portions Copyright 2010 Robert Milkowski */
     30 
     31 #include <sys/zio.h>
     32 #include <sys/spa.h>
     33 #include <sys/u8_textprep.h>
     34 #include <sys/zfs_acl.h>
     35 #include <sys/zfs_ioctl.h>
     36 #include <sys/zfs_znode.h>
     37 
     38 #include "zfs_prop.h"
     39 #include "zfs_deleg.h"
     40 
     41 #if defined(_KERNEL)
     42 #include <sys/systm.h>
     43 #else
     44 #include <stdlib.h>
     45 #include <string.h>
     46 #include <ctype.h>
     47 #endif
     48 
     49 static zprop_desc_t zfs_prop_table[ZFS_NUM_PROPS];
     50 
     51 /* Note this is indexed by zfs_userquota_prop_t, keep the order the same */
     52 const char *zfs_userquota_prop_prefixes[] = {
     53 	"userused@",
     54 	"userquota@",
     55 	"groupused@",
     56 	"groupquota@"
     57 };
     58 
     59 zprop_desc_t *
     60 zfs_prop_get_table(void)
     61 {
     62 	return (zfs_prop_table);
     63 }
     64 
     65 void
     66 zfs_prop_init(void)
     67 {
     68 	static zprop_index_t checksum_table[] = {
     69 		{ "on",		ZIO_CHECKSUM_ON },
     70 		{ "off",	ZIO_CHECKSUM_OFF },
     71 		{ "fletcher2",	ZIO_CHECKSUM_FLETCHER_2 },
     72 		{ "fletcher4",	ZIO_CHECKSUM_FLETCHER_4 },
     73 		{ "sha256",	ZIO_CHECKSUM_SHA256 },
     74 		{ "noparity",	ZIO_CHECKSUM_NOPARITY },
     75 		{ "sha512",	ZIO_CHECKSUM_SHA512 },
     76 		{ "skein",	ZIO_CHECKSUM_SKEIN },
     77 #ifdef illumos
     78 		{ "edonr",	ZIO_CHECKSUM_EDONR },
     79 #endif
     80 		{ NULL }
     81 	};
     82 
     83 	static zprop_index_t dedup_table[] = {
     84 		{ "on",		ZIO_CHECKSUM_ON },
     85 		{ "off",	ZIO_CHECKSUM_OFF },
     86 		{ "verify",	ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY },
     87 		{ "sha256",	ZIO_CHECKSUM_SHA256 },
     88 		{ "sha256,verify",
     89 				ZIO_CHECKSUM_SHA256 | ZIO_CHECKSUM_VERIFY },
     90 		{ "sha512",	ZIO_CHECKSUM_SHA512 },
     91 		{ "sha512,verify",
     92 				ZIO_CHECKSUM_SHA512 | ZIO_CHECKSUM_VERIFY },
     93 		{ "skein",	ZIO_CHECKSUM_SKEIN },
     94 		{ "skein,verify",
     95 				ZIO_CHECKSUM_SKEIN | ZIO_CHECKSUM_VERIFY },
     96 #ifdef illumos
     97 		{ "edonr,verify",
     98 				ZIO_CHECKSUM_EDONR | ZIO_CHECKSUM_VERIFY },
     99 #endif
    100 		{ NULL }
    101 	};
    102 
    103 	static zprop_index_t compress_table[] = {
    104 		{ "on",		ZIO_COMPRESS_ON },
    105 		{ "off",	ZIO_COMPRESS_OFF },
    106 		{ "lzjb",	ZIO_COMPRESS_LZJB },
    107 		{ "gzip",	ZIO_COMPRESS_GZIP_6 },	/* gzip default */
    108 		{ "gzip-1",	ZIO_COMPRESS_GZIP_1 },
    109 		{ "gzip-2",	ZIO_COMPRESS_GZIP_2 },
    110 		{ "gzip-3",	ZIO_COMPRESS_GZIP_3 },
    111 		{ "gzip-4",	ZIO_COMPRESS_GZIP_4 },
    112 		{ "gzip-5",	ZIO_COMPRESS_GZIP_5 },
    113 		{ "gzip-6",	ZIO_COMPRESS_GZIP_6 },
    114 		{ "gzip-7",	ZIO_COMPRESS_GZIP_7 },
    115 		{ "gzip-8",	ZIO_COMPRESS_GZIP_8 },
    116 		{ "gzip-9",	ZIO_COMPRESS_GZIP_9 },
    117 		{ "zle",	ZIO_COMPRESS_ZLE },
    118 		{ "lz4",	ZIO_COMPRESS_LZ4 },
    119 		{ NULL }
    120 	};
    121 
    122 	static zprop_index_t snapdir_table[] = {
    123 		{ "hidden",	ZFS_SNAPDIR_HIDDEN },
    124 		{ "visible",	ZFS_SNAPDIR_VISIBLE },
    125 		{ NULL }
    126 	};
    127 
    128 	static zprop_index_t acl_mode_table[] = {
    129 		{ "discard",	ZFS_ACL_DISCARD },
    130 		{ "groupmask",	ZFS_ACL_GROUPMASK },
    131 		{ "passthrough", ZFS_ACL_PASSTHROUGH },
    132 		{ "restricted", ZFS_ACL_RESTRICTED },
    133 		{ NULL }
    134 	};
    135 
    136 	static zprop_index_t acl_inherit_table[] = {
    137 		{ "discard",	ZFS_ACL_DISCARD },
    138 		{ "noallow",	ZFS_ACL_NOALLOW },
    139 		{ "restricted",	ZFS_ACL_RESTRICTED },
    140 		{ "passthrough", ZFS_ACL_PASSTHROUGH },
    141 		{ "secure",	ZFS_ACL_RESTRICTED }, /* bkwrd compatability */
    142 		{ "passthrough-x", ZFS_ACL_PASSTHROUGH_X },
    143 		{ NULL }
    144 	};
    145 
    146 	static zprop_index_t case_table[] = {
    147 		{ "sensitive",		ZFS_CASE_SENSITIVE },
    148 		{ "insensitive",	ZFS_CASE_INSENSITIVE },
    149 		{ "mixed",		ZFS_CASE_MIXED },
    150 		{ NULL }
    151 	};
    152 
    153 	static zprop_index_t copies_table[] = {
    154 		{ "1",		1 },
    155 		{ "2",		2 },
    156 		{ "3",		3 },
    157 		{ NULL }
    158 	};
    159 
    160 	/*
    161 	 * Use the unique flags we have to send to u8_strcmp() and/or
    162 	 * u8_textprep() to represent the various normalization property
    163 	 * values.
    164 	 */
    165 	static zprop_index_t normalize_table[] = {
    166 		{ "none",	0 },
    167 		{ "formD",	U8_TEXTPREP_NFD },
    168 		{ "formKC",	U8_TEXTPREP_NFKC },
    169 		{ "formC",	U8_TEXTPREP_NFC },
    170 		{ "formKD",	U8_TEXTPREP_NFKD },
    171 		{ NULL }
    172 	};
    173 
    174 	static zprop_index_t version_table[] = {
    175 		{ "1",		1 },
    176 		{ "2",		2 },
    177 		{ "3",		3 },
    178 		{ "4",		4 },
    179 		{ "5",		5 },
    180 		{ "current",	ZPL_VERSION },
    181 		{ NULL }
    182 	};
    183 
    184 	static zprop_index_t boolean_table[] = {
    185 		{ "off",	0 },
    186 		{ "on",		1 },
    187 		{ NULL }
    188 	};
    189 
    190 	static zprop_index_t logbias_table[] = {
    191 		{ "latency",	ZFS_LOGBIAS_LATENCY },
    192 		{ "throughput",	ZFS_LOGBIAS_THROUGHPUT },
    193 		{ NULL }
    194 	};
    195 
    196 	static zprop_index_t canmount_table[] = {
    197 		{ "off",	ZFS_CANMOUNT_OFF },
    198 		{ "on",		ZFS_CANMOUNT_ON },
    199 		{ "noauto",	ZFS_CANMOUNT_NOAUTO },
    200 		{ NULL }
    201 	};
    202 
    203 	static zprop_index_t cache_table[] = {
    204 		{ "none",	ZFS_CACHE_NONE },
    205 		{ "metadata",	ZFS_CACHE_METADATA },
    206 		{ "all",	ZFS_CACHE_ALL },
    207 		{ NULL }
    208 	};
    209 
    210 	static zprop_index_t sync_table[] = {
    211 		{ "standard",	ZFS_SYNC_STANDARD },
    212 		{ "always",	ZFS_SYNC_ALWAYS },
    213 		{ "disabled",	ZFS_SYNC_DISABLED },
    214 		{ NULL }
    215 	};
    216 
    217 	static zprop_index_t volmode_table[] = {
    218 		{ "default",	ZFS_VOLMODE_DEFAULT },
    219 		{ "geom",	ZFS_VOLMODE_GEOM },
    220 		{ "dev",	ZFS_VOLMODE_DEV },
    221 		{ "none",	ZFS_VOLMODE_NONE },
    222 		{ NULL }
    223 	};
    224 
    225 	static zprop_index_t redundant_metadata_table[] = {
    226 		{ "all",	ZFS_REDUNDANT_METADATA_ALL },
    227 		{ "most",	ZFS_REDUNDANT_METADATA_MOST },
    228 		{ NULL }
    229 	};
    230 
    231 	/* inherit index properties */
    232 	zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata",
    233 	    ZFS_REDUNDANT_METADATA_ALL,
    234 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    235 	    "all | most", "REDUND_MD",
    236 	    redundant_metadata_table);
    237 	zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD,
    238 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    239 	    "standard | always | disabled", "SYNC",
    240 	    sync_table);
    241 	zprop_register_index(ZFS_PROP_CHECKSUM, "checksum",
    242 	    ZIO_CHECKSUM_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM |
    243 	    ZFS_TYPE_VOLUME,
    244 	    "on | off | fletcher2 | fletcher4 | sha256 | sha512 | "
    245 	    "skein | edonr", "CHECKSUM", checksum_table);
    246 	zprop_register_index(ZFS_PROP_DEDUP, "dedup", ZIO_CHECKSUM_OFF,
    247 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    248 	    "on | off | verify | sha256[,verify], sha512[,verify], "
    249 	    "skein[,verify], edonr,verify", "DEDUP", dedup_table);
    250 	zprop_register_index(ZFS_PROP_COMPRESSION, "compression",
    251 	    ZIO_COMPRESS_DEFAULT, PROP_INHERIT,
    252 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    253 	    "on | off | lzjb | gzip | gzip-[1-9] | zle | lz4",
    254 	    "COMPRESS", compress_table);
    255 	zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
    256 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
    257 	    "hidden | visible", "SNAPDIR", snapdir_table);
    258 	zprop_register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_DISCARD,
    259 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
    260 	    "discard | groupmask | passthrough | restricted", "ACLMODE",
    261 	    acl_mode_table);
    262 	zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
    263 	    ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
    264 	    "discard | noallow | restricted | passthrough | passthrough-x",
    265 	    "ACLINHERIT", acl_inherit_table);
    266 	zprop_register_index(ZFS_PROP_COPIES, "copies", 1, PROP_INHERIT,
    267 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    268 	    "1 | 2 | 3", "COPIES", copies_table);
    269 	zprop_register_index(ZFS_PROP_PRIMARYCACHE, "primarycache",
    270 	    ZFS_CACHE_ALL, PROP_INHERIT,
    271 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
    272 	    "all | none | metadata", "PRIMARYCACHE", cache_table);
    273 	zprop_register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache",
    274 	    ZFS_CACHE_ALL, PROP_INHERIT,
    275 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
    276 	    "all | none | metadata", "SECONDARYCACHE", cache_table);
    277 	zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY,
    278 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    279 	    "latency | throughput", "LOGBIAS", logbias_table);
    280 	zprop_register_index(ZFS_PROP_VOLMODE, "volmode",
    281 	    ZFS_VOLMODE_DEFAULT, PROP_INHERIT,
    282 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
    283 	    "default | geom | dev | none", "VOLMODE", volmode_table);
    284 
    285 	/* inherit index (boolean) properties */
    286 	zprop_register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
    287 	    ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table);
    288 	zprop_register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT,
    289 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES",
    290 	    boolean_table);
    291 	zprop_register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT,
    292 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC",
    293 	    boolean_table);
    294 	zprop_register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT,
    295 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
    296 	    boolean_table);
    297 	zprop_register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
    298 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY",
    299 	    boolean_table);
    300 	zprop_register_index(ZFS_PROP_ZONED, "jailed", 0, PROP_INHERIT,
    301 	    ZFS_TYPE_FILESYSTEM, "on | off", "JAILED", boolean_table);
    302 	zprop_register_index(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT,
    303 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR",
    304 	    boolean_table);
    305 	zprop_register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT,
    306 	    ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN",
    307 	    boolean_table);
    308 	zprop_register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT,
    309 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "NBMAND",
    310 	    boolean_table);
    311 
    312 	/* default index properties */
    313 	zprop_register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT,
    314 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
    315 	    "1 | 2 | 3 | 4 | 5 | current", "VERSION", version_table);
    316 	zprop_register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON,
    317 	    PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto",
    318 	    "CANMOUNT", canmount_table);
    319 
    320 	/* readonly index (boolean) properties */
    321 	zprop_register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
    322 	    ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table);
    323 	zprop_register_index(ZFS_PROP_DEFER_DESTROY, "defer_destroy", 0,
    324 	    PROP_READONLY, ZFS_TYPE_SNAPSHOT, "yes | no", "DEFER_DESTROY",
    325 	    boolean_table);
    326 
    327 	/* set once index properties */
    328 	zprop_register_index(ZFS_PROP_NORMALIZE, "normalization", 0,
    329 	    PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
    330 	    "none | formC | formD | formKC | formKD", "NORMALIZATION",
    331 	    normalize_table);
    332 	zprop_register_index(ZFS_PROP_CASE, "casesensitivity",
    333 	    ZFS_CASE_SENSITIVE, PROP_ONETIME, ZFS_TYPE_FILESYSTEM |
    334 	    ZFS_TYPE_SNAPSHOT,
    335 	    "sensitive | insensitive | mixed", "CASE", case_table);
    336 
    337 	/* set once index (boolean) properties */
    338 	zprop_register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME,
    339 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
    340 	    "on | off", "UTF8ONLY", boolean_table);
    341 
    342 	/* string properties */
    343 	zprop_register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
    344 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
    345 	zprop_register_string(ZFS_PROP_CLONES, "clones", NULL, PROP_READONLY,
    346 	    ZFS_TYPE_SNAPSHOT, "<dataset>[,...]", "CLONES");
    347 	zprop_register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/",
    348 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "<path> | legacy | none",
    349 	    "MOUNTPOINT");
    350 	zprop_register_string(ZFS_PROP_SHARENFS, "sharenfs", "off",
    351 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options",
    352 	    "SHARENFS");
    353 	zprop_register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY,
    354 	    ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK,
    355 	    "filesystem | volume | snapshot | bookmark", "TYPE");
    356 	zprop_register_string(ZFS_PROP_SHARESMB, "sharesmb", "off",
    357 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
    358 	    "on | off | sharemgr(1M) options", "SHARESMB");
    359 	zprop_register_string(ZFS_PROP_MLSLABEL, "mlslabel",
    360 	    ZFS_MLSLABEL_DEFAULT, PROP_INHERIT, ZFS_TYPE_DATASET,
    361 	    "<sensitivity label>", "MLSLABEL");
    362 	zprop_register_string(ZFS_PROP_RECEIVE_RESUME_TOKEN,
    363 	    "receive_resume_token",
    364 	    NULL, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    365 	    "<string token>", "RESUMETOK");
    366 
    367 	/* readonly number properties */
    368 	zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
    369 	    ZFS_TYPE_DATASET, "<size>", "USED");
    370 	zprop_register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY,
    371 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL");
    372 	zprop_register_number(ZFS_PROP_REFERENCED, "referenced", 0,
    373 	    PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "REFER");
    374 	zprop_register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
    375 	    PROP_READONLY, ZFS_TYPE_DATASET,
    376 	    "<1.00x or higher if compressed>", "RATIO");
    377 	zprop_register_number(ZFS_PROP_REFRATIO, "refcompressratio", 0,
    378 	    PROP_READONLY, ZFS_TYPE_DATASET,
    379 	    "<1.00x or higher if compressed>", "REFRATIO");
    380 	zprop_register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize",
    381 	    ZVOL_DEFAULT_BLOCKSIZE, PROP_ONETIME,
    382 	    ZFS_TYPE_VOLUME, "512 to 128k, power of 2",	"VOLBLOCK");
    383 	zprop_register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0,
    384 	    PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
    385 	    "USEDSNAP");
    386 	zprop_register_number(ZFS_PROP_USEDDS, "usedbydataset", 0,
    387 	    PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
    388 	    "USEDDS");
    389 	zprop_register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0,
    390 	    PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
    391 	    "USEDCHILD");
    392 	zprop_register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0,
    393 	    PROP_READONLY,
    394 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV");
    395 	zprop_register_number(ZFS_PROP_USERREFS, "userrefs", 0, PROP_READONLY,
    396 	    ZFS_TYPE_SNAPSHOT, "<count>", "USERREFS");
    397 	zprop_register_number(ZFS_PROP_WRITTEN, "written", 0, PROP_READONLY,
    398 	    ZFS_TYPE_DATASET, "<size>", "WRITTEN");
    399 	zprop_register_number(ZFS_PROP_LOGICALUSED, "logicalused", 0,
    400 	    PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LUSED");
    401 	zprop_register_number(ZFS_PROP_LOGICALREFERENCED, "logicalreferenced",
    402 	    0, PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LREFER");
    403 
    404 	/* default number properties */
    405 	zprop_register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
    406 	    ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
    407 	zprop_register_number(ZFS_PROP_RESERVATION, "reservation", 0,
    408 	    PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    409 	    "<size> | none", "RESERV");
    410 	zprop_register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
    411 	    ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
    412 	zprop_register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT,
    413 	    ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA");
    414 	zprop_register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0,
    415 	    PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    416 	    "<size> | none", "REFRESERV");
    417 	zprop_register_number(ZFS_PROP_FILESYSTEM_LIMIT, "filesystem_limit",
    418 	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
    419 	    "<count> | none", "FSLIMIT");
    420 	zprop_register_number(ZFS_PROP_SNAPSHOT_LIMIT, "snapshot_limit",
    421 	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    422 	    "<count> | none", "SSLIMIT");
    423 	zprop_register_number(ZFS_PROP_FILESYSTEM_COUNT, "filesystem_count",
    424 	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
    425 	    "<count>", "FSCOUNT");
    426 	zprop_register_number(ZFS_PROP_SNAPSHOT_COUNT, "snapshot_count",
    427 	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    428 	    "<count>", "SSCOUNT");
    429 
    430 	/* inherit number properties */
    431 	zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize",
    432 	    SPA_OLD_MAXBLOCKSIZE, PROP_INHERIT,
    433 	    ZFS_TYPE_FILESYSTEM, "512 to 1M, power of 2", "RECSIZE");
    434 
    435 	/* hidden properties */
    436 	zprop_register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER,
    437 	    PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "CREATETXG");
    438 	zprop_register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
    439 	    PROP_READONLY, ZFS_TYPE_SNAPSHOT, "NUMCLONES");
    440 	zprop_register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
    441 	    PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "NAME");
    442 	zprop_register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions",
    443 	    PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS");
    444 	zprop_register_hidden(ZFS_PROP_STMF_SHAREINFO, "stmf_sbd_lu",
    445 	    PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME,
    446 	    "STMF_SBD_LU");
    447 	zprop_register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER,
    448 	    PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "GUID");
    449 	zprop_register_hidden(ZFS_PROP_USERACCOUNTING, "useraccounting",
    450 	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET,
    451 	    "USERACCOUNTING");
    452 	zprop_register_hidden(ZFS_PROP_UNIQUE, "unique", PROP_TYPE_NUMBER,
    453 	    PROP_READONLY, ZFS_TYPE_DATASET, "UNIQUE");
    454 	zprop_register_hidden(ZFS_PROP_OBJSETID, "objsetid", PROP_TYPE_NUMBER,
    455 	    PROP_READONLY, ZFS_TYPE_DATASET, "OBJSETID");
    456 	zprop_register_hidden(ZFS_PROP_INCONSISTENT, "inconsistent",
    457 	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT");
    458 	zprop_register_hidden(ZFS_PROP_PREV_SNAP, "prevsnap", PROP_TYPE_STRING,
    459 	    PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PREVSNAP");
    460 
    461 	/* oddball properties */
    462 	zprop_register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0,
    463 	    NULL, PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK,
    464 	    "<date>", "CREATION", B_FALSE, B_TRUE, NULL);
    465 }
    466 
    467 boolean_t
    468 zfs_prop_delegatable(zfs_prop_t prop)
    469 {
    470 	zprop_desc_t *pd = &zfs_prop_table[prop];
    471 
    472 	/* The mlslabel property is never delegatable. */
    473 	if (prop == ZFS_PROP_MLSLABEL)
    474 		return (B_FALSE);
    475 
    476 	return (pd->pd_attr != PROP_READONLY);
    477 }
    478 
    479 /*
    480  * Given a zfs dataset property name, returns the corresponding property ID.
    481  */
    482 zfs_prop_t
    483 zfs_name_to_prop(const char *propname)
    484 {
    485 	return (zprop_name_to_prop(propname, ZFS_TYPE_DATASET));
    486 }
    487 
    488 /*
    489  * For user property names, we allow all lowercase alphanumeric characters, plus
    490  * a few useful punctuation characters.
    491  */
    492 static int
    493 valid_char(char c)
    494 {
    495 	return ((c >= 'a' && c <= 'z') ||
    496 	    (c >= '0' && c <= '9') ||
    497 	    c == '-' || c == '_' || c == '.' || c == ':');
    498 }
    499 
    500 /*
    501  * Returns true if this is a valid user-defined property (one with a ':').
    502  */
    503 boolean_t
    504 zfs_prop_user(const char *name)
    505 {
    506 	int i;
    507 	char c;
    508 	boolean_t foundsep = B_FALSE;
    509 
    510 	for (i = 0; i < strlen(name); i++) {
    511 		c = name[i];
    512 		if (!valid_char(c))
    513 			return (B_FALSE);
    514 		if (c == ':')
    515 			foundsep = B_TRUE;
    516 	}
    517 
    518 	if (!foundsep)
    519 		return (B_FALSE);
    520 
    521 	return (B_TRUE);
    522 }
    523 
    524 /*
    525  * Returns true if this is a valid userspace-type property (one with a '@').
    526  * Note that after the @, any character is valid (eg, another @, for SID
    527  * user@domain).
    528  */
    529 boolean_t
    530 zfs_prop_userquota(const char *name)
    531 {
    532 	zfs_userquota_prop_t prop;
    533 
    534 	for (prop = 0; prop < ZFS_NUM_USERQUOTA_PROPS; prop++) {
    535 		if (strncmp(name, zfs_userquota_prop_prefixes[prop],
    536 		    strlen(zfs_userquota_prop_prefixes[prop])) == 0) {
    537 			return (B_TRUE);
    538 		}
    539 	}
    540 
    541 	return (B_FALSE);
    542 }
    543 
    544 /*
    545  * Returns true if this is a valid written@ property.
    546  * Note that after the @, any character is valid (eg, another @, for
    547  * written@pool/fs@origin).
    548  */
    549 boolean_t
    550 zfs_prop_written(const char *name)
    551 {
    552 	static const char *prefix = "written@";
    553 	return (strncmp(name, prefix, strlen(prefix)) == 0);
    554 }
    555 
    556 /*
    557  * Tables of index types, plus functions to convert between the user view
    558  * (strings) and internal representation (uint64_t).
    559  */
    560 int
    561 zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
    562 {
    563 	return (zprop_string_to_index(prop, string, index, ZFS_TYPE_DATASET));
    564 }
    565 
    566 int
    567 zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string)
    568 {
    569 	return (zprop_index_to_string(prop, index, string, ZFS_TYPE_DATASET));
    570 }
    571 
    572 uint64_t
    573 zfs_prop_random_value(zfs_prop_t prop, uint64_t seed)
    574 {
    575 	return (zprop_random_value(prop, seed, ZFS_TYPE_DATASET));
    576 }
    577 
    578 /*
    579  * Returns TRUE if the property applies to any of the given dataset types.
    580  */
    581 boolean_t
    582 zfs_prop_valid_for_type(int prop, zfs_type_t types)
    583 {
    584 	return (zprop_valid_for_type(prop, types));
    585 }
    586 
    587 zprop_type_t
    588 zfs_prop_get_type(zfs_prop_t prop)
    589 {
    590 	return (zfs_prop_table[prop].pd_proptype);
    591 }
    592 
    593 /*
    594  * Returns TRUE if the property is readonly.
    595  */
    596 boolean_t
    597 zfs_prop_readonly(zfs_prop_t prop)
    598 {
    599 	return (zfs_prop_table[prop].pd_attr == PROP_READONLY ||
    600 	    zfs_prop_table[prop].pd_attr == PROP_ONETIME);
    601 }
    602 
    603 /*
    604  * Returns TRUE if the property is only allowed to be set once.
    605  */
    606 boolean_t
    607 zfs_prop_setonce(zfs_prop_t prop)
    608 {
    609 	return (zfs_prop_table[prop].pd_attr == PROP_ONETIME);
    610 }
    611 
    612 const char *
    613 zfs_prop_default_string(zfs_prop_t prop)
    614 {
    615 	return (zfs_prop_table[prop].pd_strdefault);
    616 }
    617 
    618 uint64_t
    619 zfs_prop_default_numeric(zfs_prop_t prop)
    620 {
    621 	return (zfs_prop_table[prop].pd_numdefault);
    622 }
    623 
    624 /*
    625  * Given a dataset property ID, returns the corresponding name.
    626  * Assuming the zfs dataset property ID is valid.
    627  */
    628 const char *
    629 zfs_prop_to_name(zfs_prop_t prop)
    630 {
    631 	return (zfs_prop_table[prop].pd_name);
    632 }
    633 
    634 /*
    635  * Returns TRUE if the property is inheritable.
    636  */
    637 boolean_t
    638 zfs_prop_inheritable(zfs_prop_t prop)
    639 {
    640 	return (zfs_prop_table[prop].pd_attr == PROP_INHERIT ||
    641 	    zfs_prop_table[prop].pd_attr == PROP_ONETIME);
    642 }
    643 
    644 #ifndef _KERNEL
    645 
    646 /*
    647  * Returns a string describing the set of acceptable values for the given
    648  * zfs property, or NULL if it cannot be set.
    649  */
    650 const char *
    651 zfs_prop_values(zfs_prop_t prop)
    652 {
    653 	return (zfs_prop_table[prop].pd_values);
    654 }
    655 
    656 /*
    657  * Returns TRUE if this property is a string type.  Note that index types
    658  * (compression, checksum) are treated as strings in userland, even though they
    659  * are stored numerically on disk.
    660  */
    661 int
    662 zfs_prop_is_string(zfs_prop_t prop)
    663 {
    664 	return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING ||
    665 	    zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX);
    666 }
    667 
    668 /*
    669  * Returns the column header for the given property.  Used only in
    670  * 'zfs list -o', but centralized here with the other property information.
    671  */
    672 const char *
    673 zfs_prop_column_name(zfs_prop_t prop)
    674 {
    675 	return (zfs_prop_table[prop].pd_colname);
    676 }
    677 
    678 /*
    679  * Returns whether the given property should be displayed right-justified for
    680  * 'zfs list'.
    681  */
    682 boolean_t
    683 zfs_prop_align_right(zfs_prop_t prop)
    684 {
    685 	return (zfs_prop_table[prop].pd_rightalign);
    686 }
    687 
    688 #endif
    689