xref: /illumos-gate/usr/src/common/zfs/zfs_prop.c (revision 91ebeef555ce7f899b6270a3c2df47b51f7ad59a)
1fa9e4066Sahrens /*
2fa9e4066Sahrens  * CDDL HEADER START
3fa9e4066Sahrens  *
4fa9e4066Sahrens  * The contents of this file are subject to the terms of the
5906d120cSlling  * Common Development and Distribution License (the "License").
6906d120cSlling  * You may not use this file except in compliance with the License.
7fa9e4066Sahrens  *
8fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
10fa9e4066Sahrens  * See the License for the specific language governing permissions
11fa9e4066Sahrens  * and limitations under the License.
12fa9e4066Sahrens  *
13fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e4066Sahrens  *
19fa9e4066Sahrens  * CDDL HEADER END
20fa9e4066Sahrens  */
21fa9e4066Sahrens /*
2239c23413Seschrock  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23fa9e4066Sahrens  * Use is subject to license terms.
24fa9e4066Sahrens  */
25fa9e4066Sahrens 
26fa9e4066Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
27fa9e4066Sahrens 
28fa9e4066Sahrens #include <sys/zio.h>
29fa9e4066Sahrens #include <sys/spa.h>
30fa9e4066Sahrens #include <sys/zfs_acl.h>
31fa9e4066Sahrens #include <sys/zfs_ioctl.h>
32e7437265Sahrens #include <sys/zfs_znode.h>
33fa9e4066Sahrens 
34fa9e4066Sahrens #include "zfs_prop.h"
35ecd6cf80Smarks #include "zfs_deleg.h"
36fa9e4066Sahrens 
37fa9e4066Sahrens #if defined(_KERNEL)
38fa9e4066Sahrens #include <sys/systm.h>
39d3c8f894Stimf #include <util/qsort.h>
40fa9e4066Sahrens #else
41fa9e4066Sahrens #include <stdlib.h>
42fa9e4066Sahrens #include <string.h>
43fa9e4066Sahrens #include <ctype.h>
44fa9e4066Sahrens #endif
45fa9e4066Sahrens 
46fa9e4066Sahrens typedef enum {
47*91ebeef5Sahrens 	PROP_DEFAULT,
48*91ebeef5Sahrens 	PROP_READONLY,
49*91ebeef5Sahrens 	PROP_INHERIT
50fa9e4066Sahrens } prop_attr_t;
51fa9e4066Sahrens 
52*91ebeef5Sahrens typedef struct zfs_index {
53*91ebeef5Sahrens 	const char *name;
54*91ebeef5Sahrens 	uint64_t index;
55*91ebeef5Sahrens } zfs_index_t;
56*91ebeef5Sahrens 
57fa9e4066Sahrens typedef struct {
58*91ebeef5Sahrens 	const char *pd_name;		/* human-readable property name */
59*91ebeef5Sahrens 	zfs_proptype_t pd_proptype;	/* string, boolean, index, number */
60*91ebeef5Sahrens 	const char *pd_strdefault;	/* default for strings */
61*91ebeef5Sahrens 	uint64_t pd_numdefault;		/* for boolean / index / number */
62*91ebeef5Sahrens 	prop_attr_t pd_attr;		/* default, readonly, inherit */
63*91ebeef5Sahrens 	int pd_types;			/* bitfield of valid dataset types */
64*91ebeef5Sahrens 					/* fs | vol | snap; or pool */
65*91ebeef5Sahrens 	const char *pd_values;		/* string telling acceptable values */
66*91ebeef5Sahrens 	const char *pd_colname;		/* column header for "zfs list" */
67*91ebeef5Sahrens 	boolean_t pd_rightalign;	/* column alignment for "zfs list" */
68*91ebeef5Sahrens 	boolean_t pd_visible;		/* do we list this property with the */
69*91ebeef5Sahrens 					/* "zfs get" help message */
70*91ebeef5Sahrens 	const zfs_index_t *pd_table;	/* for index properties, a table */
71*91ebeef5Sahrens 					/* defining the possible values */
72fa9e4066Sahrens } prop_desc_t;
73fa9e4066Sahrens 
74*91ebeef5Sahrens static prop_desc_t zfs_prop_table[ZFS_NUM_PROPS];
75*91ebeef5Sahrens 
76*91ebeef5Sahrens static void
77*91ebeef5Sahrens register_impl(zfs_prop_t prop, const char *name, zfs_proptype_t type,
78*91ebeef5Sahrens     uint64_t numdefault, const char *strdefault, prop_attr_t attr,
79*91ebeef5Sahrens     int objset_types, const char *values, const char *colname,
80*91ebeef5Sahrens     boolean_t rightalign, boolean_t visible, const zfs_index_t *table)
81*91ebeef5Sahrens {
82*91ebeef5Sahrens 	prop_desc_t *pd = &zfs_prop_table[prop];
83*91ebeef5Sahrens 
84*91ebeef5Sahrens 	ASSERT(pd->pd_name == NULL || pd->pd_name == name);
85*91ebeef5Sahrens 
86*91ebeef5Sahrens 	pd->pd_name = name;
87*91ebeef5Sahrens 	pd->pd_proptype = type;
88*91ebeef5Sahrens 	pd->pd_numdefault = numdefault;
89*91ebeef5Sahrens 	pd->pd_strdefault = strdefault;
90*91ebeef5Sahrens 	pd->pd_attr = attr;
91*91ebeef5Sahrens 	pd->pd_types = objset_types;
92*91ebeef5Sahrens 	pd->pd_values = values;
93*91ebeef5Sahrens 	pd->pd_colname = colname;
94*91ebeef5Sahrens 	pd->pd_rightalign = rightalign;
95*91ebeef5Sahrens 	pd->pd_visible = visible;
96*91ebeef5Sahrens 	pd->pd_table = table;
97*91ebeef5Sahrens }
98*91ebeef5Sahrens 
99*91ebeef5Sahrens static void
100*91ebeef5Sahrens register_string(zfs_prop_t prop, const char *name, const char *def,
101*91ebeef5Sahrens     prop_attr_t attr, int objset_types, const char *values,
102*91ebeef5Sahrens     const char *colname)
103*91ebeef5Sahrens {
104*91ebeef5Sahrens 	register_impl(prop, name, PROP_TYPE_STRING, 0, def, attr,
105*91ebeef5Sahrens 	    objset_types, values, colname, B_FALSE, B_TRUE, NULL);
106*91ebeef5Sahrens 
107*91ebeef5Sahrens }
108*91ebeef5Sahrens 
109*91ebeef5Sahrens static void
110*91ebeef5Sahrens register_number(zfs_prop_t prop, const char *name, uint64_t def,
111*91ebeef5Sahrens     prop_attr_t attr, int objset_types, const char *values, const char *colname)
112*91ebeef5Sahrens {
113*91ebeef5Sahrens 	register_impl(prop, name, PROP_TYPE_NUMBER, def, NULL, attr,
114*91ebeef5Sahrens 	    objset_types, values, colname, B_TRUE, B_TRUE, NULL);
115*91ebeef5Sahrens }
116*91ebeef5Sahrens 
117*91ebeef5Sahrens static void
118*91ebeef5Sahrens register_boolean(zfs_prop_t prop, const char *name, uint64_t def,
119*91ebeef5Sahrens     prop_attr_t attr, int objset_types, const char *values, const char *colname)
120*91ebeef5Sahrens {
121*91ebeef5Sahrens 	register_impl(prop, name, PROP_TYPE_BOOLEAN, def, NULL, attr,
122*91ebeef5Sahrens 	    objset_types, values, colname, B_TRUE, B_TRUE, NULL);
123*91ebeef5Sahrens }
124*91ebeef5Sahrens 
125*91ebeef5Sahrens static void
126*91ebeef5Sahrens register_index(zfs_prop_t prop, const char *name, uint64_t def,
127*91ebeef5Sahrens     int objset_types, const char *values, const char *colname,
128*91ebeef5Sahrens     const zfs_index_t *table)
129*91ebeef5Sahrens {
130*91ebeef5Sahrens 	register_impl(prop, name, PROP_TYPE_INDEX, def, NULL, PROP_INHERIT,
131*91ebeef5Sahrens 	    objset_types, values, colname, B_TRUE, B_TRUE, table);
132*91ebeef5Sahrens }
133*91ebeef5Sahrens 
134*91ebeef5Sahrens static void
135*91ebeef5Sahrens register_hidden(zfs_prop_t prop, const char *name, zfs_proptype_t type,
136*91ebeef5Sahrens     prop_attr_t attr, int objset_types, const char *colname)
137*91ebeef5Sahrens {
138*91ebeef5Sahrens 	register_impl(prop, name, type, 0, NULL, attr,
139*91ebeef5Sahrens 	    objset_types, NULL, colname, B_FALSE, B_FALSE, NULL);
140*91ebeef5Sahrens }
141*91ebeef5Sahrens 
142*91ebeef5Sahrens void
143*91ebeef5Sahrens zfs_prop_init(void)
144*91ebeef5Sahrens {
145*91ebeef5Sahrens 	static zfs_index_t checksum_table[] = {
146*91ebeef5Sahrens 		{ "on",		ZIO_CHECKSUM_ON },
147*91ebeef5Sahrens 		{ "off",	ZIO_CHECKSUM_OFF },
148*91ebeef5Sahrens 		{ "fletcher2",	ZIO_CHECKSUM_FLETCHER_2 },
149*91ebeef5Sahrens 		{ "fletcher4",	ZIO_CHECKSUM_FLETCHER_4 },
150*91ebeef5Sahrens 		{ "sha256",	ZIO_CHECKSUM_SHA256 },
151*91ebeef5Sahrens 		{ NULL }
152*91ebeef5Sahrens 	};
153*91ebeef5Sahrens 
154*91ebeef5Sahrens 	static zfs_index_t compress_table[] = {
155*91ebeef5Sahrens 		{ "on",		ZIO_COMPRESS_ON },
156*91ebeef5Sahrens 		{ "off",	ZIO_COMPRESS_OFF },
157*91ebeef5Sahrens 		{ "lzjb",	ZIO_COMPRESS_LZJB },
158*91ebeef5Sahrens 		{ "gzip",	ZIO_COMPRESS_GZIP_6 },	/* gzip default */
159*91ebeef5Sahrens 		{ "gzip-1",	ZIO_COMPRESS_GZIP_1 },
160*91ebeef5Sahrens 		{ "gzip-2",	ZIO_COMPRESS_GZIP_2 },
161*91ebeef5Sahrens 		{ "gzip-3",	ZIO_COMPRESS_GZIP_3 },
162*91ebeef5Sahrens 		{ "gzip-4",	ZIO_COMPRESS_GZIP_4 },
163*91ebeef5Sahrens 		{ "gzip-5",	ZIO_COMPRESS_GZIP_5 },
164*91ebeef5Sahrens 		{ "gzip-6",	ZIO_COMPRESS_GZIP_6 },
165*91ebeef5Sahrens 		{ "gzip-7",	ZIO_COMPRESS_GZIP_7 },
166*91ebeef5Sahrens 		{ "gzip-8",	ZIO_COMPRESS_GZIP_8 },
167*91ebeef5Sahrens 		{ "gzip-9",	ZIO_COMPRESS_GZIP_9 },
168*91ebeef5Sahrens 		{ NULL }
169*91ebeef5Sahrens 	};
170*91ebeef5Sahrens 
171*91ebeef5Sahrens 	static zfs_index_t snapdir_table[] = {
172*91ebeef5Sahrens 		{ "hidden",	ZFS_SNAPDIR_HIDDEN },
173*91ebeef5Sahrens 		{ "visible",	ZFS_SNAPDIR_VISIBLE },
174*91ebeef5Sahrens 		{ NULL }
175*91ebeef5Sahrens 	};
176*91ebeef5Sahrens 
177*91ebeef5Sahrens 	static zfs_index_t acl_mode_table[] = {
178*91ebeef5Sahrens 		{ "discard",	ZFS_ACL_DISCARD },
179*91ebeef5Sahrens 		{ "groupmask",	ZFS_ACL_GROUPMASK },
180*91ebeef5Sahrens 		{ "passthrough", ZFS_ACL_PASSTHROUGH },
181*91ebeef5Sahrens 		{ NULL }
182*91ebeef5Sahrens 	};
183*91ebeef5Sahrens 
184*91ebeef5Sahrens 	static zfs_index_t acl_inherit_table[] = {
185*91ebeef5Sahrens 		{ "discard",	ZFS_ACL_DISCARD },
186*91ebeef5Sahrens 		{ "noallow",	ZFS_ACL_NOALLOW },
187*91ebeef5Sahrens 		{ "secure",	ZFS_ACL_SECURE },
188*91ebeef5Sahrens 		{ "passthrough", ZFS_ACL_PASSTHROUGH },
189*91ebeef5Sahrens 		{ NULL }
190*91ebeef5Sahrens 	};
191*91ebeef5Sahrens 
192*91ebeef5Sahrens 	static zfs_index_t copies_table[] = {
193*91ebeef5Sahrens 		{ "1",		1 },
194*91ebeef5Sahrens 		{ "2",		2 },
195*91ebeef5Sahrens 		{ "3",		3 },
196*91ebeef5Sahrens 		{ NULL }
197*91ebeef5Sahrens 	};
198*91ebeef5Sahrens 
199*91ebeef5Sahrens 	static zfs_index_t version_table[] = {
200*91ebeef5Sahrens 		{ "1",		1 },
201*91ebeef5Sahrens 		{ "2",		2 },
202*91ebeef5Sahrens 		{ "current",	ZPL_VERSION },
203*91ebeef5Sahrens 		{ NULL }
204*91ebeef5Sahrens 	};
205*91ebeef5Sahrens 
206*91ebeef5Sahrens 	/* inherit index properties */
207*91ebeef5Sahrens 	register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT,
208fa9e4066Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
209*91ebeef5Sahrens 	    "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM",
210*91ebeef5Sahrens 	    checksum_table);
211*91ebeef5Sahrens 	register_index(ZFS_PROP_COMPRESSION, "compression",
212*91ebeef5Sahrens 	    ZIO_COMPRESS_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
213*91ebeef5Sahrens 	    "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", compress_table);
214*91ebeef5Sahrens 	register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
215*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "hidden | visible", "SNAPDIR", snapdir_table);
216*91ebeef5Sahrens 	register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK,
217*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "discard | groupmask | passthrough", "ACLMODE",
218*91ebeef5Sahrens 	    acl_mode_table);
219*91ebeef5Sahrens 	register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_SECURE,
220fa9e4066Sahrens 	    ZFS_TYPE_FILESYSTEM,
221*91ebeef5Sahrens 	    "discard | noallow | secure | passthrough", "ACLINHERIT",
222*91ebeef5Sahrens 	    acl_inherit_table);
223*91ebeef5Sahrens 	register_index(ZFS_PROP_COPIES, "copies", 1,
2244f75c27eSeschrock 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
225*91ebeef5Sahrens 	    "1 | 2 | 3", "COPIES", copies_table);
226*91ebeef5Sahrens 	register_index(ZFS_PROP_VERSION, "version", 0,
2277b55fa8eSck 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
228*91ebeef5Sahrens 	    "1 | 2 | current", "VERSION", version_table);
229*91ebeef5Sahrens 
230*91ebeef5Sahrens 	/* string properties */
231*91ebeef5Sahrens 	register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
232*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
233*91ebeef5Sahrens 	register_string(ZPOOL_PROP_BOOTFS, "bootfs", NULL, PROP_DEFAULT,
234*91ebeef5Sahrens 	    ZFS_TYPE_POOL, "<filesystem>", "BOOTFS");
235*91ebeef5Sahrens 	register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", PROP_INHERIT,
236*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", "MOUNTPOINT");
237*91ebeef5Sahrens 	register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", PROP_INHERIT,
238*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", "SHARENFS");
239*91ebeef5Sahrens 	register_string(ZFS_PROP_SHAREISCSI, "shareiscsi", "off", PROP_INHERIT,
240*91ebeef5Sahrens 	    ZFS_TYPE_ANY, "on | off | type=<type>", "SHAREISCSI");
241*91ebeef5Sahrens 	register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY,
242*91ebeef5Sahrens 	    ZFS_TYPE_ANY, "filesystem | volume | snapshot", "TYPE");
243*91ebeef5Sahrens 
244*91ebeef5Sahrens 	/* readonly number properties */
245*91ebeef5Sahrens 	register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
246*91ebeef5Sahrens 	    ZFS_TYPE_ANY, "<size>", "USED");
247*91ebeef5Sahrens 	register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY,
248d0ad202dSahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
249*91ebeef5Sahrens 	    "<size>", "AVAIL");
250*91ebeef5Sahrens 	register_number(ZFS_PROP_REFERENCED, "referenced", 0, PROP_READONLY,
251*91ebeef5Sahrens 	    ZFS_TYPE_ANY, "<size>", "REFER");
252*91ebeef5Sahrens 	register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
253*91ebeef5Sahrens 	    PROP_READONLY, ZFS_TYPE_ANY,
254*91ebeef5Sahrens 	    "<1.00x or higher if compressed>", "RATIO");
255*91ebeef5Sahrens 	register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192,
256*91ebeef5Sahrens 	    PROP_READONLY,
257*91ebeef5Sahrens 	    ZFS_TYPE_VOLUME, "512 to 128k, power of 2",	"VOLBLOCK");
258*91ebeef5Sahrens 
259*91ebeef5Sahrens 	/* default number properties */
260*91ebeef5Sahrens 	register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
261*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
262*91ebeef5Sahrens 	register_number(ZFS_PROP_RESERVATION, "reservation", 0, PROP_DEFAULT,
263*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "RESERV");
264*91ebeef5Sahrens 	register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
265*91ebeef5Sahrens 	    ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
266*91ebeef5Sahrens 
267*91ebeef5Sahrens 	/* inherit number properties */
268*91ebeef5Sahrens 	register_number(ZFS_PROP_RECORDSIZE, "recordsize", SPA_MAXBLOCKSIZE,
269*91ebeef5Sahrens 	    PROP_INHERIT,
270*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE");
271*91ebeef5Sahrens 
272*91ebeef5Sahrens 	/* readonly boolean properties */
273*91ebeef5Sahrens 	register_boolean(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
274*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "yes | no | -", "MOUNTED");
275*91ebeef5Sahrens 
276*91ebeef5Sahrens 	/* default boolean properties */
277*91ebeef5Sahrens 	register_boolean(ZFS_PROP_CANMOUNT, "canmount", 1, PROP_DEFAULT,
278*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "on | off", "CANMOUNT");
279*91ebeef5Sahrens 	register_boolean(ZPOOL_PROP_DELEGATION, "delegation", 1, PROP_DEFAULT,
280*91ebeef5Sahrens 	    ZFS_TYPE_POOL, "on | off", "DELEGATION");
281*91ebeef5Sahrens 	register_boolean(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0, PROP_DEFAULT,
282*91ebeef5Sahrens 	    ZFS_TYPE_POOL, "on | off", "REPLACE");
283*91ebeef5Sahrens 
284*91ebeef5Sahrens 	/* inherit boolean properties */
285*91ebeef5Sahrens 	register_boolean(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
286*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "on | off", "ATIME");
287*91ebeef5Sahrens 	register_boolean(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT,
288*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES");
289*91ebeef5Sahrens 	register_boolean(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT,
290*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC");
291*91ebeef5Sahrens 	register_boolean(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT,
292*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID");
293*91ebeef5Sahrens 	register_boolean(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
294*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY");
295*91ebeef5Sahrens 	register_boolean(ZFS_PROP_ZONED, "zoned", 0, PROP_INHERIT,
296*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM, "on | off", "ZONED");
297*91ebeef5Sahrens 	register_boolean(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT,
298*91ebeef5Sahrens 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR");
299*91ebeef5Sahrens 
300*91ebeef5Sahrens 	/* hidden properties */
301*91ebeef5Sahrens 	register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER,
302*91ebeef5Sahrens 	    PROP_READONLY, ZFS_TYPE_ANY, NULL);
303*91ebeef5Sahrens 	register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
304*91ebeef5Sahrens 	    PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL);
305*91ebeef5Sahrens 	register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
306*91ebeef5Sahrens 	    PROP_READONLY, ZFS_TYPE_ANY, "NAME");
307*91ebeef5Sahrens 	register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING,
308*91ebeef5Sahrens 	    PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS");
309*91ebeef5Sahrens 	register_hidden(ZPOOL_PROP_NAME, "zpoolname", PROP_TYPE_STRING,
310*91ebeef5Sahrens 	    PROP_READONLY, ZFS_TYPE_POOL, NULL);
311*91ebeef5Sahrens 
312*91ebeef5Sahrens 	/* oddball properties */
313*91ebeef5Sahrens 	register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL,
314*91ebeef5Sahrens 	    PROP_READONLY, ZFS_TYPE_ANY,
315*91ebeef5Sahrens 	    "<date>", "CREATION", B_FALSE, B_TRUE, NULL);
316*91ebeef5Sahrens }
317*91ebeef5Sahrens 
31866e2aaccSgw 
319b1b8ab34Slling /*
320*91ebeef5Sahrens  * Returns TRUE if the property applies to any of the given dataset types.
321b1b8ab34Slling  */
322b1b8ab34Slling int
323b1b8ab34Slling zfs_prop_valid_for_type(zfs_prop_t prop, int types)
324b1b8ab34Slling {
325b1b8ab34Slling 	return ((zfs_prop_table[prop].pd_types & types) != 0);
326b1b8ab34Slling }
327b1b8ab34Slling 
328b1b8ab34Slling /*
329b1b8ab34Slling  * Determine if the specified property is visible or not.
330b1b8ab34Slling  */
331b1b8ab34Slling boolean_t
332b1b8ab34Slling zfs_prop_is_visible(zfs_prop_t prop)
333b1b8ab34Slling {
334b1b8ab34Slling 	if (prop < 0)
335b1b8ab34Slling 		return (B_FALSE);
336b1b8ab34Slling 
337b1b8ab34Slling 	return (zfs_prop_table[prop].pd_visible);
338b1b8ab34Slling }
339b1b8ab34Slling 
340d3c8f894Stimf /*
341d3c8f894Stimf  * A comparison function we can use to order indexes into the
342d3c8f894Stimf  * zfs_prop_table[]
343d3c8f894Stimf  */
344d3c8f894Stimf static int
345*91ebeef5Sahrens zfs_prop_compare(const void *arg1, const void *arg2)
346d3c8f894Stimf {
347*91ebeef5Sahrens 	const zfs_prop_t *p1 = arg1;
348*91ebeef5Sahrens 	const zfs_prop_t *p2 = arg2;
349*91ebeef5Sahrens 	boolean_t p1ro, p2ro;
350d3c8f894Stimf 
351*91ebeef5Sahrens 	p1ro = (zfs_prop_table[*p1].pd_attr == PROP_READONLY);
352*91ebeef5Sahrens 	p2ro = (zfs_prop_table[*p2].pd_attr == PROP_READONLY);
353d3c8f894Stimf 
354*91ebeef5Sahrens 	if (p1ro == p2ro) {
355*91ebeef5Sahrens 		return (strcmp(zfs_prop_table[*p1].pd_name,
356*91ebeef5Sahrens 		    zfs_prop_table[*p2].pd_name));
357*91ebeef5Sahrens 	}
358d3c8f894Stimf 
359*91ebeef5Sahrens 	return (p1ro ? -1 : 1);
360d3c8f894Stimf }
361d3c8f894Stimf 
362b1b8ab34Slling /*
363b1b8ab34Slling  * Iterate over all properties, calling back into the specified function
364b1b8ab34Slling  * for each property. We will continue to iterate until we either
365b1b8ab34Slling  * reach the end or the callback function something other than
366b1b8ab34Slling  * ZFS_PROP_CONT.
367b1b8ab34Slling  */
368b1b8ab34Slling zfs_prop_t
369b1b8ab34Slling zfs_prop_iter_common(zfs_prop_f func, void *cb, zfs_type_t type,
370d3c8f894Stimf     boolean_t show_all, boolean_t ordered)
371b1b8ab34Slling {
372b1b8ab34Slling 	int i;
373*91ebeef5Sahrens 	zfs_prop_t order[ZFS_NUM_PROPS];
374d3c8f894Stimf 
375*91ebeef5Sahrens 	for (int j = 0; j < ZFS_NUM_PROPS; j++)
376d3c8f894Stimf 		order[j] = j;
377d3c8f894Stimf 
378d3c8f894Stimf 
379d3c8f894Stimf 	if (ordered) {
380*91ebeef5Sahrens 		qsort((void *)order, ZFS_NUM_PROPS, sizeof (zfs_prop_t),
381d3c8f894Stimf 		    zfs_prop_compare);
382d3c8f894Stimf 	}
383b1b8ab34Slling 
384*91ebeef5Sahrens 	for (i = 0; i < ZFS_NUM_PROPS; i++) {
385d3c8f894Stimf 		if (zfs_prop_valid_for_type(order[i], type) &&
386d3c8f894Stimf 		    (zfs_prop_is_visible(order[i]) || show_all)) {
387d3c8f894Stimf 			if (func(order[i], cb) != ZFS_PROP_CONT)
388d3c8f894Stimf 				return (order[i]);
389b1b8ab34Slling 		}
390b1b8ab34Slling 	}
391b1b8ab34Slling 	return (ZFS_PROP_CONT);
392b1b8ab34Slling }
393b1b8ab34Slling 
394b1b8ab34Slling zfs_prop_t
395*91ebeef5Sahrens zfs_prop_iter(zfs_prop_f func, void *cb)
396b1b8ab34Slling {
397*91ebeef5Sahrens 	return (zfs_prop_iter_common(func, cb, ZFS_TYPE_ANY, B_FALSE, B_FALSE));
398d3c8f894Stimf }
399d3c8f894Stimf 
400d3c8f894Stimf zfs_prop_t
401*91ebeef5Sahrens zfs_prop_iter_ordered(zfs_prop_f func, void *cb)
402d3c8f894Stimf {
403*91ebeef5Sahrens 	return (zfs_prop_iter_common(func, cb, ZFS_TYPE_ANY, B_FALSE, B_TRUE));
404b1b8ab34Slling }
405b1b8ab34Slling 
406b1b8ab34Slling zpool_prop_t
407*91ebeef5Sahrens zpool_prop_iter(zpool_prop_f func, void *cb)
408b1b8ab34Slling {
409*91ebeef5Sahrens 	return (zfs_prop_iter_common(func, cb, ZFS_TYPE_POOL, B_FALSE,
410d3c8f894Stimf 	    B_FALSE));
411b1b8ab34Slling }
412b1b8ab34Slling 
413fa9e4066Sahrens zfs_proptype_t
414fa9e4066Sahrens zfs_prop_get_type(zfs_prop_t prop)
415fa9e4066Sahrens {
416fa9e4066Sahrens 	return (zfs_prop_table[prop].pd_proptype);
417fa9e4066Sahrens }
418fa9e4066Sahrens 
4193d7072f8Seschrock zfs_proptype_t
4203d7072f8Seschrock zpool_prop_get_type(zfs_prop_t prop)
4213d7072f8Seschrock {
4223d7072f8Seschrock 	return (zfs_prop_table[prop].pd_proptype);
4233d7072f8Seschrock }
4243d7072f8Seschrock 
425e9dbad6fSeschrock static boolean_t
426e9dbad6fSeschrock propname_match(const char *p, zfs_prop_t prop, size_t len)
4275c709891Seschrock {
4285c709891Seschrock 	const char *propname = zfs_prop_table[prop].pd_name;
4295c709891Seschrock #ifndef _KERNEL
4305c709891Seschrock 	const char *colname = zfs_prop_table[prop].pd_colname;
4315c709891Seschrock 	int c;
4325c709891Seschrock 
4333bb79becSeschrock 	if (colname == NULL)
434e9dbad6fSeschrock 		return (B_FALSE);
4353bb79becSeschrock #endif
4363bb79becSeschrock 
4375c709891Seschrock 	if (len == strlen(propname) &&
4385c709891Seschrock 	    strncmp(p, propname, len) == 0)
439e9dbad6fSeschrock 		return (B_TRUE);
4405c709891Seschrock 
4415c709891Seschrock #ifndef _KERNEL
4423bb79becSeschrock 	if (len != strlen(colname))
443e9dbad6fSeschrock 		return (B_FALSE);
4445c709891Seschrock 
4455c709891Seschrock 	for (c = 0; c < len; c++)
4465c709891Seschrock 		if (p[c] != tolower(colname[c]))
4475c709891Seschrock 			break;
4485c709891Seschrock 
4495c709891Seschrock 	return (colname[c] == '\0');
4505c709891Seschrock #else
451e9dbad6fSeschrock 	return (B_FALSE);
4525c709891Seschrock #endif
4535c709891Seschrock }
4545c709891Seschrock 
45566e2aaccSgw zfs_prop_t
45666e2aaccSgw zfs_name_to_prop_cb(zfs_prop_t prop, void *cb_data)
45766e2aaccSgw {
45866e2aaccSgw 	const char *propname = cb_data;
45966e2aaccSgw 
460*91ebeef5Sahrens 	if (propname_match(propname, prop, strlen(propname)))
46166e2aaccSgw 		return (prop);
46266e2aaccSgw 
46366e2aaccSgw 	return (ZFS_PROP_CONT);
46466e2aaccSgw }
4655c709891Seschrock 
466fa9e4066Sahrens /*
467b1b8ab34Slling  * Given a property name and its type, returns the corresponding property ID.
468fa9e4066Sahrens  */
469fa9e4066Sahrens zfs_prop_t
470b1b8ab34Slling zfs_name_to_prop_common(const char *propname, zfs_type_t type)
471fa9e4066Sahrens {
47266e2aaccSgw 	zfs_prop_t prop;
473fa9e4066Sahrens 
474b1b8ab34Slling 	prop = zfs_prop_iter_common(zfs_name_to_prop_cb, (void *)propname,
475d3c8f894Stimf 	    type, B_TRUE, B_FALSE);
47666e2aaccSgw 	return (prop == ZFS_PROP_CONT ? ZFS_PROP_INVAL : prop);
477fa9e4066Sahrens }
478fa9e4066Sahrens 
479b1b8ab34Slling /*
480b1b8ab34Slling  * Given a zfs dataset property name, returns the corresponding property ID.
481b1b8ab34Slling  */
482b1b8ab34Slling zfs_prop_t
483b1b8ab34Slling zfs_name_to_prop(const char *propname)
484b1b8ab34Slling {
485b1b8ab34Slling 	return (zfs_name_to_prop_common(propname, ZFS_TYPE_ANY));
486b1b8ab34Slling }
487b1b8ab34Slling 
488b1b8ab34Slling /*
489b1b8ab34Slling  * Given a pool property name, returns the corresponding property ID.
490b1b8ab34Slling  */
491b1b8ab34Slling zpool_prop_t
492b1b8ab34Slling zpool_name_to_prop(const char *propname)
493b1b8ab34Slling {
494b1b8ab34Slling 	return (zfs_name_to_prop_common(propname, ZFS_TYPE_POOL));
495b1b8ab34Slling }
496b1b8ab34Slling 
497*91ebeef5Sahrens boolean_t
498*91ebeef5Sahrens zfs_prop_delegatable(zfs_prop_t prop)
499ecd6cf80Smarks {
500*91ebeef5Sahrens 	prop_desc_t *pd = &zfs_prop_table[prop];
501*91ebeef5Sahrens 	return (pd->pd_attr != PROP_READONLY && pd->pd_types != ZFS_TYPE_POOL);
502ecd6cf80Smarks }
503ecd6cf80Smarks 
504e9dbad6fSeschrock /*
505e9dbad6fSeschrock  * For user property names, we allow all lowercase alphanumeric characters, plus
506e9dbad6fSeschrock  * a few useful punctuation characters.
507e9dbad6fSeschrock  */
508e9dbad6fSeschrock static int
509e9dbad6fSeschrock valid_char(char c)
510e9dbad6fSeschrock {
511e9dbad6fSeschrock 	return ((c >= 'a' && c <= 'z') ||
512e9dbad6fSeschrock 	    (c >= '0' && c <= '9') ||
513e9dbad6fSeschrock 	    c == '-' || c == '_' || c == '.' || c == ':');
514e9dbad6fSeschrock }
515e9dbad6fSeschrock 
516e9dbad6fSeschrock /*
517e9dbad6fSeschrock  * Returns true if this is a valid user-defined property (one with a ':').
518e9dbad6fSeschrock  */
519e9dbad6fSeschrock boolean_t
520e9dbad6fSeschrock zfs_prop_user(const char *name)
521e9dbad6fSeschrock {
522e9dbad6fSeschrock 	int i;
523e9dbad6fSeschrock 	char c;
524e9dbad6fSeschrock 	boolean_t foundsep = B_FALSE;
525e9dbad6fSeschrock 
526e9dbad6fSeschrock 	for (i = 0; i < strlen(name); i++) {
527e9dbad6fSeschrock 		c = name[i];
528e9dbad6fSeschrock 		if (!valid_char(c))
529e9dbad6fSeschrock 			return (B_FALSE);
530e9dbad6fSeschrock 		if (c == ':')
531e9dbad6fSeschrock 			foundsep = B_TRUE;
532e9dbad6fSeschrock 	}
533e9dbad6fSeschrock 
534e9dbad6fSeschrock 	if (!foundsep)
535e9dbad6fSeschrock 		return (B_FALSE);
536e9dbad6fSeschrock 
537e9dbad6fSeschrock 	return (B_TRUE);
538e9dbad6fSeschrock }
539e9dbad6fSeschrock 
540fa9e4066Sahrens /*
541fa9e4066Sahrens  * Return the default value for the given property.
542fa9e4066Sahrens  */
5437f7322feSeschrock const char *
5447f7322feSeschrock zfs_prop_default_string(zfs_prop_t prop)
545fa9e4066Sahrens {
5467f7322feSeschrock 	return (zfs_prop_table[prop].pd_strdefault);
547fa9e4066Sahrens }
548fa9e4066Sahrens 
5493d7072f8Seschrock const char *
5503d7072f8Seschrock zpool_prop_default_string(zpool_prop_t prop)
5513d7072f8Seschrock {
5523d7072f8Seschrock 	return (zfs_prop_table[prop].pd_strdefault);
5533d7072f8Seschrock }
5543d7072f8Seschrock 
555fa9e4066Sahrens uint64_t
556fa9e4066Sahrens zfs_prop_default_numeric(zfs_prop_t prop)
557fa9e4066Sahrens {
558fa9e4066Sahrens 	return (zfs_prop_table[prop].pd_numdefault);
559fa9e4066Sahrens }
560fa9e4066Sahrens 
5613d7072f8Seschrock uint64_t
5623d7072f8Seschrock zpool_prop_default_numeric(zpool_prop_t prop)
5633d7072f8Seschrock {
5643d7072f8Seschrock 	return (zfs_prop_table[prop].pd_numdefault);
5653d7072f8Seschrock }
5663d7072f8Seschrock 
567fa9e4066Sahrens /*
568fa9e4066Sahrens  * Returns TRUE if the property is readonly.
569fa9e4066Sahrens  */
570fa9e4066Sahrens int
571fa9e4066Sahrens zfs_prop_readonly(zfs_prop_t prop)
572fa9e4066Sahrens {
573*91ebeef5Sahrens 	return (zfs_prop_table[prop].pd_attr == PROP_READONLY);
574fa9e4066Sahrens }
575fa9e4066Sahrens 
576fa9e4066Sahrens /*
577b1b8ab34Slling  * Given a dataset property ID, returns the corresponding name.
5783d7072f8Seschrock  * Assuming the zfs dataset property ID is valid.
579fa9e4066Sahrens  */
580fa9e4066Sahrens const char *
581fa9e4066Sahrens zfs_prop_to_name(zfs_prop_t prop)
582fa9e4066Sahrens {
583fa9e4066Sahrens 	return (zfs_prop_table[prop].pd_name);
584fa9e4066Sahrens }
585fa9e4066Sahrens 
586b1b8ab34Slling /*
587b1b8ab34Slling  * Given a pool property ID, returns the corresponding name.
5883d7072f8Seschrock  * Assuming the pool property ID is valid.
589b1b8ab34Slling  */
590b1b8ab34Slling const char *
591b1b8ab34Slling zpool_prop_to_name(zpool_prop_t prop)
592b1b8ab34Slling {
593b1b8ab34Slling 	return (zfs_prop_table[prop].pd_name);
594b1b8ab34Slling }
595b1b8ab34Slling 
596fa9e4066Sahrens /*
597fa9e4066Sahrens  * Returns TRUE if the property is inheritable.
598fa9e4066Sahrens  */
599fa9e4066Sahrens int
600fa9e4066Sahrens zfs_prop_inheritable(zfs_prop_t prop)
601fa9e4066Sahrens {
602*91ebeef5Sahrens 	return (zfs_prop_table[prop].pd_attr == PROP_INHERIT);
603e9dbad6fSeschrock }
604e9dbad6fSeschrock 
605e9dbad6fSeschrock /*
606e9dbad6fSeschrock  * Tables of index types, plus functions to convert between the user view
607e9dbad6fSeschrock  * (strings) and internal representation (uint64_t).
608e9dbad6fSeschrock  */
609e9dbad6fSeschrock int
610e9dbad6fSeschrock zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
611e9dbad6fSeschrock {
612*91ebeef5Sahrens 	const zfs_index_t *table;
613e9dbad6fSeschrock 	int i;
614e9dbad6fSeschrock 
615*91ebeef5Sahrens 	if ((table = zfs_prop_table[prop].pd_table) == NULL)
616e9dbad6fSeschrock 		return (-1);
617e9dbad6fSeschrock 
618e9dbad6fSeschrock 	for (i = 0; table[i].name != NULL; i++) {
619e9dbad6fSeschrock 		if (strcmp(string, table[i].name) == 0) {
620e9dbad6fSeschrock 			*index = table[i].index;
621e9dbad6fSeschrock 			return (0);
622e9dbad6fSeschrock 		}
623e9dbad6fSeschrock 	}
624e9dbad6fSeschrock 
625e9dbad6fSeschrock 	return (-1);
626e9dbad6fSeschrock }
627e9dbad6fSeschrock 
628e9dbad6fSeschrock int
629e9dbad6fSeschrock zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string)
630e9dbad6fSeschrock {
631*91ebeef5Sahrens 	const zfs_index_t *table;
632e9dbad6fSeschrock 	int i;
633e9dbad6fSeschrock 
634*91ebeef5Sahrens 	if ((table = zfs_prop_table[prop].pd_table) == NULL)
635e9dbad6fSeschrock 		return (-1);
636e9dbad6fSeschrock 
637e9dbad6fSeschrock 	for (i = 0; table[i].name != NULL; i++) {
638e9dbad6fSeschrock 		if (table[i].index == index) {
639e9dbad6fSeschrock 			*string = table[i].name;
640e9dbad6fSeschrock 			return (0);
641e9dbad6fSeschrock 		}
642e9dbad6fSeschrock 	}
643e9dbad6fSeschrock 
644e9dbad6fSeschrock 	return (-1);
645e9dbad6fSeschrock }
646e9dbad6fSeschrock 
647acd76fe5Seschrock #ifndef _KERNEL
648acd76fe5Seschrock 
649fa9e4066Sahrens /*
650b1b8ab34Slling  * Returns a string describing the set of acceptable values for the given
651b1b8ab34Slling  * zfs property, or NULL if it cannot be set.
652fa9e4066Sahrens  */
653b1b8ab34Slling const char *
654b1b8ab34Slling zfs_prop_values(zfs_prop_t prop)
655fa9e4066Sahrens {
656b1b8ab34Slling 	if (zfs_prop_table[prop].pd_types == ZFS_TYPE_POOL)
657b1b8ab34Slling 		return (NULL);
658b1b8ab34Slling 
659b1b8ab34Slling 	return (zfs_prop_table[prop].pd_values);
660fa9e4066Sahrens }
661fa9e4066Sahrens 
662fa9e4066Sahrens /*
663fa9e4066Sahrens  * Returns a string describing the set of acceptable values for the given
664b1b8ab34Slling  * zpool property, or NULL if it cannot be set.
665fa9e4066Sahrens  */
666fa9e4066Sahrens const char *
667b1b8ab34Slling zpool_prop_values(zfs_prop_t prop)
668fa9e4066Sahrens {
669b1b8ab34Slling 	if (zfs_prop_table[prop].pd_types != ZFS_TYPE_POOL)
670b1b8ab34Slling 		return (NULL);
671b1b8ab34Slling 
672fa9e4066Sahrens 	return (zfs_prop_table[prop].pd_values);
673fa9e4066Sahrens }
674fa9e4066Sahrens 
675fa9e4066Sahrens /*
676fa9e4066Sahrens  * Returns TRUE if this property is a string type.  Note that index types
677fa9e4066Sahrens  * (compression, checksum) are treated as strings in userland, even though they
678fa9e4066Sahrens  * are stored numerically on disk.
679fa9e4066Sahrens  */
680fa9e4066Sahrens int
681fa9e4066Sahrens zfs_prop_is_string(zfs_prop_t prop)
682fa9e4066Sahrens {
683*91ebeef5Sahrens 	return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING ||
684*91ebeef5Sahrens 	    zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX);
685fa9e4066Sahrens }
686fa9e4066Sahrens 
687fa9e4066Sahrens /*
688fa9e4066Sahrens  * Returns the column header for the given property.  Used only in
689fa9e4066Sahrens  * 'zfs list -o', but centralized here with the other property information.
690fa9e4066Sahrens  */
691fa9e4066Sahrens const char *
692fa9e4066Sahrens zfs_prop_column_name(zfs_prop_t prop)
693fa9e4066Sahrens {
694fa9e4066Sahrens 	return (zfs_prop_table[prop].pd_colname);
695fa9e4066Sahrens }
696fa9e4066Sahrens 
697fa9e4066Sahrens /*
698e9dbad6fSeschrock  * Returns whether the given property should be displayed right-justified for
699e9dbad6fSeschrock  * 'zfs list'.
700fa9e4066Sahrens  */
701e9dbad6fSeschrock boolean_t
702e9dbad6fSeschrock zfs_prop_align_right(zfs_prop_t prop)
703fa9e4066Sahrens {
704e9dbad6fSeschrock 	return (zfs_prop_table[prop].pd_rightalign);
705fa9e4066Sahrens }
706fa9e4066Sahrens 
707fa9e4066Sahrens /*
708e9dbad6fSeschrock  * Determines the minimum width for the column, and indicates whether it's fixed
709e9dbad6fSeschrock  * or not.  Only string columns are non-fixed.
710fa9e4066Sahrens  */
711e9dbad6fSeschrock size_t
712e9dbad6fSeschrock zfs_prop_width(zfs_prop_t prop, boolean_t *fixed)
713fa9e4066Sahrens {
714e9dbad6fSeschrock 	prop_desc_t *pd = &zfs_prop_table[prop];
715*91ebeef5Sahrens 	const zfs_index_t *idx;
716e9dbad6fSeschrock 	size_t ret;
717fa9e4066Sahrens 	int i;
718fa9e4066Sahrens 
719e9dbad6fSeschrock 	*fixed = B_TRUE;
720fa9e4066Sahrens 
72107ba0419Seschrock 	/*
722e9dbad6fSeschrock 	 * Start with the width of the column name.
72307ba0419Seschrock 	 */
724e9dbad6fSeschrock 	ret = strlen(pd->pd_colname);
725fa9e4066Sahrens 
72607ba0419Seschrock 	/*
727e9dbad6fSeschrock 	 * For fixed-width values, make sure the width is large enough to hold
728e9dbad6fSeschrock 	 * any possible value.
72907ba0419Seschrock 	 */
730e9dbad6fSeschrock 	switch (pd->pd_proptype) {
731*91ebeef5Sahrens 	case PROP_TYPE_NUMBER:
73207ba0419Seschrock 		/*
733e9dbad6fSeschrock 		 * The maximum length of a human-readable number is 5 characters
734e9dbad6fSeschrock 		 * ("20.4M", for example).
73507ba0419Seschrock 		 */
736e9dbad6fSeschrock 		if (ret < 5)
737e9dbad6fSeschrock 			ret = 5;
73807ba0419Seschrock 		/*
739e9dbad6fSeschrock 		 * 'creation' is handled specially because it's a number
740e9dbad6fSeschrock 		 * internally, but displayed as a date string.
74107ba0419Seschrock 		 */
742e9dbad6fSeschrock 		if (prop == ZFS_PROP_CREATION)
743e9dbad6fSeschrock 			*fixed = B_FALSE;
744e9dbad6fSeschrock 		break;
745*91ebeef5Sahrens 	case PROP_TYPE_BOOLEAN:
74607ba0419Seschrock 		/*
747e9dbad6fSeschrock 		 * The maximum length of a boolean value is 3 characters, for
748e9dbad6fSeschrock 		 * "off".
74907ba0419Seschrock 		 */
750e9dbad6fSeschrock 		if (ret < 3)
751e9dbad6fSeschrock 			ret = 3;
752e9dbad6fSeschrock 		break;
753*91ebeef5Sahrens 	case PROP_TYPE_INDEX:
754*91ebeef5Sahrens 		idx = zfs_prop_table[prop].pd_table;
755e9dbad6fSeschrock 		for (i = 0; idx[i].name != NULL; i++) {
756e9dbad6fSeschrock 			if (strlen(idx[i].name) > ret)
757e9dbad6fSeschrock 				ret = strlen(idx[i].name);
75807ba0419Seschrock 		}
759e9dbad6fSeschrock 		break;
76007ba0419Seschrock 
761*91ebeef5Sahrens 	case PROP_TYPE_STRING:
762e9dbad6fSeschrock 		*fixed = B_FALSE;
763e9dbad6fSeschrock 		break;
76407ba0419Seschrock 	}
765fa9e4066Sahrens 
766e9dbad6fSeschrock 	return (ret);
767fa9e4066Sahrens }
768fa9e4066Sahrens 
769fa9e4066Sahrens #endif
770