]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zcommon/zfs_prop.c
OpenZFS 7614, 9064 - zfs device evacuation/removal
[mirror_zfs.git] / module / zcommon / zfs_prop.c
index 029075ebec93caf703372bc6e82ca1765d7764ca..34b7228ec9be5fe614c4010d4936723740493247 100644 (file)
@@ -20,8 +20,9 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright 2016, Joyent, Inc.
  */
 
 /* Portions Copyright 2010 Robert Milkowski */
@@ -32,6 +33,7 @@
 #include <sys/zfs_acl.h>
 #include <sys/zfs_ioctl.h>
 #include <sys/zfs_znode.h>
+#include <sys/dsl_crypt.h>
 
 #include "zfs_prop.h"
 #include "zfs_deleg.h"
@@ -52,7 +54,15 @@ const char *zfs_userquota_prop_prefixes[] = {
        "userused@",
        "userquota@",
        "groupused@",
-       "groupquota@"
+       "groupquota@",
+       "userobjused@",
+       "userobjquota@",
+       "groupobjused@",
+       "groupobjquota@",
+       "projectused@",
+       "projectquota@",
+       "projectobjused@",
+       "projectobjquota@"
 };
 
 zprop_desc_t *
@@ -114,6 +124,26 @@ zfs_prop_init(void)
                { NULL }
        };
 
+       static zprop_index_t crypto_table[] = {
+               { "on",                 ZIO_CRYPT_ON },
+               { "off",                ZIO_CRYPT_OFF },
+               { "aes-128-ccm",        ZIO_CRYPT_AES_128_CCM },
+               { "aes-192-ccm",        ZIO_CRYPT_AES_192_CCM },
+               { "aes-256-ccm",        ZIO_CRYPT_AES_256_CCM },
+               { "aes-128-gcm",        ZIO_CRYPT_AES_128_GCM },
+               { "aes-192-gcm",        ZIO_CRYPT_AES_192_GCM },
+               { "aes-256-gcm",        ZIO_CRYPT_AES_256_GCM },
+               { NULL }
+       };
+
+       static zprop_index_t keyformat_table[] = {
+               { "none",               ZFS_KEYFORMAT_NONE },
+               { "raw",                ZFS_KEYFORMAT_RAW },
+               { "hex",                ZFS_KEYFORMAT_HEX },
+               { "passphrase",         ZFS_KEYFORMAT_PASSPHRASE },
+               { NULL }
+       };
+
        static zprop_index_t snapdir_table[] = {
                { "hidden",     ZFS_SNAPDIR_HIDDEN },
                { "visible",    ZFS_SNAPDIR_VISIBLE },
@@ -139,7 +169,7 @@ zfs_prop_init(void)
                { "noallow",    ZFS_ACL_NOALLOW },
                { "restricted", ZFS_ACL_RESTRICTED },
                { "passthrough", ZFS_ACL_PASSTHROUGH },
-               { "secure",     ZFS_ACL_RESTRICTED }, /* bkwrd compatability */
+               { "secure",     ZFS_ACL_RESTRICTED }, /* bkwrd compatibility */
                { "passthrough-x", ZFS_ACL_PASSTHROUGH_X },
                { NULL }
        };
@@ -188,6 +218,13 @@ zfs_prop_init(void)
                { NULL }
        };
 
+       static zprop_index_t keystatus_table[] = {
+               { "none",               ZFS_KEYSTATUS_NONE},
+               { "unavailable",        ZFS_KEYSTATUS_UNAVAILABLE},
+               { "available",          ZFS_KEYSTATUS_AVAILABLE},
+               { NULL }
+       };
+
        static zprop_index_t logbias_table[] = {
                { "latency",    ZFS_LOGBIAS_LATENCY },
                { "throughput", ZFS_LOGBIAS_THROUGHPUT },
@@ -240,6 +277,15 @@ zfs_prop_init(void)
                { NULL }
        };
 
