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