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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/zio.h> 29 #include <sys/spa.h> 30 #include <sys/zfs_acl.h> 31 #include <sys/zfs_ioctl.h> 32 #include <sys/zfs_znode.h> 33 34 #include "zfs_prop.h" 35 #include "zfs_deleg.h" 36 37 #if defined(_KERNEL) 38 #include <sys/systm.h> 39 #else 40 #include <stdlib.h> 41 #include <string.h> 42 #include <ctype.h> 43 #endif 44 45 static zprop_desc_t zfs_prop_table[ZFS_NUM_PROPS]; 46 47 zprop_desc_t * 48 zfs_prop_get_table(void) 49 { 50 return (zfs_prop_table); 51 } 52 53 void 54 zfs_prop_init(void) 55 { 56 static zprop_index_t checksum_table[] = { 57 { "on", ZIO_CHECKSUM_ON }, 58 { "off", ZIO_CHECKSUM_OFF }, 59 { "fletcher2", ZIO_CHECKSUM_FLETCHER_2 }, 60 { "fletcher4", ZIO_CHECKSUM_FLETCHER_4 }, 61 { "sha256", ZIO_CHECKSUM_SHA256 }, 62 { NULL } 63 }; 64 65 static zprop_index_t compress_table[] = { 66 { "on", ZIO_COMPRESS_ON }, 67 { "off", ZIO_COMPRESS_OFF }, 68 { "lzjb", ZIO_COMPRESS_LZJB }, 69 { "gzip", ZIO_COMPRESS_GZIP_6 }, /* gzip default */ 70 { "gzip-1", ZIO_COMPRESS_GZIP_1 }, 71 { "gzip-2", ZIO_COMPRESS_GZIP_2 }, 72 { "gzip-3", ZIO_COMPRESS_GZIP_3 }, 73 { "gzip-4", ZIO_COMPRESS_GZIP_4 }, 74 { "gzip-5", ZIO_COMPRESS_GZIP_5 }, 75 { "gzip-6", ZIO_COMPRESS_GZIP_6 }, 76 { "gzip-7", ZIO_COMPRESS_GZIP_7 }, 77 { "gzip-8", ZIO_COMPRESS_GZIP_8 }, 78 { "gzip-9", ZIO_COMPRESS_GZIP_9 }, 79 { NULL } 80 }; 81 82 static zprop_index_t snapdir_table[] = { 83 { "hidden", ZFS_SNAPDIR_HIDDEN }, 84 { "visible", ZFS_SNAPDIR_VISIBLE }, 85 { NULL } 86 }; 87 88 static zprop_index_t acl_mode_table[] = { 89 { "discard", ZFS_ACL_DISCARD }, 90 { "groupmask", ZFS_ACL_GROUPMASK }, 91 { "passthrough", ZFS_ACL_PASSTHROUGH }, 92 { NULL } 93 }; 94 95 static zprop_index_t acl_inherit_table[] = { 96 { "discard", ZFS_ACL_DISCARD }, 97 { "noallow", ZFS_ACL_NOALLOW }, 98 { "secure", ZFS_ACL_SECURE }, 99 { "passthrough", ZFS_ACL_PASSTHROUGH }, 100 { NULL } 101 }; 102 103 static zprop_index_t copies_table[] = { 104 { "1", 1 }, 105 { "2", 2 }, 106 { "3", 3 }, 107 { NULL } 108 }; 109 110 static zprop_index_t version_table[] = { 111 { "1", 1 }, 112 { "2", 2 }, 113 { "current", ZPL_VERSION }, 114 { NULL } 115 }; 116 117 static zprop_index_t boolean_table[] = { 118 { "off", 0 }, 119 { "on", 1 }, 120 { NULL } 121 }; 122 123 /* inherit index properties */ 124 register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT, 125 PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, 126 "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM", 127 checksum_table); 128 register_index(ZFS_PROP_COMPRESSION, "compression", 129 ZIO_COMPRESS_DEFAULT, PROP_INHERIT, 130 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, 131 "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", compress_table); 132 register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN, 133 PROP_INHERIT, ZFS_TYPE_FILESYSTEM, 134 "hidden | visible", "SNAPDIR", snapdir_table); 135 register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK, 136 PROP_INHERIT, ZFS_TYPE_FILESYSTEM, 137 "discard | groupmask | passthrough", "ACLMODE", acl_mode_table); 138 register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_SECURE, 139 PROP_INHERIT, ZFS_TYPE_FILESYSTEM, 140 "discard | noallow | secure | passthrough", "ACLINHERIT", 141 acl_inherit_table); 142 register_index(ZFS_PROP_COPIES, "copies", 1, 143 PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, 144 "1 | 2 | 3", "COPIES", copies_table); 145 146 /* inherit index (boolean) properties */ 147 register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT, 148 ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table); 149 register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT, 150 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES", 151 boolean_table); 152 register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT, 153 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC", 154 boolean_table); 155 register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT, 156 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID", 157 boolean_table); 158 register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT, 159 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY", 160 boolean_table); 161 register_index(ZFS_PROP_ZONED, "zoned", 0, PROP_INHERIT, 162 ZFS_TYPE_FILESYSTEM, "on | off", "ZONED", boolean_table); 163 register_index(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT, 164 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR", 165 boolean_table); 166 167 /* default index properties */ 168 register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT, 169 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, 170 "1 | 2 | current", "VERSION", version_table); 171 172 /* default index (boolean) properties */ 173 register_index(ZFS_PROP_CANMOUNT, "canmount", 1, PROP_DEFAULT, 174 ZFS_TYPE_FILESYSTEM, "on | off", "CANMOUNT", boolean_table); 175 176 /* readonly index (boolean) properties */ 177 register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY, 178 ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table); 179 180 /* string properties */ 181 register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY, 182 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN"); 183 register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", PROP_INHERIT, 184 ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", "MOUNTPOINT"); 185 register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", PROP_INHERIT, 186 ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", "SHARENFS"); 187 register_string(ZFS_PROP_SHAREISCSI, "shareiscsi", "off", PROP_INHERIT, 188 ZFS_TYPE_DATASET, "on | off | type=<type>", "SHAREISCSI"); 189 register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY, 190 ZFS_TYPE_DATASET, "filesystem | volume | snapshot", "TYPE"); 191 192 /* readonly number properties */ 193 register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY, 194 ZFS_TYPE_DATASET, "<size>", "USED"); 195 register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY, 196 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL"); 197 register_number(ZFS_PROP_REFERENCED, "referenced", 0, PROP_READONLY, 198 ZFS_TYPE_DATASET, "<size>", "REFER"); 199 register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0, 200 PROP_READONLY, ZFS_TYPE_DATASET, 201 "<1.00x or higher if compressed>", "RATIO"); 202 register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192, 203 PROP_READONLY, ZFS_TYPE_VOLUME, 204 "512 to 128k, power of 2", "VOLBLOCK"); 205 206 /* default number properties */ 207 register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT, 208 ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA"); 209 register_number(ZFS_PROP_RESERVATION, "reservation", 0, PROP_DEFAULT, 210 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "RESERV"); 211 register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT, 212 ZFS_TYPE_VOLUME, "<size>", "VOLSIZE"); 213 214 /* inherit number properties */ 215 register_number(ZFS_PROP_RECORDSIZE, "recordsize", SPA_MAXBLOCKSIZE, 216 PROP_INHERIT, 217 ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE"); 218 219 /* hidden properties */ 220 register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER, 221 PROP_READONLY, ZFS_TYPE_DATASET, NULL); 222 register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER, 223 PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL); 224 register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING, 225 PROP_READONLY, ZFS_TYPE_DATASET, "NAME"); 226 register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING, 227 PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS"); 228 229 /* oddball properties */ 230 register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL, 231 PROP_READONLY, ZFS_TYPE_DATASET, 232 "<date>", "CREATION", B_FALSE, B_TRUE, NULL); 233 } 234 235 boolean_t 236 zfs_prop_delegatable(zfs_prop_t prop) 237 { 238 zprop_desc_t *pd = &zfs_prop_table[prop]; 239 return (pd->pd_attr != PROP_READONLY); 240 } 241 242 /* 243 * Given a zfs dataset property name, returns the corresponding property ID. 244 */ 245 zfs_prop_t 246 zfs_name_to_prop(const char *propname) 247 { 248 return (zprop_name_to_prop(propname, ZFS_TYPE_DATASET)); 249 } 250 251 252 /* 253 * For user property names, we allow all lowercase alphanumeric characters, plus 254 * a few useful punctuation characters. 255 */ 256 static int 257 valid_char(char c) 258 { 259 return ((c >= 'a' && c <= 'z') || 260 (c >= '0' && c <= '9') || 261 c == '-' || c == '_' || c == '.' || c == ':'); 262 } 263 264 /* 265 * Returns true if this is a valid user-defined property (one with a ':'). 266 */ 267 boolean_t 268 zfs_prop_user(const char *name) 269 { 270 int i; 271 char c; 272 boolean_t foundsep = B_FALSE; 273 274 for (i = 0; i < strlen(name); i++) { 275 c = name[i]; 276 if (!valid_char(c)) 277 return (B_FALSE); 278 if (c == ':') 279 foundsep = B_TRUE; 280 } 281 282 if (!foundsep) 283 return (B_FALSE); 284 285 return (B_TRUE); 286 } 287 288 /* 289 * Tables of index types, plus functions to convert between the user view 290 * (strings) and internal representation (uint64_t). 291 */ 292 int 293 zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index) 294 { 295 return (zprop_string_to_index(prop, string, index, ZFS_TYPE_DATASET)); 296 } 297 298 int 299 zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string) 300 { 301 return (zprop_index_to_string(prop, index, string, ZFS_TYPE_DATASET)); 302 } 303 304 /* 305 * Returns TRUE if the property applies to any of the given dataset types. 306 */ 307 int 308 zfs_prop_valid_for_type(int prop, zfs_type_t types) 309 { 310 return (zprop_valid_for_type(prop, types)); 311 } 312 313 zprop_type_t 314 zfs_prop_get_type(zfs_prop_t prop) 315 { 316 return (zfs_prop_table[prop].pd_proptype); 317 } 318 319 /* 320 * Returns TRUE if the property is readonly. 321 */ 322 boolean_t 323 zfs_prop_readonly(zfs_prop_t prop) 324 { 325 return (zfs_prop_table[prop].pd_attr == PROP_READONLY); 326 } 327 328 const char * 329 zfs_prop_default_string(zfs_prop_t prop) 330 { 331 return (zfs_prop_table[prop].pd_strdefault); 332 } 333 334 uint64_t 335 zfs_prop_default_numeric(zfs_prop_t prop) 336 { 337 return (zfs_prop_table[prop].pd_numdefault); 338 } 339 340 /* 341 * Given a dataset property ID, returns the corresponding name. 342 * Assuming the zfs dataset property ID is valid. 343 */ 344 const char * 345 zfs_prop_to_name(zfs_prop_t prop) 346 { 347 return (zfs_prop_table[prop].pd_name); 348 } 349 350 /* 351 * Returns TRUE if the property is inheritable. 352 */ 353 boolean_t 354 zfs_prop_inheritable(zfs_prop_t prop) 355 { 356 return (zfs_prop_table[prop].pd_attr == PROP_INHERIT); 357 } 358 359 #ifndef _KERNEL 360 361 /* 362 * Returns a string describing the set of acceptable values for the given 363 * zfs property, or NULL if it cannot be set. 364 */ 365 const char * 366 zfs_prop_values(zfs_prop_t prop) 367 { 368 return (zfs_prop_table[prop].pd_values); 369 } 370 371 /* 372 * Returns TRUE if this property is a string type. Note that index types 373 * (compression, checksum) are treated as strings in userland, even though they 374 * are stored numerically on disk. 375 */ 376 int 377 zfs_prop_is_string(zfs_prop_t prop) 378 { 379 return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING || 380 zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX); 381 } 382 383 /* 384 * Returns the column header for the given property. Used only in 385 * 'zfs list -o', but centralized here with the other property information. 386 */ 387 const char * 388 zfs_prop_column_name(zfs_prop_t prop) 389 { 390 return (zfs_prop_table[prop].pd_colname); 391 } 392 393 /* 394 * Returns whether the given property should be displayed right-justified for 395 * 'zfs list'. 396 */ 397 boolean_t 398 zfs_prop_align_right(zfs_prop_t prop) 399 { 400 return (zfs_prop_table[prop].pd_rightalign); 401 } 402 #endif 403