zfs_prop.c revision 209962
190075Sobrien/* 290075Sobrien * CDDL HEADER START 390075Sobrien * 490075Sobrien * The contents of this file are subject to the terms of the 5132718Skan * Common Development and Distribution License (the "License"). 690075Sobrien * You may not use this file except in compliance with the License. 7132718Skan * 890075Sobrien * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 990075Sobrien * or http://www.opensolaris.org/os/licensing. 1090075Sobrien * See the License for the specific language governing permissions 1190075Sobrien * and limitations under the License. 12132718Skan * 1390075Sobrien * When distributing Covered Code, include this CDDL HEADER in each 1490075Sobrien * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1590075Sobrien * If applicable, add the following below this CDDL HEADER, with the 1690075Sobrien * fields enclosed by brackets "[]" replaced with your own identifying 1790075Sobrien * information: Portions Copyright [yyyy] [name of copyright owner] 18132718Skan * 19169689Skan * CDDL HEADER END 20169689Skan */ 2190075Sobrien/* 22117395Skan * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23117395Skan * Use is subject to license terms. 24117395Skan */ 25117395Skan 26117395Skan#include <sys/zio.h> 27117395Skan#include <sys/spa.h> 28117395Skan#include <sys/u8_textprep.h> 2990075Sobrien#include <sys/zfs_acl.h> 30117395Skan#include <sys/zfs_ioctl.h> 31117395Skan#include <sys/zfs_znode.h> 3290075Sobrien 3390075Sobrien#include "zfs_prop.h" 3490075Sobrien#include "zfs_deleg.h" 3590075Sobrien 3690075Sobrien#if defined(_KERNEL) 3790075Sobrien#include <sys/systm.h> 3890075Sobrien#else 3990075Sobrien#include <stdlib.h> 4090075Sobrien#include <string.h> 4190075Sobrien#include <ctype.h> 42132718Skan#endif 4390075Sobrien 44132718Skanstatic zprop_desc_t zfs_prop_table[ZFS_NUM_PROPS]; 4590075Sobrien 46132718Skan/* Note this is indexed by zfs_userquota_prop_t, keep the order the same */ 4790075Sobrienconst char *zfs_userquota_prop_prefixes[] = { 4890075Sobrien "userused@", 4990075Sobrien "userquota@", 5090075Sobrien "groupused@", 5190075Sobrien "groupquota@" 5290075Sobrien}; 5390075Sobrien 5490075Sobrienzprop_desc_t * 5590075Sobrienzfs_prop_get_table(void) 5690075Sobrien{ 5790075Sobrien return (zfs_prop_table); 5890075Sobrien} 5990075Sobrien 6090075Sobrienvoid 6190075Sobrienzfs_prop_init(void) 6290075Sobrien{ 63117395Skan static zprop_index_t checksum_table[] = { 64117395Skan { "on", ZIO_CHECKSUM_ON }, 6590075Sobrien { "off", ZIO_CHECKSUM_OFF }, 6690075Sobrien { "fletcher2", ZIO_CHECKSUM_FLETCHER_2 }, 6790075Sobrien { "fletcher4", ZIO_CHECKSUM_FLETCHER_4 }, 6890075Sobrien { "sha256", ZIO_CHECKSUM_SHA256 }, 6990075Sobrien { NULL } 7090075Sobrien }; 7190075Sobrien 7290075Sobrien static zprop_index_t compress_table[] = { 7390075Sobrien { "on", ZIO_COMPRESS_ON }, 7490075Sobrien { "off", ZIO_COMPRESS_OFF }, 7590075Sobrien { "lzjb", ZIO_COMPRESS_LZJB }, 76117395Skan { "gzip", ZIO_COMPRESS_GZIP_6 }, /* gzip default */ 77117395Skan { "gzip-1", ZIO_COMPRESS_GZIP_1 }, 78117395Skan { "gzip-2", ZIO_COMPRESS_GZIP_2 }, 7990075Sobrien { "gzip-3", ZIO_COMPRESS_GZIP_3 }, 8090075Sobrien { "gzip-4", ZIO_COMPRESS_GZIP_4 }, 8190075Sobrien { "gzip-5", ZIO_COMPRESS_GZIP_5 }, 8290075Sobrien { "gzip-6", ZIO_COMPRESS_GZIP_6 }, 8390075Sobrien { "gzip-7", ZIO_COMPRESS_GZIP_7 }, 8490075Sobrien { "gzip-8", ZIO_COMPRESS_GZIP_8 }, 8590075Sobrien { "gzip-9", ZIO_COMPRESS_GZIP_9 }, 8690075Sobrien { NULL } 8790075Sobrien }; 8890075Sobrien 8990075Sobrien static zprop_index_t snapdir_table[] = { 9090075Sobrien { "hidden", ZFS_SNAPDIR_HIDDEN }, 9190075Sobrien { "visible", ZFS_SNAPDIR_VISIBLE }, 9290075Sobrien { NULL } 9390075Sobrien }; 9490075Sobrien 9590075Sobrien static zprop_index_t acl_mode_table[] = { 9690075Sobrien { "discard", ZFS_ACL_DISCARD }, 9790075Sobrien { "groupmask", ZFS_ACL_GROUPMASK }, 9890075Sobrien { "passthrough", ZFS_ACL_PASSTHROUGH }, 9990075Sobrien { NULL } 10090075Sobrien }; 10190075Sobrien 10290075Sobrien static zprop_index_t acl_inherit_table[] = { 10390075Sobrien { "discard", ZFS_ACL_DISCARD }, 10490075Sobrien { "noallow", ZFS_ACL_NOALLOW }, 10590075Sobrien { "restricted", ZFS_ACL_RESTRICTED }, 10690075Sobrien { "passthrough", ZFS_ACL_PASSTHROUGH }, 10790075Sobrien { "secure", ZFS_ACL_RESTRICTED }, /* bkwrd compatability */ 10890075Sobrien { "passthrough-x", ZFS_ACL_PASSTHROUGH_X }, 10990075Sobrien { NULL } 11090075Sobrien }; 11190075Sobrien 11290075Sobrien static zprop_index_t case_table[] = { 11390075Sobrien { "sensitive", ZFS_CASE_SENSITIVE }, 11490075Sobrien { "insensitive", ZFS_CASE_INSENSITIVE }, 11590075Sobrien { "mixed", ZFS_CASE_MIXED }, 11690075Sobrien { NULL } 11790075Sobrien }; 11890075Sobrien 11990075Sobrien static zprop_index_t copies_table[] = { 12090075Sobrien { "1", 1 }, 12190075Sobrien { "2", 2 }, 12290075Sobrien { "3", 3 }, 12390075Sobrien { NULL } 12490075Sobrien }; 12590075Sobrien 12690075Sobrien /* 12790075Sobrien * Use the unique flags we have to send to u8_strcmp() and/or 12890075Sobrien * u8_textprep() to represent the various normalization property 12990075Sobrien * values. 13090075Sobrien */ 13190075Sobrien static zprop_index_t normalize_table[] = { 13290075Sobrien { "none", 0 }, 13390075Sobrien { "formD", U8_TEXTPREP_NFD }, 13490075Sobrien { "formKC", U8_TEXTPREP_NFKC }, 13590075Sobrien { "formC", U8_TEXTPREP_NFC }, 13690075Sobrien { "formKD", U8_TEXTPREP_NFKD }, 13790075Sobrien { NULL } 13890075Sobrien }; 13990075Sobrien 14090075Sobrien static zprop_index_t version_table[] = { 14190075Sobrien { "1", 1 }, 14290075Sobrien { "2", 2 }, 143117395Skan { "3", 3 }, 14490075Sobrien { "4", 4 }, 14590075Sobrien { "current", ZPL_VERSION }, 14690075Sobrien { NULL } 14790075Sobrien }; 14890075Sobrien 14990075Sobrien static zprop_index_t boolean_table[] = { 15090075Sobrien { "off", 0 }, 15190075Sobrien { "on", 1 }, 152117395Skan { NULL } 153117395Skan }; 154117395Skan 155117395Skan static zprop_index_t canmount_table[] = { 156117395Skan { "off", ZFS_CANMOUNT_OFF }, 157117395Skan { "on", ZFS_CANMOUNT_ON }, 158117395Skan { "noauto", ZFS_CANMOUNT_NOAUTO }, 159117395Skan { NULL } 160117395Skan }; 161117395Skan 162117395Skan static zprop_index_t cache_table[] = { 163117395Skan { "none", ZFS_CACHE_NONE }, 164117395Skan { "metadata", ZFS_CACHE_METADATA }, 165117395Skan { "all", ZFS_CACHE_ALL }, 166117395Skan { NULL } 167117395Skan }; 168117395Skan 169117395Skan /* inherit index properties */ 17090075Sobrien register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT, 17190075Sobrien PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, 17290075Sobrien "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM", 17390075Sobrien checksum_table); 17490075Sobrien register_index(ZFS_PROP_COMPRESSION, "compression", 17590075Sobrien ZIO_COMPRESS_DEFAULT, PROP_INHERIT, 17690075Sobrien ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, 17790075Sobrien "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", compress_table); 17890075Sobrien register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN, 17990075Sobrien PROP_INHERIT, ZFS_TYPE_FILESYSTEM, 18090075Sobrien "hidden | visible", "SNAPDIR", snapdir_table); 18190075Sobrien register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK, 18290075Sobrien PROP_INHERIT, ZFS_TYPE_FILESYSTEM, 183117395Skan "discard | groupmask | passthrough", "ACLMODE", acl_mode_table); 18490075Sobrien register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_RESTRICTED, 18590075Sobrien PROP_INHERIT, ZFS_TYPE_FILESYSTEM, 18690075Sobrien "discard | noallow | restricted | passthrough | passthrough-x", 18790075Sobrien "ACLINHERIT", acl_inherit_table); 18890075Sobrien register_index(ZFS_PROP_COPIES, "copies", 1, 18990075Sobrien PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, 190117395Skan "1 | 2 | 3", "COPIES", copies_table); 191117395Skan register_index(ZFS_PROP_PRIMARYCACHE, "primarycache", 19290075Sobrien ZFS_CACHE_ALL, PROP_INHERIT, 19390075Sobrien ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, 19490075Sobrien "all | none | metadata", "PRIMARYCACHE", cache_table); 19590075Sobrien register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache", 19690075Sobrien ZFS_CACHE_ALL, PROP_INHERIT, 19790075Sobrien ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, 19890075Sobrien "all | none | metadata", "SECONDARYCACHE", cache_table); 19990075Sobrien 20090075Sobrien /* inherit index (boolean) properties */ 20190075Sobrien register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT, 20290075Sobrien ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table); 20390075Sobrien register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT, 204117395Skan ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES", 20590075Sobrien boolean_table); 20690075Sobrien register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT, 207 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC", 208 boolean_table); 209 register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT, 210 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID", 211 boolean_table); 212 register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT, 213 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY", 214 boolean_table); 215 register_index(ZFS_PROP_ZONED, "jailed", 0, PROP_INHERIT, 216 ZFS_TYPE_FILESYSTEM, "on | off", "JAILED", boolean_table); 217 register_index(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT, 218 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR", 219 boolean_table); 220 register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT, 221 ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN", 222 boolean_table); 223 register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT, 224 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "NBMAND", 225 boolean_table); 226 227 /* default index properties */ 228 register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT, 229 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, 230 "1 | 2 | 3 | 4 | current", "VERSION", version_table); 231 register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON, 232 PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto", 233 "CANMOUNT", canmount_table); 234 235 /* readonly index (boolean) properties */ 236 register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY, 237 ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table); 238 239 /* set once index properties */ 240 register_index(ZFS_PROP_NORMALIZE, "normalization", 0, 241 PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, 242 "none | formC | formD | formKC | formKD", "NORMALIZATION", 243 normalize_table); 244 register_index(ZFS_PROP_CASE, "casesensitivity", ZFS_CASE_SENSITIVE, 245 PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, 246 "sensitive | insensitive | mixed", "CASE", case_table); 247 248 /* set once index (boolean) properties */ 249 register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME, 250 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, 251 "on | off", "UTF8ONLY", boolean_table); 252 253 /* string properties */ 254 register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY, 255 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN"); 256 register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", PROP_INHERIT, 257 ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", "MOUNTPOINT"); 258 register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", PROP_INHERIT, 259 ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", "SHARENFS"); 260 register_string(ZFS_PROP_SHAREISCSI, "shareiscsi", "off", PROP_INHERIT, 261 ZFS_TYPE_DATASET, "on | off | type=<type>", "SHAREISCSI"); 262 register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY, 263 ZFS_TYPE_DATASET, "filesystem | volume | snapshot", "TYPE"); 264 register_string(ZFS_PROP_SHARESMB, "sharesmb", "off", PROP_INHERIT, 265 ZFS_TYPE_FILESYSTEM, "on | off | sharemgr(1M) options", "SHARESMB"); 266 267 /* readonly number properties */ 268 register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY, 269 ZFS_TYPE_DATASET, "<size>", "USED"); 270 register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY, 271 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL"); 272 register_number(ZFS_PROP_REFERENCED, "referenced", 0, PROP_READONLY, 273 ZFS_TYPE_DATASET, "<size>", "REFER"); 274 register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0, 275 PROP_READONLY, ZFS_TYPE_DATASET, 276 "<1.00x or higher if compressed>", "RATIO"); 277 register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192, 278 PROP_ONETIME, 279 ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK"); 280 register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0, PROP_READONLY, 281 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDSNAP"); 282 register_number(ZFS_PROP_USEDDS, "usedbydataset", 0, PROP_READONLY, 283 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDDS"); 284 register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0, PROP_READONLY, 285 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDCHILD"); 286 register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0, 287 PROP_READONLY, 288 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV"); 289 290 /* default number properties */ 291 register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT, 292 ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA"); 293 register_number(ZFS_PROP_RESERVATION, "reservation", 0, PROP_DEFAULT, 294 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "RESERV"); 295 register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT, 296 ZFS_TYPE_VOLUME, "<size>", "VOLSIZE"); 297 register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT, 298 ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA"); 299 register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0, 300 PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, 301 "<size> | none", "REFRESERV"); 302 303 /* inherit number properties */ 304 register_number(ZFS_PROP_RECORDSIZE, "recordsize", SPA_MAXBLOCKSIZE, 305 PROP_INHERIT, 306 ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE"); 307 308 /* hidden properties */ 309 register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER, 310 PROP_READONLY, ZFS_TYPE_DATASET, "CREATETXG"); 311 register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER, 312 PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL); 313 register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING, 314 PROP_READONLY, ZFS_TYPE_DATASET, "NAME"); 315 register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING, 316 PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS"); 317 register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER, PROP_READONLY, 318 ZFS_TYPE_DATASET, "GUID"); 319 register_hidden(ZFS_PROP_USERACCOUNTING, "useraccounting", 320 PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, NULL); 321 322 /* oddball properties */ 323 register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL, 324 PROP_READONLY, ZFS_TYPE_DATASET, 325 "<date>", "CREATION", B_FALSE, B_TRUE, NULL); 326} 327 328boolean_t 329zfs_prop_delegatable(zfs_prop_t prop) 330{ 331 zprop_desc_t *pd = &zfs_prop_table[prop]; 332 return (pd->pd_attr != PROP_READONLY); 333} 334 335/* 336 * Given a zfs dataset property name, returns the corresponding property ID. 337 */ 338zfs_prop_t 339zfs_name_to_prop(const char *propname) 340{ 341 return (zprop_name_to_prop(propname, ZFS_TYPE_DATASET)); 342} 343 344/* 345 * For user property names, we allow all lowercase alphanumeric characters, plus 346 * a few useful punctuation characters. 347 */ 348static int 349valid_char(char c) 350{ 351 return ((c >= 'a' && c <= 'z') || 352 (c >= '0' && c <= '9') || 353 c == '-' || c == '_' || c == '.' || c == ':'); 354} 355 356/* 357 * Returns true if this is a valid user-defined property (one with a ':'). 358 */ 359boolean_t 360zfs_prop_user(const char *name) 361{ 362 int i; 363 char c; 364 boolean_t foundsep = B_FALSE; 365 366 for (i = 0; i < strlen(name); i++) { 367 c = name[i]; 368 if (!valid_char(c)) 369 return (B_FALSE); 370 if (c == ':') 371 foundsep = B_TRUE; 372 } 373 374 if (!foundsep) 375 return (B_FALSE); 376 377 return (B_TRUE); 378} 379 380/* 381 * Returns true if this is a valid userspace-type property (one with a '@'). 382 * Note that after the @, any character is valid (eg, another @, for SID 383 * user@domain). 384 */ 385boolean_t 386zfs_prop_userquota(const char *name) 387{ 388 zfs_userquota_prop_t prop; 389 390 for (prop = 0; prop < ZFS_NUM_USERQUOTA_PROPS; prop++) { 391 if (strncmp(name, zfs_userquota_prop_prefixes[prop], 392 strlen(zfs_userquota_prop_prefixes[prop])) == 0) { 393 return (B_TRUE); 394 } 395 } 396 397 return (B_FALSE); 398} 399 400/* 401 * Tables of index types, plus functions to convert between the user view 402 * (strings) and internal representation (uint64_t). 403 */ 404int 405zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index) 406{ 407 return (zprop_string_to_index(prop, string, index, ZFS_TYPE_DATASET)); 408} 409 410int 411zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string) 412{ 413 return (zprop_index_to_string(prop, index, string, ZFS_TYPE_DATASET)); 414} 415 416/* 417 * Returns TRUE if the property applies to any of the given dataset types. 418 */ 419boolean_t 420zfs_prop_valid_for_type(int prop, zfs_type_t types) 421{ 422 return (zprop_valid_for_type(prop, types)); 423} 424 425zprop_type_t 426zfs_prop_get_type(zfs_prop_t prop) 427{ 428 return (zfs_prop_table[prop].pd_proptype); 429} 430 431/* 432 * Returns TRUE if the property is readonly. 433 */ 434boolean_t 435zfs_prop_readonly(zfs_prop_t prop) 436{ 437 return (zfs_prop_table[prop].pd_attr == PROP_READONLY || 438 zfs_prop_table[prop].pd_attr == PROP_ONETIME); 439} 440 441/* 442 * Returns TRUE if the property is only allowed to be set once. 443 */ 444boolean_t 445zfs_prop_setonce(zfs_prop_t prop) 446{ 447 return (zfs_prop_table[prop].pd_attr == PROP_ONETIME); 448} 449 450const char * 451zfs_prop_default_string(zfs_prop_t prop) 452{ 453 return (zfs_prop_table[prop].pd_strdefault); 454} 455 456uint64_t 457zfs_prop_default_numeric(zfs_prop_t prop) 458{ 459 return (zfs_prop_table[prop].pd_numdefault); 460} 461 462/* 463 * Given a dataset property ID, returns the corresponding name. 464 * Assuming the zfs dataset property ID is valid. 465 */ 466const char * 467zfs_prop_to_name(zfs_prop_t prop) 468{ 469 return (zfs_prop_table[prop].pd_name); 470} 471 472/* 473 * Returns TRUE if the property is inheritable. 474 */ 475boolean_t 476zfs_prop_inheritable(zfs_prop_t prop) 477{ 478 return (zfs_prop_table[prop].pd_attr == PROP_INHERIT || 479 zfs_prop_table[prop].pd_attr == PROP_ONETIME); 480} 481 482#ifndef _KERNEL 483 484/* 485 * Returns a string describing the set of acceptable values for the given 486 * zfs property, or NULL if it cannot be set. 487 */ 488const char * 489zfs_prop_values(zfs_prop_t prop) 490{ 491 return (zfs_prop_table[prop].pd_values); 492} 493 494/* 495 * Returns TRUE if this property is a string type. Note that index types 496 * (compression, checksum) are treated as strings in userland, even though they 497 * are stored numerically on disk. 498 */ 499int 500zfs_prop_is_string(zfs_prop_t prop) 501{ 502 return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING || 503 zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX); 504} 505 506/* 507 * Returns the column header for the given property. Used only in 508 * 'zfs list -o', but centralized here with the other property information. 509 */ 510const char * 511zfs_prop_column_name(zfs_prop_t prop) 512{ 513 return (zfs_prop_table[prop].pd_colname); 514} 515 516/* 517 * Returns whether the given property should be displayed right-justified for 518 * 'zfs list'. 519 */ 520boolean_t 521zfs_prop_align_right(zfs_prop_t prop) 522{ 523 return (zfs_prop_table[prop].pd_rightalign); 524} 525 526#endif 527