Deleted Added
full compact
zfs_prop.c (177698) zfs_prop.c (185029)
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

--- 5 unchanged lines hidden (view full) ---

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/*
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

--- 5 unchanged lines hidden (view full) ---

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 2007 Sun Microsystems, Inc. All rights reserved.
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
23 * Use is subject to license terms.
24 */
25
26#pragma ident "%Z%%M% %I% %E% SMI"
27
28/*
29 * Master property table.
30 *
31 * This table keeps track of all the properties supported by ZFS, and their
32 * various attributes. Not all of these are needed by the kernel, and several
33 * are only used by a single libzfs client. But having them here centralizes
34 * all property information in one location.
35 *
36 * name The human-readable string representing this property
37 * proptype Basic type (string, boolean, number)
38 * default Default value for the property. Sadly, C only allows
39 * you to initialize the first member of a union, so we
40 * have two default members for each property.
41 * attr Attributes (readonly, inheritable) for the property
42 * types Valid dataset types to which this applies
43 * values String describing acceptable values for the property
44 * colname The column header for 'zfs list'
45 * colfmt The column formatting for 'zfs list'
46 *
47 * This table must match the order of property types in libzfs.h.
48 */
49
50#include <sys/zio.h>
51#include <sys/spa.h>
26#include <sys/zio.h>
27#include <sys/spa.h>
28#include <sys/u8_textprep.h>
52#include <sys/zfs_acl.h>
53#include <sys/zfs_ioctl.h>
29#include <sys/zfs_acl.h>
30#include <sys/zfs_ioctl.h>
31#include <sys/zfs_znode.h>
54
55#include "zfs_prop.h"
32
33#include "zfs_prop.h"
34#include "zfs_deleg.h"
56
57#if defined(_KERNEL)
58#include <sys/systm.h>
59#else
60#include <stdlib.h>
61#include <string.h>
62#include <ctype.h>
63#endif
64
35
36#if defined(_KERNEL)
37#include <sys/systm.h>
38#else
39#include <stdlib.h>
40#include <string.h>
41#include <ctype.h>
42#endif
43
65typedef enum {
66 prop_default,
67 prop_readonly,
68 prop_inherit
69} prop_attr_t;
44static zprop_desc_t zfs_prop_table[ZFS_NUM_PROPS];
70
45
71typedef struct {
72 const char *pd_name;
73 zfs_proptype_t pd_proptype;
74 uint64_t pd_numdefault;
75 const char *pd_strdefault;
76 prop_attr_t pd_attr;
77 int pd_types;
78 const char *pd_values;
79 const char *pd_colname;
80 boolean_t pd_rightalign;
81 boolean_t pd_visible;
82} prop_desc_t;
83
84static prop_desc_t zfs_prop_table[] = {
85 { "type", prop_type_string, 0, NULL, prop_readonly,
86 ZFS_TYPE_ANY, "filesystem | volume | snapshot", "TYPE", B_TRUE,
87 B_TRUE },
88 { "creation", prop_type_number, 0, NULL, prop_readonly,
89 ZFS_TYPE_ANY, "<date>", "CREATION", B_FALSE, B_TRUE },
90 { "used", prop_type_number, 0, NULL, prop_readonly,
91 ZFS_TYPE_ANY, "<size>", "USED", B_TRUE, B_TRUE },
92 { "available", prop_type_number, 0, NULL, prop_readonly,
93 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL", B_TRUE,
94 B_TRUE },
95 { "referenced", prop_type_number, 0, NULL, prop_readonly,
96 ZFS_TYPE_ANY,
97 "<size>", "REFER", B_TRUE, B_TRUE },
98 { "compressratio", prop_type_number, 0, NULL, prop_readonly,
99 ZFS_TYPE_ANY, "<1.00x or higher if compressed>", "RATIO", B_TRUE,
100 B_TRUE },
101 { "mounted", prop_type_boolean, 0, NULL, prop_readonly,
102 ZFS_TYPE_FILESYSTEM, "yes | no | -", "MOUNTED", B_TRUE, B_TRUE },
103 { "origin", prop_type_string, 0, NULL, prop_readonly,
104 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN",
105 B_FALSE, B_TRUE },
106 { "quota", prop_type_number, 0, NULL, prop_default,
107 ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA", B_TRUE, B_TRUE },
108 { "reservation", prop_type_number, 0, NULL, prop_default,
109 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
110 "<size> | none", "RESERV", B_TRUE, B_TRUE },
111 { "volsize", prop_type_number, 0, NULL, prop_default,
112 ZFS_TYPE_VOLUME, "<size>", "VOLSIZE", B_TRUE, B_TRUE },
113 { "volblocksize", prop_type_number, 8192, NULL, prop_readonly,
114 ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK", B_TRUE,
115 B_TRUE },
116 { "recordsize", prop_type_number, SPA_MAXBLOCKSIZE, NULL,
117 prop_inherit,
118 ZFS_TYPE_FILESYSTEM,
119 "512 to 128k, power of 2", "RECSIZE", B_TRUE, B_TRUE },
120 { "mountpoint", prop_type_string, 0, "/", prop_inherit,
121 ZFS_TYPE_FILESYSTEM,
122 "<path> | legacy | none", "MOUNTPOINT", B_FALSE, B_TRUE },
123 { "sharenfs", prop_type_string, 0, "off", prop_inherit,
124 ZFS_TYPE_FILESYSTEM,
125 "on | off | exports(5) options", "SHARENFS", B_FALSE, B_TRUE },
126 { "checksum", prop_type_index, ZIO_CHECKSUM_DEFAULT, "on",
127 prop_inherit, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
128 "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM", B_TRUE,
129 B_TRUE },
130 { "compression", prop_type_index, ZIO_COMPRESS_DEFAULT, "off",
131 prop_inherit, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
132 "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", B_TRUE, B_TRUE },
133 { "atime", prop_type_boolean, 1, NULL, prop_inherit,
134 ZFS_TYPE_FILESYSTEM,
135 "on | off", "ATIME", B_TRUE, B_TRUE },
136 { "devices", prop_type_boolean, 1, NULL, prop_inherit,
137 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
138 "on | off", "DEVICES", B_TRUE, B_TRUE },
139 { "exec", prop_type_boolean, 1, NULL, prop_inherit,
140 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
141 "on | off", "EXEC", B_TRUE, B_TRUE },
142 { "setuid", prop_type_boolean, 1, NULL, prop_inherit,
143 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
144 B_TRUE, B_TRUE },
145 { "readonly", prop_type_boolean, 0, NULL, prop_inherit,
146 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
147 "on | off", "RDONLY", B_TRUE, B_TRUE },
148 { "jailed", prop_type_boolean, 0, NULL, prop_inherit,
149 ZFS_TYPE_FILESYSTEM,
150 "on | off", "JAILED", B_TRUE, B_TRUE },
151 { "snapdir", prop_type_index, ZFS_SNAPDIR_HIDDEN, "hidden",
152 prop_inherit,
153 ZFS_TYPE_FILESYSTEM,
154 "hidden | visible", "SNAPDIR", B_TRUE, B_TRUE },
155 { "aclmode", prop_type_index, ZFS_ACL_GROUPMASK, "groupmask",
156 prop_inherit, ZFS_TYPE_FILESYSTEM,
157 "discard | groupmask | passthrough", "ACLMODE", B_TRUE, B_TRUE },
158 { "aclinherit", prop_type_index, ZFS_ACL_SECURE, "secure",
159 prop_inherit, ZFS_TYPE_FILESYSTEM,
160 "discard | noallow | secure | passthrough", "ACLINHERIT", B_TRUE,
161 B_TRUE },
162 { "createtxg", prop_type_number, 0, NULL, prop_readonly,
163 ZFS_TYPE_ANY, NULL, NULL, B_FALSE, B_FALSE },
164 { "name", prop_type_string, 0, NULL, prop_readonly,
165 ZFS_TYPE_ANY, NULL, "NAME", B_FALSE, B_FALSE },
166 { "canmount", prop_type_boolean, 1, NULL, prop_default,
167 ZFS_TYPE_FILESYSTEM,
168 "on | off", "CANMOUNT", B_TRUE, B_TRUE },
169 { "shareiscsi", prop_type_string, 0, "off", prop_inherit,
170 ZFS_TYPE_ANY,
171 "on | off | type=<type>", "SHAREISCSI", B_FALSE, B_TRUE },
172 { "iscsioptions", prop_type_string, 0, NULL, prop_inherit,
173 ZFS_TYPE_VOLUME, NULL, "ISCSIOPTIONS", B_FALSE, B_FALSE },
174 { "xattr", prop_type_boolean, 1, NULL, prop_inherit,
175 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
176 "on | off", "XATTR", B_TRUE, B_TRUE },
177 { "numclones", prop_type_number, 0, NULL, prop_readonly,
178 ZFS_TYPE_SNAPSHOT, NULL, NULL, B_FALSE, B_FALSE },
179 { "copies", prop_type_index, 1, "1", prop_inherit,
180 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
181 "1 | 2 | 3", "COPIES", B_TRUE, B_TRUE },
182 { "bootfs", prop_type_string, 0, NULL, prop_default,
183 ZFS_TYPE_POOL, "<filesystem>", "BOOTFS", B_FALSE, B_TRUE },
184};
185
186#define ZFS_PROP_COUNT ((sizeof (zfs_prop_table))/(sizeof (prop_desc_t)))
187
188/*
189 * Returns TRUE if the property applies to the given dataset types.
190 */
191int
192zfs_prop_valid_for_type(zfs_prop_t prop, int types)
46zprop_desc_t *
47zfs_prop_get_table(void)
193{
48{
194 return ((zfs_prop_table[prop].pd_types & types) != 0);
49 return (zfs_prop_table);
195}
196
50}
51
197/*
198 * Determine if the specified property is visible or not.
199 */
200boolean_t
201zfs_prop_is_visible(zfs_prop_t prop)
52void
53zfs_prop_init(void)
202{
54{
203 if (prop < 0)
204 return (B_FALSE);
55 static zprop_index_t checksum_table[] = {
56 { "on", ZIO_CHECKSUM_ON },
57 { "off", ZIO_CHECKSUM_OFF },
58 { "fletcher2", ZIO_CHECKSUM_FLETCHER_2 },
59 { "fletcher4", ZIO_CHECKSUM_FLETCHER_4 },
60 { "sha256", ZIO_CHECKSUM_SHA256 },
61 { NULL }
62 };
205
63
206 return (zfs_prop_table[prop].pd_visible);
207}
64 static zprop_index_t compress_table[] = {
65 { "on", ZIO_COMPRESS_ON },
66 { "off", ZIO_COMPRESS_OFF },
67 { "lzjb", ZIO_COMPRESS_LZJB },
68 { "gzip", ZIO_COMPRESS_GZIP_6 }, /* gzip default */
69 { "gzip-1", ZIO_COMPRESS_GZIP_1 },
70 { "gzip-2", ZIO_COMPRESS_GZIP_2 },
71 { "gzip-3", ZIO_COMPRESS_GZIP_3 },
72 { "gzip-4", ZIO_COMPRESS_GZIP_4 },
73 { "gzip-5", ZIO_COMPRESS_GZIP_5 },
74 { "gzip-6", ZIO_COMPRESS_GZIP_6 },
75 { "gzip-7", ZIO_COMPRESS_GZIP_7 },
76 { "gzip-8", ZIO_COMPRESS_GZIP_8 },
77 { "gzip-9", ZIO_COMPRESS_GZIP_9 },
78 { NULL }
79 };
208
80
209/*
210 * Iterate over all properties, calling back into the specified function
211 * for each property. We will continue to iterate until we either
212 * reach the end or the callback function something other than
213 * ZFS_PROP_CONT.
214 */
215zfs_prop_t
216zfs_prop_iter_common(zfs_prop_f func, void *cb, zfs_type_t type,
217 boolean_t show_all)
218{
219 int i;
81 static zprop_index_t snapdir_table[] = {
82 { "hidden", ZFS_SNAPDIR_HIDDEN },
83 { "visible", ZFS_SNAPDIR_VISIBLE },
84 { NULL }
85 };
220
86
221 for (i = 0; i < ZFS_PROP_COUNT; i++) {
222 if (zfs_prop_valid_for_type(i, type) &&
223 (zfs_prop_is_visible(i) || show_all)) {
224 if (func(i, cb) != ZFS_PROP_CONT)
225 return (i);
226 }
227 }
228 return (ZFS_PROP_CONT);
229}
87 static zprop_index_t acl_mode_table[] = {
88 { "discard", ZFS_ACL_DISCARD },
89 { "groupmask", ZFS_ACL_GROUPMASK },
90 { "passthrough", ZFS_ACL_PASSTHROUGH },
91 { NULL }
92 };
230
93
231zfs_prop_t
232zfs_prop_iter(zfs_prop_f func, void *cb, boolean_t show_all)
233{
234 return (zfs_prop_iter_common(func, cb, ZFS_TYPE_ANY, show_all));
235}
94 static zprop_index_t acl_inherit_table[] = {
95 { "discard", ZFS_ACL_DISCARD },
96 { "noallow", ZFS_ACL_NOALLOW },
97 { "restricted", ZFS_ACL_RESTRICTED },
98 { "passthrough", ZFS_ACL_PASSTHROUGH },
99 { "secure", ZFS_ACL_RESTRICTED }, /* bkwrd compatability */
100 { NULL }
101 };
236
102
237zpool_prop_t
238zpool_prop_iter(zpool_prop_f func, void *cb, boolean_t show_all)
239{
240 return (zfs_prop_iter_common(func, cb, ZFS_TYPE_POOL, show_all));
241}
103 static zprop_index_t case_table[] = {
104 { "sensitive", ZFS_CASE_SENSITIVE },
105 { "insensitive", ZFS_CASE_INSENSITIVE },
106 { "mixed", ZFS_CASE_MIXED },
107 { NULL }
108 };
242
109
243zfs_proptype_t
244zfs_prop_get_type(zfs_prop_t prop)
245{
246 return (zfs_prop_table[prop].pd_proptype);
247}
110 static zprop_index_t copies_table[] = {
111 { "1", 1 },
112 { "2", 2 },
113 { "3", 3 },
114 { NULL }
115 };
248
116
249static boolean_t
250propname_match(const char *p, zfs_prop_t prop, size_t len)
251{
252 const char *propname = zfs_prop_table[prop].pd_name;
253#ifndef _KERNEL
254 const char *colname = zfs_prop_table[prop].pd_colname;
255 int c;
256#endif
117 /*
118 * Use the unique flags we have to send to u8_strcmp() and/or
119 * u8_textprep() to represent the various normalization property
120 * values.
121 */
122 static zprop_index_t normalize_table[] = {
123 { "none", 0 },
124 { "formD", U8_TEXTPREP_NFD },
125 { "formKC", U8_TEXTPREP_NFKC },
126 { "formC", U8_TEXTPREP_NFC },
127 { "formKD", U8_TEXTPREP_NFKD },
128 { NULL }
129 };
257
130
258#ifndef _KERNEL
259 if (colname == NULL)
260 return (B_FALSE);
261#endif
131 static zprop_index_t version_table[] = {
132 { "1", 1 },
133 { "2", 2 },
134 { "3", 3 },
135 { "current", ZPL_VERSION },
136 { NULL }
137 };
262
138
263 if (len == strlen(propname) &&
264 strncmp(p, propname, len) == 0)
265 return (B_TRUE);
139 static zprop_index_t boolean_table[] = {
140 { "off", 0 },
141 { "on", 1 },
142 { NULL }
143 };
266
144
267#ifndef _KERNEL
268 if (len != strlen(colname))
269 return (B_FALSE);
145 static zprop_index_t canmount_table[] = {
146 { "off", ZFS_CANMOUNT_OFF },
147 { "on", ZFS_CANMOUNT_ON },
148 { "noauto", ZFS_CANMOUNT_NOAUTO },
149 { NULL }
150 };
270
151
271 for (c = 0; c < len; c++)
272 if (p[c] != tolower(colname[c]))
273 break;
152 static zprop_index_t cache_table[] = {
153 { "none", ZFS_CACHE_NONE },
154 { "metadata", ZFS_CACHE_METADATA },
155 { "all", ZFS_CACHE_ALL },
156 { NULL }
157 };
274
158
275 return (colname[c] == '\0');
276#else
277 return (B_FALSE);
278#endif
279}
159 /* inherit index properties */
160 register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT,
161 PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
162 "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM",
163 checksum_table);
164 register_index(ZFS_PROP_COMPRESSION, "compression",
165 ZIO_COMPRESS_DEFAULT, PROP_INHERIT,
166 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
167 "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", compress_table);
168 register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
169 PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
170 "hidden | visible", "SNAPDIR", snapdir_table);
171 register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK,
172 PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
173 "discard | groupmask | passthrough", "ACLMODE", acl_mode_table);
174 register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_RESTRICTED,
175 PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
176 "discard | noallow | restricted | passthrough",
177 "ACLINHERIT", acl_inherit_table);
178 register_index(ZFS_PROP_COPIES, "copies", 1,
179 PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
180 "1 | 2 | 3", "COPIES", copies_table);
181 register_index(ZFS_PROP_PRIMARYCACHE, "primarycache",
182 ZFS_CACHE_ALL, PROP_INHERIT,
183 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
184 "all | none | metadata", "PRIMARYCACHE", cache_table);
185 register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache",
186 ZFS_CACHE_ALL, PROP_INHERIT,
187 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
188 "all | none | metadata", "SECONDARYCACHE", cache_table);
280
189
281zfs_prop_t
282zfs_name_to_prop_cb(zfs_prop_t prop, void *cb_data)
283{
284 const char *propname = cb_data;
190 /* inherit index (boolean) properties */
191 register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
192 ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table);
193 register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT,
194 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES",
195 boolean_table);
196 register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT,
197 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC",
198 boolean_table);
199 register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT,
200 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
201 boolean_table);
202 register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
203 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY",
204 boolean_table);
205 register_index(ZFS_PROP_ZONED, "jailed", 0, PROP_INHERIT,
206 ZFS_TYPE_FILESYSTEM, "on | off", "JAILED", boolean_table);
207 register_index(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT,
208 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR",
209 boolean_table);
210 register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT,
211 ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN",
212 boolean_table);
213 register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT,
214 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "NBMAND",
215 boolean_table);
285
216
286 if (propname_match(propname, prop, strlen(propname)))
287 return (prop);
217 /* default index properties */
218 register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT,
219 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
220 "1 | 2 | 3 | current", "VERSION", version_table);
221 register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON,
222 PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto",
223 "CANMOUNT", canmount_table);
288
224
289 return (ZFS_PROP_CONT);
225 /* readonly index (boolean) properties */
226 register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
227 ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table);
228
229 /* set once index properties */
230 register_index(ZFS_PROP_NORMALIZE, "normalization", 0,
231 PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
232 "none | formC | formD | formKC | formKD", "NORMALIZATION",
233 normalize_table);
234 register_index(ZFS_PROP_CASE, "casesensitivity", ZFS_CASE_SENSITIVE,
235 PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
236 "sensitive | insensitive | mixed", "CASE", case_table);
237
238 /* set once index (boolean) properties */
239 register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME,
240 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
241 "on | off", "UTF8ONLY", boolean_table);
242
243 /* string properties */
244 register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
245 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
246 register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", PROP_INHERIT,
247 ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", "MOUNTPOINT");
248 register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", PROP_INHERIT,
249 ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", "SHARENFS");
250 register_string(ZFS_PROP_SHAREISCSI, "shareiscsi", "off", PROP_INHERIT,
251 ZFS_TYPE_DATASET, "on | off | type=<type>", "SHAREISCSI");
252 register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY,
253 ZFS_TYPE_DATASET, "filesystem | volume | snapshot", "TYPE");
254 register_string(ZFS_PROP_SHARESMB, "sharesmb", "off", PROP_INHERIT,
255 ZFS_TYPE_FILESYSTEM, "on | off | sharemgr(1M) options", "SHARESMB");
256
257 /* readonly number properties */
258 register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
259 ZFS_TYPE_DATASET, "<size>", "USED");
260 register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY,
261 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL");
262 register_number(ZFS_PROP_REFERENCED, "referenced", 0, PROP_READONLY,
263 ZFS_TYPE_DATASET, "<size>", "REFER");
264 register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
265 PROP_READONLY, ZFS_TYPE_DATASET,
266 "<1.00x or higher if compressed>", "RATIO");
267 register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192,
268 PROP_ONETIME,
269 ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK");
270 register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0, PROP_READONLY,
271 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDSNAP");
272 register_number(ZFS_PROP_USEDDS, "usedbydataset", 0, PROP_READONLY,
273 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDDS");
274 register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0, PROP_READONLY,
275 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDCHILD");
276 register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0,
277 PROP_READONLY,
278 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV");
279
280 /* default number properties */
281 register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
282 ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
283 register_number(ZFS_PROP_RESERVATION, "reservation", 0, PROP_DEFAULT,
284 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "RESERV");
285 register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
286 ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
287 register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT,
288 ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA");
289 register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0,
290 PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
291 "<size> | none", "REFRESERV");
292
293 /* inherit number properties */
294 register_number(ZFS_PROP_RECORDSIZE, "recordsize", SPA_MAXBLOCKSIZE,
295 PROP_INHERIT,
296 ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE");
297
298 /* hidden properties */
299 register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER,
300 PROP_READONLY, ZFS_TYPE_DATASET, NULL);
301 register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
302 PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL);
303 register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
304 PROP_READONLY, ZFS_TYPE_DATASET, "NAME");
305 register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING,
306 PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS");
307 register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER, PROP_READONLY,
308 ZFS_TYPE_DATASET, "GUID");
309
310 /* oddball properties */
311 register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL,
312 PROP_READONLY, ZFS_TYPE_DATASET,
313 "<date>", "CREATION", B_FALSE, B_TRUE, NULL);
290}
291
314}
315
292/*
293 * Given a property name and its type, returns the corresponding property ID.
294 */
295zfs_prop_t
296zfs_name_to_prop_common(const char *propname, zfs_type_t type)
316boolean_t
317zfs_prop_delegatable(zfs_prop_t prop)
297{
318{
298 zfs_prop_t prop;
299
300 prop = zfs_prop_iter_common(zfs_name_to_prop_cb, (void *)propname,
301 type, B_TRUE);
302 return (prop == ZFS_PROP_CONT ? ZFS_PROP_INVAL : prop);
319 zprop_desc_t *pd = &zfs_prop_table[prop];
320 return (pd->pd_attr != PROP_READONLY);
303}
304
305/*
306 * Given a zfs dataset property name, returns the corresponding property ID.
307 */
308zfs_prop_t
309zfs_name_to_prop(const char *propname)
310{
321}
322
323/*
324 * Given a zfs dataset property name, returns the corresponding property ID.
325 */
326zfs_prop_t
327zfs_name_to_prop(const char *propname)
328{
311 return (zfs_name_to_prop_common(propname, ZFS_TYPE_ANY));
329 return (zprop_name_to_prop(propname, ZFS_TYPE_DATASET));
312}
313
330}
331
314/*
315 * Given a pool property name, returns the corresponding property ID.
316 */
317zpool_prop_t
318zpool_name_to_prop(const char *propname)
319{
320 return (zfs_name_to_prop_common(propname, ZFS_TYPE_POOL));
321}
322
323/*
324 * For user property names, we allow all lowercase alphanumeric characters, plus
325 * a few useful punctuation characters.
326 */
327static int
328valid_char(char c)
329{

--- 22 unchanged lines hidden (view full) ---

352
353 if (!foundsep)
354 return (B_FALSE);
355
356 return (B_TRUE);
357}
358
359/*
332
333/*
334 * For user property names, we allow all lowercase alphanumeric characters, plus
335 * a few useful punctuation characters.
336 */
337static int
338valid_char(char c)
339{

--- 22 unchanged lines hidden (view full) ---

362
363 if (!foundsep)
364 return (B_FALSE);
365
366 return (B_TRUE);
367}
368
369/*
360 * Return the default value for the given property.
370 * Tables of index types, plus functions to convert between the user view
371 * (strings) and internal representation (uint64_t).
361 */
372 */
362const char *
363zfs_prop_default_string(zfs_prop_t prop)
373int
374zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
364{
375{
365 return (zfs_prop_table[prop].pd_strdefault);
376 return (zprop_string_to_index(prop, string, index, ZFS_TYPE_DATASET));
366}
367
377}
378
368uint64_t
369zfs_prop_default_numeric(zfs_prop_t prop)
379int
380zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string)
370{
381{
371 return (zfs_prop_table[prop].pd_numdefault);
382 return (zprop_index_to_string(prop, index, string, ZFS_TYPE_DATASET));
372}
373
374/*
383}
384
385/*
375 * Returns TRUE if the property is readonly.
386 * Returns TRUE if the property applies to any of the given dataset types.
376 */
387 */
377int
378zfs_prop_readonly(zfs_prop_t prop)
388boolean_t
389zfs_prop_valid_for_type(int prop, zfs_type_t types)
379{
390{
380 return (zfs_prop_table[prop].pd_attr == prop_readonly);
391 return (zprop_valid_for_type(prop, types));
381}
382
392}
393
383/*
384 * Given a dataset property ID, returns the corresponding name.
385 * Assuming the zfs dataset propety ID is valid.
386 */
387const char *
388zfs_prop_to_name(zfs_prop_t prop)
394zprop_type_t
395zfs_prop_get_type(zfs_prop_t prop)
389{
396{
390 return (zfs_prop_table[prop].pd_name);
397 return (zfs_prop_table[prop].pd_proptype);
391}
392
393/*
398}
399
400/*
394 * Given a pool property ID, returns the corresponding name.
395 * Assuming the pool propety ID is valid.
401 * Returns TRUE if the property is readonly.
396 */
402 */
397const char *
398zpool_prop_to_name(zpool_prop_t prop)
403boolean_t
404zfs_prop_readonly(zfs_prop_t prop)
399{
405{
400 return (zfs_prop_table[prop].pd_name);
406 return (zfs_prop_table[prop].pd_attr == PROP_READONLY ||
407 zfs_prop_table[prop].pd_attr == PROP_ONETIME);
401}
402
403/*
408}
409
410/*
404 * Returns TRUE if the property is inheritable.
411 * Returns TRUE if the property is only allowed to be set once.
405 */
412 */
406int
407zfs_prop_inheritable(zfs_prop_t prop)
413boolean_t
414zfs_prop_setonce(zfs_prop_t prop)
408{
415{
409 return (zfs_prop_table[prop].pd_attr == prop_inherit);
416 return (zfs_prop_table[prop].pd_attr == PROP_ONETIME);
410}
411
417}
418
412typedef struct zfs_index {
413 const char *name;
414 uint64_t index;
415} zfs_index_t;
419const char *
420zfs_prop_default_string(zfs_prop_t prop)
421{
422 return (zfs_prop_table[prop].pd_strdefault);
423}
416
424
417static zfs_index_t checksum_table[] = {
418 { "on", ZIO_CHECKSUM_ON },
419 { "off", ZIO_CHECKSUM_OFF },
420 { "fletcher2", ZIO_CHECKSUM_FLETCHER_2 },
421 { "fletcher4", ZIO_CHECKSUM_FLETCHER_4 },
422 { "sha256", ZIO_CHECKSUM_SHA256 },
423 { NULL }
424};
425
426static zfs_index_t compress_table[] = {
427 { "on", ZIO_COMPRESS_ON },
428 { "off", ZIO_COMPRESS_OFF },
429 { "lzjb", ZIO_COMPRESS_LZJB },
430 { "gzip", ZIO_COMPRESS_GZIP_6 }, /* the default gzip level */
431 { "gzip-1", ZIO_COMPRESS_GZIP_1 },
432 { "gzip-2", ZIO_COMPRESS_GZIP_2 },
433 { "gzip-3", ZIO_COMPRESS_GZIP_3 },
434 { "gzip-4", ZIO_COMPRESS_GZIP_4 },
435 { "gzip-5", ZIO_COMPRESS_GZIP_5 },
436 { "gzip-6", ZIO_COMPRESS_GZIP_6 },
437 { "gzip-7", ZIO_COMPRESS_GZIP_7 },
438 { "gzip-8", ZIO_COMPRESS_GZIP_8 },
439 { "gzip-9", ZIO_COMPRESS_GZIP_9 },
440 { NULL }
441};
442
443static zfs_index_t snapdir_table[] = {
444 { "hidden", ZFS_SNAPDIR_HIDDEN },
445 { "visible", ZFS_SNAPDIR_VISIBLE },
446 { NULL }
447};
448
449static zfs_index_t acl_mode_table[] = {
450 { "discard", ZFS_ACL_DISCARD },
451 { "groupmask", ZFS_ACL_GROUPMASK },
452 { "passthrough", ZFS_ACL_PASSTHROUGH },
453 { NULL }
454};
455
456static zfs_index_t acl_inherit_table[] = {
457 { "discard", ZFS_ACL_DISCARD },
458 { "noallow", ZFS_ACL_NOALLOW },
459 { "secure", ZFS_ACL_SECURE },
460 { "passthrough", ZFS_ACL_PASSTHROUGH },
461 { NULL }
462};
463
464static zfs_index_t copies_table[] = {
465 { "1", 1 },
466 { "2", 2 },
467 { "3", 3 },
468 { NULL }
469};
470
471static zfs_index_t *
472zfs_prop_index_table(zfs_prop_t prop)
425uint64_t
426zfs_prop_default_numeric(zfs_prop_t prop)
473{
427{
474 switch (prop) {
475 case ZFS_PROP_CHECKSUM:
476 return (checksum_table);
477 case ZFS_PROP_COMPRESSION:
478 return (compress_table);
479 case ZFS_PROP_SNAPDIR:
480 return (snapdir_table);
481 case ZFS_PROP_ACLMODE:
482 return (acl_mode_table);
483 case ZFS_PROP_ACLINHERIT:
484 return (acl_inherit_table);
485 case ZFS_PROP_COPIES:
486 return (copies_table);
487 default:
488 return (NULL);
489 }
428 return (zfs_prop_table[prop].pd_numdefault);
490}
491
429}
430
492
493/*
431/*
494 * Tables of index types, plus functions to convert between the user view
495 * (strings) and internal representation (uint64_t).
432 * Given a dataset property ID, returns the corresponding name.
433 * Assuming the zfs dataset property ID is valid.
496 */
434 */
497int
498zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
435const char *
436zfs_prop_to_name(zfs_prop_t prop)
499{
437{
500 zfs_index_t *table;
501 int i;
502
503 if ((table = zfs_prop_index_table(prop)) == NULL)
504 return (-1);
505
506 for (i = 0; table[i].name != NULL; i++) {
507 if (strcmp(string, table[i].name) == 0) {
508 *index = table[i].index;
509 return (0);
510 }
511 }
512
513 return (-1);
438 return (zfs_prop_table[prop].pd_name);
514}
515
439}
440
516int
517zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string)
441/*
442 * Returns TRUE if the property is inheritable.
443 */
444boolean_t
445zfs_prop_inheritable(zfs_prop_t prop)
518{
446{
519 zfs_index_t *table;
520 int i;
521
522 if ((table = zfs_prop_index_table(prop)) == NULL)
523 return (-1);
524
525 for (i = 0; table[i].name != NULL; i++) {
526 if (table[i].index == index) {
527 *string = table[i].name;
528 return (0);
529 }
530 }
531
532 return (-1);
447 return (zfs_prop_table[prop].pd_attr == PROP_INHERIT ||
448 zfs_prop_table[prop].pd_attr == PROP_ONETIME);
533}
534
535#ifndef _KERNEL
536
537/*
538 * Returns a string describing the set of acceptable values for the given
539 * zfs property, or NULL if it cannot be set.
540 */
541const char *
542zfs_prop_values(zfs_prop_t prop)
543{
449}
450
451#ifndef _KERNEL
452
453/*
454 * Returns a string describing the set of acceptable values for the given
455 * zfs property, or NULL if it cannot be set.
456 */
457const char *
458zfs_prop_values(zfs_prop_t prop)
459{
544 if (zfs_prop_table[prop].pd_types == ZFS_TYPE_POOL)
545 return (NULL);
546
547 return (zfs_prop_table[prop].pd_values);
548}
549
550/*
460 return (zfs_prop_table[prop].pd_values);
461}
462
463/*
551 * Returns a string describing the set of acceptable values for the given
552 * zpool property, or NULL if it cannot be set.
553 */
554const char *
555zpool_prop_values(zfs_prop_t prop)
556{
557 if (zfs_prop_table[prop].pd_types != ZFS_TYPE_POOL)
558 return (NULL);
559
560 return (zfs_prop_table[prop].pd_values);
561}
562
563/*
564 * Returns TRUE if this property is a string type. Note that index types
565 * (compression, checksum) are treated as strings in userland, even though they
566 * are stored numerically on disk.
567 */
568int
569zfs_prop_is_string(zfs_prop_t prop)
570{
464 * Returns TRUE if this property is a string type. Note that index types
465 * (compression, checksum) are treated as strings in userland, even though they
466 * are stored numerically on disk.
467 */
468int
469zfs_prop_is_string(zfs_prop_t prop)
470{
571 return (zfs_prop_table[prop].pd_proptype == prop_type_string ||
572 zfs_prop_table[prop].pd_proptype == prop_type_index);
471 return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING ||
472 zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX);
573}
574
575/*
576 * Returns the column header for the given property. Used only in
577 * 'zfs list -o', but centralized here with the other property information.
578 */
579const char *
580zfs_prop_column_name(zfs_prop_t prop)

--- 6 unchanged lines hidden (view full) ---

587 * 'zfs list'.
588 */
589boolean_t
590zfs_prop_align_right(zfs_prop_t prop)
591{
592 return (zfs_prop_table[prop].pd_rightalign);
593}
594
473}
474
475/*
476 * Returns the column header for the given property. Used only in
477 * 'zfs list -o', but centralized here with the other property information.
478 */
479const char *
480zfs_prop_column_name(zfs_prop_t prop)

--- 6 unchanged lines hidden (view full) ---

487 * 'zfs list'.
488 */
489boolean_t
490zfs_prop_align_right(zfs_prop_t prop)
491{
492 return (zfs_prop_table[prop].pd_rightalign);
493}
494
595/*
596 * Determines the minimum width for the column, and indicates whether it's fixed
597 * or not. Only string columns are non-fixed.
598 */
599size_t
600zfs_prop_width(zfs_prop_t prop, boolean_t *fixed)
601{
602 prop_desc_t *pd = &zfs_prop_table[prop];
603 zfs_index_t *idx;
604 size_t ret;
605 int i;
606
607 *fixed = B_TRUE;
608
609 /*
610 * Start with the width of the column name.
611 */
612 ret = strlen(pd->pd_colname);
613
614 /*
615 * For fixed-width values, make sure the width is large enough to hold
616 * any possible value.
617 */
618 switch (pd->pd_proptype) {
619 case prop_type_number:
620 /*
621 * The maximum length of a human-readable number is 5 characters
622 * ("20.4M", for example).
623 */
624 if (ret < 5)
625 ret = 5;
626 /*
627 * 'creation' is handled specially because it's a number
628 * internally, but displayed as a date string.
629 */
630 if (prop == ZFS_PROP_CREATION)
631 *fixed = B_FALSE;
632 break;
633 case prop_type_boolean:
634 /*
635 * The maximum length of a boolean value is 3 characters, for
636 * "off".
637 */
638 if (ret < 3)
639 ret = 3;
640 break;
641 case prop_type_index:
642 idx = zfs_prop_index_table(prop);
643 for (i = 0; idx[i].name != NULL; i++) {
644 if (strlen(idx[i].name) > ret)
645 ret = strlen(idx[i].name);
646 }
647 break;
648
649 case prop_type_string:
650 *fixed = B_FALSE;
651 break;
652 }
653
654 return (ret);
655}
656
657#endif
495#endif