+       static zprop_index_t volmode_table[] = {
+               { "default",    ZFS_VOLMODE_DEFAULT },
+               { "full",       ZFS_VOLMODE_GEOM },
+               { "geom",       ZFS_VOLMODE_GEOM },
+               { "dev",        ZFS_VOLMODE_DEV },
+               { "none",       ZFS_VOLMODE_NONE },
+               { NULL }
+       };
+
        /* inherit index properties */
        zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata",
            ZFS_REDUNDANT_METADATA_ALL,
@@ -297,6 +343,10 @@ zfs_prop_init(void)
        zprop_register_index(ZFS_PROP_DNODESIZE, "dnodesize",
            ZFS_DNSIZE_LEGACY, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
            "legacy | auto | 1k | 2k | 4k | 8k | 16k", "DNSIZE", dnsize_table);
+       zprop_register_index(ZFS_PROP_VOLMODE, "volmode",
+           ZFS_VOLMODE_DEFAULT, PROP_INHERIT,
+           ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+           "default | full | geom | dev | none", "VOLMODE", volmode_table);
 
        /* inherit index (boolean) properties */
        zprop_register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
@@ -333,12 +383,16 @@ zfs_prop_init(void)
            PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto",
            "CANMOUNT", canmount_table);
 
-       /* readonly index (boolean) properties */
+       /* readonly index properties */
        zprop_register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
            ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table);
        zprop_register_index(ZFS_PROP_DEFER_DESTROY, "defer_destroy", 0,
            PROP_READONLY, ZFS_TYPE_SNAPSHOT, "yes | no", "DEFER_DESTROY",
            boolean_table);
+       zprop_register_index(ZFS_PROP_KEYSTATUS, "keystatus",
+           ZFS_KEYSTATUS_NONE, PROP_READONLY, ZFS_TYPE_DATASET,
+           "none | unavailable | available",
+           "KEYSTATUS", keystatus_table);
 
        /* set once index properties */
        zprop_register_index(ZFS_PROP_NORMALIZE, "normalization", 0,
@@ -349,6 +403,15 @@ zfs_prop_init(void)
            ZFS_CASE_SENSITIVE, PROP_ONETIME, ZFS_TYPE_FILESYSTEM |
            ZFS_TYPE_SNAPSHOT,
            "sensitive | insensitive | mixed", "CASE", case_table);
+       zprop_register_index(ZFS_PROP_KEYFORMAT, "keyformat",
+           ZFS_KEYFORMAT_NONE, PROP_ONETIME_DEFAULT,
+           ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+           "none | raw | hex | passphrase", "KEYFORMAT", keyformat_table);
+       zprop_register_index(ZFS_PROP_ENCRYPTION, "encryption",
+           ZIO_CRYPT_DEFAULT, PROP_ONETIME, ZFS_TYPE_DATASET,
+           "on | off | aes-128-ccm | aes-192-ccm | aes-256-ccm | "
+           "aes-128-gcm | aes-192-gcm | aes-256-gcm", "ENCRYPTION",
+           crypto_table);
 
        /* set once index (boolean) properties */
        zprop_register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME,
@@ -391,6 +454,12 @@ zfs_prop_init(void)
            "receive_resume_token",
            NULL, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
            "<string token>", "RESUMETOK");
+       zprop_register_string(ZFS_PROP_ENCRYPTION_ROOT, "encryptionroot", NULL,
+           PROP_READONLY, ZFS_TYPE_DATASET, "<filesystem | volume>",
+           "ENCROOT");
+       zprop_register_string(ZFS_PROP_KEYLOCATION, "keylocation",
+           "none", PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+           "prompt | <file URI>", "KEYLOCATION");
 
        /* readonly number properties */
        zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
@@ -425,9 +494,25 @@ zfs_prop_init(void)
        zprop_register_number(ZFS_PROP_WRITTEN, "written", 0, PROP_READONLY,
            ZFS_TYPE_DATASET, "<size>", "WRITTEN");
        zprop_register_number(ZFS_PROP_LOGICALUSED, "logicalused", 0,
-           PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LUSED");
+           PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
+           "LUSED");
        zprop_register_number(ZFS_PROP_LOGICALREFERENCED, "logicalreferenced",
            0, PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LREFER");
+       zprop_register_number(ZFS_PROP_FILESYSTEM_COUNT, "filesystem_count",
+           UINT64_MAX, PROP_READONLY, ZFS_TYPE_FILESYSTEM,
+           "<count>", "FSCOUNT");
+       zprop_register_number(ZFS_PROP_SNAPSHOT_COUNT, "snapshot_count",
+           UINT64_MAX, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+           "<count>", "SSCOUNT");
+       zprop_register_number(ZFS_PROP_GUID, "guid", 0, PROP_READONLY,
+           ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "GUID");
+       zprop_register_number(ZFS_PROP_CREATETXG, "createtxg", 0, PROP_READONLY,
+           ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "CREATETXG");
+       zprop_register_hidden(ZFS_PROP_REMAPTXG, "remaptxg", PROP_TYPE_NUMBER,
+           PROP_READONLY, ZFS_TYPE_DATASET, "REMAPTXG");
+       zprop_register_number(ZFS_PROP_PBKDF2_ITERS, "pbkdf2iters",
+           0, PROP_ONETIME_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+           "<iters>", "PBKDF2ITERS");
 
        /* default number properties */
        zprop_register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
@@ -448,12 +533,6 @@ zfs_prop_init(void)
        zprop_register_number(ZFS_PROP_SNAPSHOT_LIMIT, "snapshot_limit",
            UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
            "<count> | none", "SSLIMIT");
-       zprop_register_number(ZFS_PROP_FILESYSTEM_COUNT, "filesystem_count",
-           UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
-           "<count>", "FSCOUNT");
-       zprop_register_number(ZFS_PROP_SNAPSHOT_COUNT, "snapshot_count",
-           UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
-           "<count>", "SSCOUNT");
 
        /* inherit number properties */
        zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize",
@@ -461,8 +540,6 @@ zfs_prop_init(void)
            ZFS_TYPE_FILESYSTEM, "512 to 1M, power of 2", "RECSIZE");
 
        /* hidden properties */
-       zprop_register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER,
-           PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "CREATETXG");
        zprop_register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
            PROP_READONLY, ZFS_TYPE_SNAPSHOT, "NUMCLONES");
        zprop_register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
@@ -472,8 +549,6 @@ zfs_prop_init(void)
        zprop_register_hidden(ZFS_PROP_STMF_SHAREINFO, "stmf_sbd_lu",
            PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME,
            "STMF_SBD_LU");
-       zprop_register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER,
-           PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "GUID");
        zprop_register_hidden(ZFS_PROP_USERACCOUNTING, "useraccounting",
            PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET,
            "USERACCOUNTING");
@@ -485,6 +560,11 @@ zfs_prop_init(void)
            PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT");
        zprop_register_hidden(ZFS_PROP_PREV_SNAP, "prevsnap", PROP_TYPE_STRING,
            PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PREVSNAP");
+       zprop_register_hidden(ZFS_PROP_PBKDF2_SALT, "pbkdf2salt",
+           PROP_TYPE_NUMBER, PROP_ONETIME_DEFAULT,
+           ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PBKDF2SALT");
+       zprop_register_hidden(ZFS_PROP_KEY_GUID, "keyguid", PROP_TYPE_NUMBER,
+           PROP_READONLY, ZFS_TYPE_DATASET, "KEYGUID");
 
        /*
         * Property to be removed once libbe is integrated
@@ -632,7 +712,17 @@ boolean_t
 zfs_prop_readonly(zfs_prop_t prop)
 {
        return (zfs_prop_table[prop].pd_attr == PROP_READONLY ||
-           zfs_prop_table[prop].pd_attr == PROP_ONETIME);
+           zfs_prop_table[prop].pd_attr == PROP_ONETIME ||
+           zfs_prop_table[prop].pd_attr == PROP_ONETIME_DEFAULT);
+}
+
+/*
+ * Returns TRUE if the property is visible (not hidden).
+ */
+boolean_t
+zfs_prop_visible(zfs_prop_t prop)
+{
+       return (zfs_prop_table[prop].pd_visible);
 }
 
 /*
@@ -641,7 +731,8 @@ zfs_prop_readonly(zfs_prop_t prop)
 boolean_t
 zfs_prop_setonce(zfs_prop_t prop)
 {
-       return (zfs_prop_table[prop].pd_attr == PROP_ONETIME);
+       return (zfs_prop_table[prop].pd_attr == PROP_ONETIME ||
+           zfs_prop_table[prop].pd_attr == PROP_ONETIME_DEFAULT);
 }
 
 const char *
@@ -676,6 +767,40 @@ zfs_prop_inheritable(zfs_prop_t prop)
            zfs_prop_table[prop].pd_attr == PROP_ONETIME);
 }
 
+/*
+ * Returns TRUE if property is one of the encryption properties that requires
+ * a loaded encryption key to modify.
+ */
+boolean_t
+zfs_prop_encryption_key_param(zfs_prop_t prop)
+{
+       /*
+        * keylocation does not count as an encryption property. It can be
+        * changed at will without needing the master keys.
+        */
+       return (prop == ZFS_PROP_PBKDF2_SALT || prop == ZFS_PROP_PBKDF2_ITERS ||
+           prop == ZFS_PROP_KEYFORMAT);
+}
+
+/*
+ * Helper function used by both kernelspace and userspace to check the
+ * keylocation property. If encrypted is set, the keylocation must be valid
+ * for an encrypted dataset.
+ */
+boolean_t
+zfs_prop_valid_keylocation(const char *str, boolean_t encrypted)
+{
+       if (strcmp("none", str) == 0)
+               return (!encrypted);
+       else if (strcmp("prompt", str) == 0)
+               return (B_TRUE);
+       else if (strlen(str) > 8 && strncmp("file:///", str, 8) == 0)
+               return (B_TRUE);
+
+       return (B_FALSE);
+}
+
+
 #ifndef _KERNEL
 
 /*
@@ -750,12 +875,15 @@ EXPORT_SYMBOL(zfs_prop_init);
 EXPORT_SYMBOL(zfs_prop_get_type);
 EXPORT_SYMBOL(zfs_prop_get_table);
 EXPORT_SYMBOL(zfs_prop_delegatable);
+EXPORT_SYMBOL(zfs_prop_visible);
 
 /* Dataset property functions shared between libzfs and kernel. */
 EXPORT_SYMBOL(zfs_prop_default_string);
 EXPORT_SYMBOL(zfs_prop_default_numeric);
 EXPORT_SYMBOL(zfs_prop_readonly);
 EXPORT_SYMBOL(zfs_prop_inheritable);
+EXPORT_SYMBOL(zfs_prop_encryption_key_param);
+EXPORT_SYMBOL(zfs_prop_valid_keylocation);
 EXPORT_SYMBOL(zfs_prop_setonce);
 EXPORT_SYMBOL(zfs_prop_to_name);
 EXPORT_SYMBOL(zfs_name_to_prop);
@@ -764,5 +892,6 @@ EXPORT_SYMBOL(zfs_prop_userquota);
 EXPORT_SYMBOL(zfs_prop_index_to_string);
 EXPORT_SYMBOL(zfs_prop_string_to_index);
 EXPORT_SYMBOL(zfs_prop_valid_for_type);
+EXPORT_SYMBOL(zfs_prop_written);
 
 #endif