zcommon: pre-iterate over sysfs instead of statting every feature

If sufficient memory (<2K, realistically) is available, libzfs_init()
can be significantly shorted by iterating over the correct sysfs
directory before registrations, we can turn 168 stats into 15/18
syscalls (3 opens (6 if built in), 3 fstats, 6 getdentses, and 3
closes), a tenfoldish reduction; this is probably a bit faster, too.

The list is always optional, and registration functions (and one-off
users) can simply pass NULL, which will fall back to the previous
mechanism

Also, don't allocate in zfs_mod_supported_impl, and use use access()
instead of stat(), since existence is really what we care about

Also, fix pre-prop-checking compat in fallback for built-in ZFS

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #12089
This commit is contained in:
наб 2021-12-17 01:43:10 +01:00 committed by GitHub
parent 8fdc6f618c
commit eb51a9d747
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 584 additions and 405 deletions

View File

@ -25,6 +25,10 @@
#ifndef _SYS_ZFS_SYSFS_H
#define _SYS_ZFS_SYSFS_H extern __attribute__((visibility("default")))
struct zfs_mod_supported_features;
struct zfs_mod_supported_features *zfs_mod_list_supported(const char *scope);
void zfs_mod_list_supported_free(struct zfs_mod_supported_features *);
#ifdef _KERNEL
void zfs_sysfs_init(void);
@ -35,7 +39,8 @@ void zfs_sysfs_fini(void);
#define zfs_sysfs_init()
#define zfs_sysfs_fini()
_SYS_ZFS_SYSFS_H boolean_t zfs_mod_supported(const char *, const char *);
_SYS_ZFS_SYSFS_H boolean_t zfs_mod_supported(const char *, const char *,
const struct zfs_mod_supported_features *);
#endif
#define ZFS_SYSFS_POOL_PROPERTIES "properties.pool"

View File

@ -28,6 +28,7 @@
#include <sys/fs/zfs.h>
#include <sys/types.h>
#include <sys/zfs_sysfs.h>
#ifdef __cplusplus
extern "C" {
@ -111,15 +112,19 @@ _ZFS_PROP_H zprop_desc_t *vdev_prop_get_table(void);
*/
_ZFS_PROP_H void zprop_register_impl(int, const char *, zprop_type_t, uint64_t,
const char *, zprop_attr_t, int, const char *, const char *,
boolean_t, boolean_t, const zprop_index_t *);
boolean_t, boolean_t, const zprop_index_t *,
const struct zfs_mod_supported_features *);
_ZFS_PROP_H void zprop_register_string(int, const char *, const char *,
zprop_attr_t attr, int, const char *, const char *);
zprop_attr_t attr, int, const char *, const char *,
const struct zfs_mod_supported_features *);
_ZFS_PROP_H void zprop_register_number(int, const char *, uint64_t,
zprop_attr_t, int, const char *, const char *);
zprop_attr_t, int, const char *, const char *,
const struct zfs_mod_supported_features *);
_ZFS_PROP_H void zprop_register_index(int, const char *, uint64_t, zprop_attr_t,
int, const char *, const char *, const zprop_index_t *);
int, const char *, const char *, const zprop_index_t *,
const struct zfs_mod_supported_features *);
_ZFS_PROP_H void zprop_register_hidden(int, const char *, zprop_type_t,
zprop_attr_t, int, const char *);
zprop_attr_t, int, const char *, const struct zfs_mod_supported_features *);
/*
* Common routines for zfs and zpool property management

View File

@ -1947,8 +1947,18 @@
</data-member>
</class-decl>
<typedef-decl name='zfeature_info_t' type-id='1178d146' id='83f29ca2'/>
<class-decl name='zfs_mod_supported_features' size-in-bits='128' is-struct='yes' visibility='default' id='3eee3342'>
<data-member access='public' layout-offset-in-bits='0'>
<var-decl name='tree' type-id='eaa32e2f' visibility='default'/>
</data-member>
<data-member access='public' layout-offset-in-bits='64'>
<var-decl name='all_features' type-id='c19b74c3' visibility='default'/>
</data-member>
</class-decl>
<qualified-type-def type-id='d6618c78' const='yes' id='81a65028'/>
<pointer-type-def type-id='81a65028' size-in-bits='64' id='1acff326'/>
<qualified-type-def type-id='3eee3342' const='yes' id='0c1d5bbb'/>
<pointer-type-def type-id='0c1d5bbb' size-in-bits='64' id='a3372543'/>
<pointer-type-def type-id='d6618c78' size-in-bits='64' id='a8425263'/>
<var-decl name='spa_feature_table' type-id='d96379d0' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
@ -1978,6 +1988,7 @@
<function-decl name='zfs_mod_supported' mangled-name='zfs_mod_supported' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_mod_supported'>
<parameter type-id='80f4b756' name='scope'/>
<parameter type-id='80f4b756' name='name'/>
<parameter type-id='a3372543' name='sfeatures'/>
<return type-id='c19b74c3'/>
</function-decl>
<function-decl name='zpool_feature_init' mangled-name='zpool_feature_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_feature_init'>
@ -2793,6 +2804,7 @@
<parameter type-id='c19b74c3' name='rightalign'/>
<parameter type-id='c19b74c3' name='visible'/>
<parameter type-id='c8bc397b' name='idx_tbl'/>
<parameter type-id='a3372543' name='sfeatures'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zprop_register_string' mangled-name='zprop_register_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_string'>
@ -2803,6 +2815,7 @@
<parameter type-id='95e97e5e' name='objset_types'/>
<parameter type-id='80f4b756' name='values'/>
<parameter type-id='80f4b756' name='colname'/>
<parameter type-id='a3372543' name='sfeatures'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zprop_register_number' mangled-name='zprop_register_number' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_number'>
@ -2813,6 +2826,7 @@
<parameter type-id='95e97e5e' name='objset_types'/>
<parameter type-id='80f4b756' name='values'/>
<parameter type-id='80f4b756' name='colname'/>
<parameter type-id='a3372543' name='sfeatures'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zprop_register_index' mangled-name='zprop_register_index' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_index'>
@ -2824,6 +2838,7 @@
<parameter type-id='80f4b756' name='values'/>
<parameter type-id='80f4b756' name='colname'/>
<parameter type-id='c8bc397b' name='idx_tbl'/>
<parameter type-id='a3372543' name='sfeatures'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zprop_register_hidden' mangled-name='zprop_register_hidden' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_hidden'>
@ -2833,6 +2848,7 @@
<parameter type-id='999701cc' name='attr'/>
<parameter type-id='95e97e5e' name='objset_types'/>
<parameter type-id='80f4b756' name='colname'/>
<parameter type-id='a3372543' name='sfeatures'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zprop_iter_common' mangled-name='zprop_iter_common' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_iter_common'>

View File

@ -32,6 +32,8 @@
#ifndef _KERNEL
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <search.h>
#include <sys/stat.h>
#endif
#include <sys/debug.h>
@ -164,30 +166,109 @@ deps_contains_feature(const spa_feature_t *deps, const spa_feature_t feature)
return (B_FALSE);
}
#define STRCMP ((int(*)(const void *, const void *))&strcmp)
struct zfs_mod_supported_features {
void *tree;
boolean_t all_features;
};
struct zfs_mod_supported_features *
zfs_mod_list_supported(const char *scope)
{
#if defined(__FreeBSD__) || defined(_KERNEL) || defined(LIB_ZPOOL_BUILD)
(void) scope;
return (NULL);
#else
struct zfs_mod_supported_features *ret = calloc(1, sizeof (*ret));
if (ret == NULL)
return (NULL);
DIR *sysfs_dir = NULL;
char path[128];
if (snprintf(path, sizeof (path), "%s/%s",
ZFS_SYSFS_DIR, scope) < sizeof (path))
sysfs_dir = opendir(path);
if (sysfs_dir == NULL && errno == ENOENT) {
if (snprintf(path, sizeof (path), "%s/%s",
ZFS_SYSFS_ALT_DIR, scope) < sizeof (path))
sysfs_dir = opendir(path);
}
if (sysfs_dir == NULL) {
ret->all_features = errno == ENOENT &&
(access(ZFS_SYSFS_DIR, F_OK) == 0 ||
access(ZFS_SYSFS_ALT_DIR, F_OK) == 0);
return (ret);
}
struct dirent *node;
while ((node = readdir(sysfs_dir)) != NULL) {
if (strcmp(node->d_name, ".") == 0 ||
strcmp(node->d_name, "..") == 0)
continue;
char *name = strdup(node->d_name);
if (name == NULL) {
goto nomem;
}
if (tsearch(name, &ret->tree, STRCMP) == NULL) {
/*
* Don't bother checking for duplicate entries:
* we're iterating a single directory.
*/
free(name);
goto nomem;
}
}
end:
closedir(sysfs_dir);
return (ret);
nomem:
zfs_mod_list_supported_free(ret);
ret = NULL;
goto end;
#endif
}
void
zfs_mod_list_supported_free(struct zfs_mod_supported_features *list)
{
#if !defined(__FreeBSD__) && !defined(_KERNEL) && !defined(LIB_ZPOOL_BUILD)
if (list) {
tdestroy(list->tree, free);
free(list);
}
#else
(void) list;
#endif
}
#if !defined(_KERNEL) && !defined(LIB_ZPOOL_BUILD)
static boolean_t
zfs_mod_supported_impl(const char *scope, const char *name, const char *sysfs)
{
boolean_t supported = B_FALSE;
char *path;
int len = asprintf(&path, "%s%s%s%s%s", sysfs,
scope == NULL ? "" : "/", scope == NULL ? "" : scope,
name == NULL ? "" : "/", name == NULL ? "" : name);
if (len > 0) {
struct stat64 statbuf;
supported = !!(stat64(path, &statbuf) == 0);
free(path);
}
return (supported);
char path[128];
if (snprintf(path, sizeof (path), "%s%s%s%s%s", sysfs,
scope == NULL ? "" : "/", scope ?: "",
name == NULL ? "" : "/", name ?: "") < sizeof (path))
return (access(path, F_OK) == 0);
else
return (B_FALSE);
}
boolean_t
zfs_mod_supported(const char *scope, const char *name)
zfs_mod_supported(const char *scope, const char *name,
const struct zfs_mod_supported_features *sfeatures)
{
boolean_t supported;
if (sfeatures != NULL)
return (sfeatures->all_features ||
tfind(name, &sfeatures->tree, STRCMP));
/*
* Check both the primary and alternate sysfs locations to determine
* if the required functionality is supported.
@ -202,10 +283,10 @@ zfs_mod_supported(const char *scope, const char *name)
* scope directory does not exist.
*/
if (supported == B_FALSE) {
struct stat64 statbuf;
if ((stat64(ZFS_SYSFS_DIR, &statbuf) == 0) &&
!zfs_mod_supported_impl(scope, NULL, ZFS_SYSFS_DIR) &&
!zfs_mod_supported_impl(scope, NULL, ZFS_SYSFS_ALT_DIR)) {
if ((access(ZFS_SYSFS_DIR, F_OK) == 0 &&
!zfs_mod_supported_impl(scope, NULL, ZFS_SYSFS_DIR)) ||
(access(ZFS_SYSFS_ALT_DIR, F_OK) == 0 &&
!zfs_mod_supported_impl(scope, NULL, ZFS_SYSFS_ALT_DIR))) {
supported = B_TRUE;
}
}
@ -215,7 +296,8 @@ zfs_mod_supported(const char *scope, const char *name)
#endif
static boolean_t
zfs_mod_supported_feature(const char *name)
zfs_mod_supported_feature(const char *name,
const struct zfs_mod_supported_features *sfeatures)
{
/*
* The zfs module spa_feature_table[], whether in-kernel or in
@ -229,17 +311,18 @@ zfs_mod_supported_feature(const char *name)
*/
#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) || defined(__FreeBSD__)
(void) name;
(void) name, (void) sfeatures;
return (B_TRUE);
#else
return (zfs_mod_supported(ZFS_SYSFS_POOL_FEATURES, name));
return (zfs_mod_supported(ZFS_SYSFS_POOL_FEATURES, name, sfeatures));
#endif
}
static void
zfeature_register(spa_feature_t fid, const char *guid, const char *name,
const char *desc, zfeature_flags_t flags, zfeature_type_t type,
const spa_feature_t *deps)
const spa_feature_t *deps,
const struct zfs_mod_supported_features *sfeatures)
{
zfeature_info_t *feature = &spa_feature_table[fid];
static spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
@ -264,7 +347,8 @@ zfeature_register(spa_feature_t fid, const char *guid, const char *name,
feature->fi_flags = flags;
feature->fi_type = type;
feature->fi_depends = deps;
feature->fi_zfs_mod_supported = zfs_mod_supported_feature(guid);
feature->fi_zfs_mod_supported =
zfs_mod_supported_feature(guid, sfeatures);
}
/*
@ -283,318 +367,335 @@ zfeature_register(spa_feature_t fid, const char *guid, const char *name,
void
zpool_feature_init(void)
{
struct zfs_mod_supported_features *sfeatures =
zfs_mod_list_supported(ZFS_SYSFS_POOL_FEATURES);
zfeature_register(SPA_FEATURE_ASYNC_DESTROY,
"com.delphix:async_destroy", "async_destroy",
"Destroy filesystems asynchronously.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
zfeature_register(SPA_FEATURE_EMPTY_BPOBJ,
"com.delphix:empty_bpobj", "empty_bpobj",
"Snapshots use less space.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
"org.illumos:lz4_compress", "lz4_compress",
"LZ4 compression algorithm support.",
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
zfeature_register(SPA_FEATURE_MULTI_VDEV_CRASH_DUMP,
"com.joyent:multi_vdev_crash_dump", "multi_vdev_crash_dump",
"Crash dumps to multiple vdev pools.",
0, ZFEATURE_TYPE_BOOLEAN, NULL);
0, ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM,
"com.delphix:spacemap_histogram", "spacemap_histogram",
"Spacemaps maintain space histograms.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
zfeature_register(SPA_FEATURE_ENABLED_TXG,
"com.delphix:enabled_txg", "enabled_txg",
"Record txg at which a feature is enabled",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
{
static const spa_feature_t hole_birth_deps[] = {
SPA_FEATURE_ENABLED_TXG,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_HOLE_BIRTH,
"com.delphix:hole_birth", "hole_birth",
"Retain hole birth txg for more precise zfs send",
ZFEATURE_FLAG_MOS | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE,
ZFEATURE_TYPE_BOOLEAN, hole_birth_deps);
static const spa_feature_t hole_birth_deps[] = {
SPA_FEATURE_ENABLED_TXG,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_HOLE_BIRTH,
"com.delphix:hole_birth", "hole_birth",
"Retain hole birth txg for more precise zfs send",
ZFEATURE_FLAG_MOS | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE,
ZFEATURE_TYPE_BOOLEAN, hole_birth_deps, sfeatures);
}
zfeature_register(SPA_FEATURE_POOL_CHECKPOINT,
"com.delphix:zpool_checkpoint", "zpool_checkpoint",
"Pool state can be checkpointed, allowing rewind later.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
zfeature_register(SPA_FEATURE_SPACEMAP_V2,
"com.delphix:spacemap_v2", "spacemap_v2",
"Space maps representing large segments are more efficient.",
ZFEATURE_FLAG_READONLY_COMPAT | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE,
ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
zfeature_register(SPA_FEATURE_EXTENSIBLE_DATASET,
"com.delphix:extensible_dataset", "extensible_dataset",
"Enhanced dataset functionality, used by other features.",
0, ZFEATURE_TYPE_BOOLEAN, NULL);
0, ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
{
static const spa_feature_t bookmarks_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
static const spa_feature_t bookmarks_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_BOOKMARKS,
"com.delphix:bookmarks", "bookmarks",
"\"zfs bookmark\" command",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
bookmarks_deps);
zfeature_register(SPA_FEATURE_BOOKMARKS,
"com.delphix:bookmarks", "bookmarks",
"\"zfs bookmark\" command",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
bookmarks_deps, sfeatures);
}
{
static const spa_feature_t filesystem_limits_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_FS_SS_LIMIT,
"com.joyent:filesystem_limits", "filesystem_limits",
"Filesystem and snapshot limits.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
filesystem_limits_deps);
static const spa_feature_t filesystem_limits_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_FS_SS_LIMIT,
"com.joyent:filesystem_limits", "filesystem_limits",
"Filesystem and snapshot limits.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
filesystem_limits_deps, sfeatures);
}
zfeature_register(SPA_FEATURE_EMBEDDED_DATA,
"com.delphix:embedded_data", "embedded_data",
"Blocks which compress very well use even less space.",
ZFEATURE_FLAG_MOS | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE,
ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
{
static const spa_feature_t livelist_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LIVELIST,
"com.delphix:livelist", "livelist",
"Improved clone deletion performance.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
livelist_deps);
static const spa_feature_t livelist_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LIVELIST,
"com.delphix:livelist", "livelist",
"Improved clone deletion performance.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
livelist_deps, sfeatures);
}
{
static const spa_feature_t log_spacemap_deps[] = {
SPA_FEATURE_SPACEMAP_V2,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LOG_SPACEMAP,
"com.delphix:log_spacemap", "log_spacemap",
"Log metaslab changes on a single spacemap and "
"flush them periodically.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
log_spacemap_deps);
static const spa_feature_t log_spacemap_deps[] = {
SPA_FEATURE_SPACEMAP_V2,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LOG_SPACEMAP,
"com.delphix:log_spacemap", "log_spacemap",
"Log metaslab changes on a single spacemap and "
"flush them periodically.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
log_spacemap_deps, sfeatures);
}
{
static const spa_feature_t large_blocks_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LARGE_BLOCKS,
"org.open-zfs:large_blocks", "large_blocks",
"Support for blocks larger than 128KB.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
large_blocks_deps);
static const spa_feature_t large_blocks_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LARGE_BLOCKS,
"org.open-zfs:large_blocks", "large_blocks",
"Support for blocks larger than 128KB.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
large_blocks_deps, sfeatures);
}
{
static const spa_feature_t large_dnode_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LARGE_DNODE,
"org.zfsonlinux:large_dnode", "large_dnode",
"Variable on-disk size of dnodes.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
large_dnode_deps);
static const spa_feature_t large_dnode_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_LARGE_DNODE,
"org.zfsonlinux:large_dnode", "large_dnode",
"Variable on-disk size of dnodes.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
large_dnode_deps, sfeatures);
}
{
static const spa_feature_t sha512_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_SHA512,
"org.illumos:sha512", "sha512",
"SHA-512/256 hash algorithm.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
sha512_deps);
static const spa_feature_t sha512_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_SHA512,
"org.illumos:sha512", "sha512",
"SHA-512/256 hash algorithm.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
sha512_deps, sfeatures);
}
{
static const spa_feature_t skein_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_SKEIN,
"org.illumos:skein", "skein",
"Skein hash algorithm.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
skein_deps);
static const spa_feature_t skein_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_SKEIN,
"org.illumos:skein", "skein",
"Skein hash algorithm.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
skein_deps, sfeatures);
}
{
static const spa_feature_t edonr_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_EDONR,
"org.illumos:edonr", "edonr",
"Edon-R hash algorithm.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
edonr_deps);
static const spa_feature_t edonr_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_EDONR,
"org.illumos:edonr", "edonr",
"Edon-R hash algorithm.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
edonr_deps, sfeatures);
}
{
static const spa_feature_t redact_books_deps[] = {
SPA_FEATURE_BOOKMARK_V2,
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARKS,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_REDACTION_BOOKMARKS,
"com.delphix:redaction_bookmarks", "redaction_bookmarks",
"Support for bookmarks which store redaction lists for zfs "
"redacted send/recv.", 0, ZFEATURE_TYPE_BOOLEAN,
redact_books_deps);
static const spa_feature_t redact_books_deps[] = {
SPA_FEATURE_BOOKMARK_V2,
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARKS,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_REDACTION_BOOKMARKS,
"com.delphix:redaction_bookmarks", "redaction_bookmarks",
"Support for bookmarks which store redaction lists for zfs "
"redacted send/recv.", 0, ZFEATURE_TYPE_BOOLEAN,
redact_books_deps, sfeatures);
}
{
static const spa_feature_t redact_datasets_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_REDACTED_DATASETS,
"com.delphix:redacted_datasets", "redacted_datasets", "Support for "
"redacted datasets, produced by receiving a redacted zfs send "
"stream.", ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_UINT64_ARRAY,
redact_datasets_deps);
static const spa_feature_t redact_datasets_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_REDACTED_DATASETS,
"com.delphix:redacted_datasets", "redacted_datasets",
"Support for redacted datasets, produced by receiving "
"a redacted zfs send stream.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_UINT64_ARRAY,
redact_datasets_deps, sfeatures);
}
{
static const spa_feature_t bookmark_written_deps[] = {
SPA_FEATURE_BOOKMARK_V2,
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARKS,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_BOOKMARK_WRITTEN,
"com.delphix:bookmark_written", "bookmark_written",
"Additional accounting, enabling the written#<bookmark> property"
"(space written since a bookmark), and estimates of send stream "
"sizes for incrementals from bookmarks.",
0, ZFEATURE_TYPE_BOOLEAN, bookmark_written_deps);
static const spa_feature_t bookmark_written_deps[] = {
SPA_FEATURE_BOOKMARK_V2,
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARKS,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_BOOKMARK_WRITTEN,
"com.delphix:bookmark_written", "bookmark_written",
"Additional accounting, enabling the written#<bookmark> "
"property (space written since a bookmark), "
"and estimates of send stream sizes for incrementals from "
"bookmarks.",
0, ZFEATURE_TYPE_BOOLEAN, bookmark_written_deps, sfeatures);
}
zfeature_register(SPA_FEATURE_DEVICE_REMOVAL,
"com.delphix:device_removal", "device_removal",
"Top-level vdevs can be removed, reducing logical pool size.",
ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
{
static const spa_feature_t obsolete_counts_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_DEVICE_REMOVAL,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_OBSOLETE_COUNTS,
"com.delphix:obsolete_counts", "obsolete_counts",
"Reduce memory used by removed devices when their blocks are "
"freed or remapped.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
obsolete_counts_deps);
static const spa_feature_t obsolete_counts_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_DEVICE_REMOVAL,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_OBSOLETE_COUNTS,
"com.delphix:obsolete_counts", "obsolete_counts",
"Reduce memory used by removed devices when their blocks "
"are freed or remapped.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN,
obsolete_counts_deps, sfeatures);
}
{
static const spa_feature_t userobj_accounting_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_USEROBJ_ACCOUNTING,
"org.zfsonlinux:userobj_accounting", "userobj_accounting",
"User/Group object accounting.",
ZFEATURE_FLAG_READONLY_COMPAT | ZFEATURE_FLAG_PER_DATASET,
ZFEATURE_TYPE_BOOLEAN, userobj_accounting_deps);
static const spa_feature_t userobj_accounting_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_USEROBJ_ACCOUNTING,
"org.zfsonlinux:userobj_accounting", "userobj_accounting",
"User/Group object accounting.",
ZFEATURE_FLAG_READONLY_COMPAT | ZFEATURE_FLAG_PER_DATASET,
ZFEATURE_TYPE_BOOLEAN, userobj_accounting_deps, sfeatures);
}
{
static const spa_feature_t bookmark_v2_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARKS,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_BOOKMARK_V2,
"com.datto:bookmark_v2", "bookmark_v2",
"Support for larger bookmarks",
0, ZFEATURE_TYPE_BOOLEAN, bookmark_v2_deps);
static const spa_feature_t bookmark_v2_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARKS,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_BOOKMARK_V2,
"com.datto:bookmark_v2", "bookmark_v2",
"Support for larger bookmarks",
0, ZFEATURE_TYPE_BOOLEAN, bookmark_v2_deps, sfeatures);
}
{
static const spa_feature_t encryption_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARK_V2,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_ENCRYPTION,
"com.datto:encryption", "encryption",
"Support for dataset level encryption",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
encryption_deps);
static const spa_feature_t encryption_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_BOOKMARK_V2,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_ENCRYPTION,
"com.datto:encryption", "encryption",
"Support for dataset level encryption",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN,
encryption_deps, sfeatures);
}
{
static const spa_feature_t project_quota_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_PROJECT_QUOTA,
"org.zfsonlinux:project_quota", "project_quota",
"space/object accounting based on project ID.",
ZFEATURE_FLAG_READONLY_COMPAT | ZFEATURE_FLAG_PER_DATASET,
ZFEATURE_TYPE_BOOLEAN, project_quota_deps);
static const spa_feature_t project_quota_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_PROJECT_QUOTA,
"org.zfsonlinux:project_quota", "project_quota",
"space/object accounting based on project ID.",
ZFEATURE_FLAG_READONLY_COMPAT | ZFEATURE_FLAG_PER_DATASET,
ZFEATURE_TYPE_BOOLEAN, project_quota_deps, sfeatures);
}
zfeature_register(SPA_FEATURE_ALLOCATION_CLASSES,
"org.zfsonlinux:allocation_classes", "allocation_classes",
"Support for separate allocation classes.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
zfeature_register(SPA_FEATURE_RESILVER_DEFER,
"com.datto:resilver_defer", "resilver_defer",
"Support for deferring new resilvers when one is already running.",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
zfeature_register(SPA_FEATURE_DEVICE_REBUILD,
"org.openzfs:device_rebuild", "device_rebuild",
"Support for sequential mirror/dRAID device rebuilds",
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
{
static const spa_feature_t zstd_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_ZSTD_COMPRESS,
"org.freebsd:zstd_compress", "zstd_compress",
"zstd compression algorithm support.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN, zstd_deps);
static const spa_feature_t zstd_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_ZSTD_COMPRESS,
"org.freebsd:zstd_compress", "zstd_compress",
"zstd compression algorithm support.",
ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN, zstd_deps,
sfeatures);
}
zfeature_register(SPA_FEATURE_DRAID,
"org.openzfs:draid", "draid", "Support for distributed spare RAID",
ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL);
ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
zfs_mod_list_supported_free(sfeatures);
}
#if defined(_KERNEL)

View File

@ -377,44 +377,47 @@ zfs_prop_init(void)
{ NULL }
};
struct zfs_mod_supported_features *sfeatures =
zfs_mod_list_supported(ZFS_SYSFS_DATASET_PROPERTIES);
/* inherit index properties */
zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata",
ZFS_REDUNDANT_METADATA_ALL,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"all | most", "REDUND_MD",
redundant_metadata_table);
redundant_metadata_table, sfeatures);
zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"standard | always | disabled", "SYNC",
sync_table);
sync_table, sfeatures);
zprop_register_index(ZFS_PROP_CHECKSUM, "checksum",
ZIO_CHECKSUM_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM |
ZFS_TYPE_VOLUME,
"on | off | fletcher2 | fletcher4 | sha256 | sha512 | skein"
" | edonr",
"CHECKSUM", checksum_table);
"CHECKSUM", checksum_table, sfeatures);
zprop_register_index(ZFS_PROP_DEDUP, "dedup", ZIO_CHECKSUM_OFF,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"on | off | verify | sha256[,verify] | sha512[,verify] | "
"skein[,verify] | edonr,verify",
"DEDUP", dedup_table);
"DEDUP", dedup_table, sfeatures);
zprop_register_index(ZFS_PROP_COMPRESSION, "compression",
ZIO_COMPRESS_DEFAULT, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"on | off | lzjb | gzip | gzip-[1-9] | zle | lz4 | "
"zstd | zstd-[1-19] | "
"zstd-fast | zstd-fast-[1-10,20,30,40,50,60,70,80,90,100,500,1000]",
"COMPRESS", compress_table);
"COMPRESS", compress_table, sfeatures);
zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"hidden | visible", "SNAPDIR", snapdir_table);
"hidden | visible", "SNAPDIR", snapdir_table, sfeatures);
zprop_register_index(ZFS_PROP_SNAPDEV, "snapdev", ZFS_SNAPDEV_HIDDEN,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"hidden | visible", "SNAPDEV", snapdev_table);
"hidden | visible", "SNAPDEV", snapdev_table, sfeatures);
zprop_register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_DISCARD,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"discard | groupmask | passthrough | restricted", "ACLMODE",
acl_mode_table);
acl_mode_table, sfeatures);
zprop_register_index(ZFS_PROP_ACLTYPE, "acltype",
#ifdef __linux__
/* Linux doesn't natively support ZFS's NFSv4-style ACLs. */
@ -423,270 +426,288 @@ zfs_prop_init(void)
ZFS_ACLTYPE_NFSV4,
#endif
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"off | nfsv4 | posix", "ACLTYPE", acltype_table);
"off | nfsv4 | posix", "ACLTYPE", acltype_table, sfeatures);
zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"discard | noallow | restricted | passthrough | passthrough-x",
"ACLINHERIT", acl_inherit_table);
"ACLINHERIT", acl_inherit_table, sfeatures);
zprop_register_index(ZFS_PROP_COPIES, "copies", 1, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"1 | 2 | 3", "COPIES", copies_table);
"1 | 2 | 3", "COPIES", copies_table, sfeatures);
zprop_register_index(ZFS_PROP_PRIMARYCACHE, "primarycache",
ZFS_CACHE_ALL, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
"all | none | metadata", "PRIMARYCACHE", cache_table);
"all | none | metadata", "PRIMARYCACHE", cache_table, sfeatures);
zprop_register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache",
ZFS_CACHE_ALL, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
"all | none | metadata", "SECONDARYCACHE", cache_table);
"all | none | metadata", "SECONDARYCACHE", cache_table, sfeatures);
zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"latency | throughput", "LOGBIAS", logbias_table);
"latency | throughput", "LOGBIAS", logbias_table, sfeatures);
zprop_register_index(ZFS_PROP_XATTR, "xattr", ZFS_XATTR_DIR,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"on | off | dir | sa", "XATTR", xattr_table);
"on | off | dir | sa", "XATTR", xattr_table, sfeatures);
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);
"legacy | auto | 1k | 2k | 4k | 8k | 16k", "DNSIZE", dnsize_table,
sfeatures);
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);
"default | full | geom | dev | none", "VOLMODE", volmode_table,
sfeatures);
/* inherit index (boolean) properties */
zprop_register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table);
ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table, sfeatures);
zprop_register_index(ZFS_PROP_RELATIME, "relatime", 0, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM, "on | off", "RELATIME", boolean_table);
ZFS_TYPE_FILESYSTEM, "on | off", "RELATIME", boolean_table,
sfeatures);
zprop_register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY",
boolean_table);
boolean_table, sfeatures);
#ifdef __FreeBSD__
zprop_register_index(ZFS_PROP_ZONED, "jailed", 0, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM, "on | off", "JAILED", boolean_table);
ZFS_TYPE_FILESYSTEM, "on | off", "JAILED", boolean_table,
sfeatures);
#else
zprop_register_index(ZFS_PROP_ZONED, "zoned", 0, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM, "on | off", "ZONED", boolean_table);
ZFS_TYPE_FILESYSTEM, "on | off", "ZONED", boolean_table, sfeatures);
#endif
zprop_register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN", boolean_table);
ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN", boolean_table, sfeatures);
zprop_register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "NBMAND",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(ZFS_PROP_OVERLAY, "overlay", 1, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM, "on | off", "OVERLAY", boolean_table);
ZFS_TYPE_FILESYSTEM, "on | off", "OVERLAY", boolean_table,
sfeatures);
/* default index properties */
zprop_register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"1 | 2 | 3 | 4 | 5 | current", "VERSION", version_table);
"1 | 2 | 3 | 4 | 5 | current", "VERSION", version_table, sfeatures);
zprop_register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON,
PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto",
"CANMOUNT", canmount_table);
"CANMOUNT", canmount_table, sfeatures);
/* readonly index properties */
zprop_register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table);
ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table,
sfeatures);
zprop_register_index(ZFS_PROP_DEFER_DESTROY, "defer_destroy", 0,
PROP_READONLY, ZFS_TYPE_SNAPSHOT, "yes | no", "DEFER_DESTROY",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(ZFS_PROP_KEYSTATUS, "keystatus",
ZFS_KEYSTATUS_NONE, PROP_READONLY, ZFS_TYPE_DATASET,
"none | unavailable | available",
"KEYSTATUS", keystatus_table);
"KEYSTATUS", keystatus_table, sfeatures);
/* set once index properties */
zprop_register_index(ZFS_PROP_NORMALIZE, "normalization", 0,
PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"none | formC | formD | formKC | formKD", "NORMALIZATION",
normalize_table);
normalize_table, sfeatures);
zprop_register_index(ZFS_PROP_CASE, "casesensitivity",
ZFS_CASE_SENSITIVE, PROP_ONETIME, ZFS_TYPE_FILESYSTEM |
ZFS_TYPE_SNAPSHOT,
"sensitive | insensitive | mixed", "CASE", case_table);
"sensitive | insensitive | mixed", "CASE", case_table, sfeatures);
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);
"none | raw | hex | passphrase", "KEYFORMAT", keyformat_table,
sfeatures);
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);
crypto_table, sfeatures);
/* set once index (boolean) properties */
zprop_register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"on | off", "UTF8ONLY", boolean_table);
"on | off", "UTF8ONLY", boolean_table, sfeatures);
/* string properties */
zprop_register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN",
sfeatures);
zprop_register_string(ZFS_PROP_CLONES, "clones", NULL, PROP_READONLY,
ZFS_TYPE_SNAPSHOT, "<dataset>[,...]", "CLONES");
ZFS_TYPE_SNAPSHOT, "<dataset>[,...]", "CLONES", sfeatures);
zprop_register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/",
PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "<path> | legacy | none",
"MOUNTPOINT");
"MOUNTPOINT", sfeatures);
zprop_register_string(ZFS_PROP_SHARENFS, "sharenfs", "off",
PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off | NFS share options",
"SHARENFS");
"SHARENFS", sfeatures);
zprop_register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY,
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK,
"filesystem | volume | snapshot | bookmark", "TYPE");
"filesystem | volume | snapshot | bookmark", "TYPE", sfeatures);
zprop_register_string(ZFS_PROP_SHARESMB, "sharesmb", "off",
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"on | off | SMB share options", "SHARESMB");
"on | off | SMB share options", "SHARESMB", sfeatures);
zprop_register_string(ZFS_PROP_MLSLABEL, "mlslabel",
ZFS_MLSLABEL_DEFAULT, PROP_INHERIT, ZFS_TYPE_DATASET,
"<sensitivity label>", "MLSLABEL");
"<sensitivity label>", "MLSLABEL", sfeatures);
zprop_register_string(ZFS_PROP_SELINUX_CONTEXT, "context",
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux context>",
"CONTEXT");
"CONTEXT", sfeatures);
zprop_register_string(ZFS_PROP_SELINUX_FSCONTEXT, "fscontext",
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux fscontext>",
"FSCONTEXT");
"FSCONTEXT", sfeatures);
zprop_register_string(ZFS_PROP_SELINUX_DEFCONTEXT, "defcontext",
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux defcontext>",
"DEFCONTEXT");
"DEFCONTEXT", sfeatures);
zprop_register_string(ZFS_PROP_SELINUX_ROOTCONTEXT, "rootcontext",
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux rootcontext>",
"ROOTCONTEXT");
"ROOTCONTEXT", sfeatures);
zprop_register_string(ZFS_PROP_RECEIVE_RESUME_TOKEN,
"receive_resume_token",
NULL, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<string token>", "RESUMETOK");
"<string token>", "RESUMETOK", sfeatures);
zprop_register_string(ZFS_PROP_ENCRYPTION_ROOT, "encryptionroot", NULL,
PROP_READONLY, ZFS_TYPE_DATASET, "<filesystem | volume>",
"ENCROOT");
"ENCROOT", sfeatures);
zprop_register_string(ZFS_PROP_KEYLOCATION, "keylocation",
"none", PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"prompt | <file URI> | <https URL> | <http URL>", "KEYLOCATION");
"prompt | <file URI> | <https URL> | <http URL>", "KEYLOCATION",
sfeatures);
zprop_register_string(ZFS_PROP_REDACT_SNAPS,
"redact_snaps", NULL, PROP_READONLY,
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<snapshot>[,...]",
"RSNAPS");
"RSNAPS", sfeatures);
/* readonly number properties */
zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
ZFS_TYPE_DATASET, "<size>", "USED");
ZFS_TYPE_DATASET, "<size>", "USED", sfeatures);
zprop_register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL");
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL",
sfeatures);
zprop_register_number(ZFS_PROP_REFERENCED, "referenced", 0,
PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<size>",
"REFER");
"REFER", sfeatures);
zprop_register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK,
"<1.00x or higher if compressed>", "RATIO");
"<1.00x or higher if compressed>", "RATIO", sfeatures);
zprop_register_number(ZFS_PROP_REFRATIO, "refcompressratio", 0,
PROP_READONLY, ZFS_TYPE_DATASET,
"<1.00x or higher if compressed>", "REFRATIO");
"<1.00x or higher if compressed>", "REFRATIO", sfeatures);
zprop_register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize",
ZVOL_DEFAULT_BLOCKSIZE, PROP_ONETIME,
ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK");
ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK", sfeatures);
zprop_register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0,
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
"USEDSNAP");
"USEDSNAP", sfeatures);
zprop_register_number(ZFS_PROP_USEDDS, "usedbydataset", 0,
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
"USEDDS");
"USEDDS", sfeatures);
zprop_register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0,
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
"USEDCHILD");
"USEDCHILD", sfeatures);
zprop_register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0,
PROP_READONLY,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV");
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV",
sfeatures);
zprop_register_number(ZFS_PROP_USERREFS, "userrefs", 0, PROP_READONLY,
ZFS_TYPE_SNAPSHOT, "<count>", "USERREFS");
ZFS_TYPE_SNAPSHOT, "<count>", "USERREFS", sfeatures);
zprop_register_number(ZFS_PROP_WRITTEN, "written", 0, PROP_READONLY,
ZFS_TYPE_DATASET, "<size>", "WRITTEN");
ZFS_TYPE_DATASET, "<size>", "WRITTEN", sfeatures);
zprop_register_number(ZFS_PROP_LOGICALUSED, "logicalused", 0,
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
"LUSED");
"LUSED", sfeatures);
zprop_register_number(ZFS_PROP_LOGICALREFERENCED, "logicalreferenced",
0, PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<size>",
"LREFER");
"LREFER", sfeatures);
zprop_register_number(ZFS_PROP_FILESYSTEM_COUNT, "filesystem_count",
UINT64_MAX, PROP_READONLY, ZFS_TYPE_FILESYSTEM,
"<count>", "FSCOUNT");
"<count>", "FSCOUNT", sfeatures);
zprop_register_number(ZFS_PROP_SNAPSHOT_COUNT, "snapshot_count",
UINT64_MAX, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<count>", "SSCOUNT");
"<count>", "SSCOUNT", sfeatures);
zprop_register_number(ZFS_PROP_GUID, "guid", 0, PROP_READONLY,
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "GUID");
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "GUID",
sfeatures);
zprop_register_number(ZFS_PROP_CREATETXG, "createtxg", 0, PROP_READONLY,
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "CREATETXG");
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "CREATETXG",
sfeatures);
zprop_register_number(ZFS_PROP_PBKDF2_ITERS, "pbkdf2iters",
0, PROP_ONETIME_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<iters>", "PBKDF2ITERS");
"<iters>", "PBKDF2ITERS", sfeatures);
zprop_register_number(ZFS_PROP_OBJSETID, "objsetid", 0,
PROP_READONLY, ZFS_TYPE_DATASET, "<uint64>", "OBJSETID");
PROP_READONLY, ZFS_TYPE_DATASET, "<uint64>", "OBJSETID", sfeatures);
/* default number properties */
zprop_register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA", sfeatures);
zprop_register_number(ZFS_PROP_RESERVATION, "reservation", 0,
PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<size> | none", "RESERV");
"<size> | none", "RESERV", sfeatures);
zprop_register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, "<size>", "VOLSIZE",
sfeatures);
zprop_register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT,
ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA");
ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA", sfeatures);
zprop_register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0,
PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<size> | none", "REFRESERV");
"<size> | none", "REFRESERV", sfeatures);
zprop_register_number(ZFS_PROP_FILESYSTEM_LIMIT, "filesystem_limit",
UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
"<count> | none", "FSLIMIT");
"<count> | none", "FSLIMIT", sfeatures);
zprop_register_number(ZFS_PROP_SNAPSHOT_LIMIT, "snapshot_limit",
UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<count> | none", "SSLIMIT");
"<count> | none", "SSLIMIT", sfeatures);
/* inherit number properties */
zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize",
SPA_OLD_MAXBLOCKSIZE, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM, "512 to 1M, power of 2", "RECSIZE");
ZFS_TYPE_FILESYSTEM, "512 to 1M, power of 2", "RECSIZE", sfeatures);
zprop_register_number(ZFS_PROP_SPECIAL_SMALL_BLOCKS,
"special_small_blocks", 0, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"zero or 512 to 1M, power of 2", "SPECIAL_SMALL_BLOCKS");
"zero or 512 to 1M, power of 2", "SPECIAL_SMALL_BLOCKS", sfeatures);
/* hidden properties */
zprop_register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
PROP_READONLY, ZFS_TYPE_SNAPSHOT, "NUMCLONES");
PROP_READONLY, ZFS_TYPE_SNAPSHOT, "NUMCLONES", sfeatures);
zprop_register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "NAME");
PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "NAME",
sfeatures);
zprop_register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions",
PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS");
PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS",
sfeatures);
zprop_register_hidden(ZFS_PROP_STMF_SHAREINFO, "stmf_sbd_lu",
PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME,
"STMF_SBD_LU");
"STMF_SBD_LU", sfeatures);
zprop_register_hidden(ZFS_PROP_USERACCOUNTING, "useraccounting",
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET,
"USERACCOUNTING");
"USERACCOUNTING", sfeatures);
zprop_register_hidden(ZFS_PROP_UNIQUE, "unique", PROP_TYPE_NUMBER,
PROP_READONLY, ZFS_TYPE_DATASET, "UNIQUE");
PROP_READONLY, ZFS_TYPE_DATASET, "UNIQUE", sfeatures);
zprop_register_hidden(ZFS_PROP_INCONSISTENT, "inconsistent",
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT");
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT",
sfeatures);
zprop_register_hidden(ZFS_PROP_IVSET_GUID, "ivsetguid",
PROP_TYPE_NUMBER, PROP_READONLY,
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "IVSETGUID");
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "IVSETGUID", sfeatures);
zprop_register_hidden(ZFS_PROP_PREV_SNAP, "prevsnap", PROP_TYPE_STRING,
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PREVSNAP");
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PREVSNAP",
sfeatures);
zprop_register_hidden(ZFS_PROP_PBKDF2_SALT, "pbkdf2salt",
PROP_TYPE_NUMBER, PROP_ONETIME_DEFAULT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PBKDF2SALT");
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PBKDF2SALT", sfeatures);
zprop_register_hidden(ZFS_PROP_KEY_GUID, "keyguid", PROP_TYPE_NUMBER,
PROP_READONLY, ZFS_TYPE_DATASET, "KEYGUID");
PROP_READONLY, ZFS_TYPE_DATASET, "KEYGUID", sfeatures);
zprop_register_hidden(ZFS_PROP_REDACTED, "redacted", PROP_TYPE_NUMBER,
PROP_READONLY, ZFS_TYPE_DATASET, "REDACTED");
PROP_READONLY, ZFS_TYPE_DATASET, "REDACTED", sfeatures);
/*
* Properties that are obsolete and not used. These are retained so
@ -694,12 +715,14 @@ zfs_prop_init(void)
* have NULL pointers in the zfs_prop_table[].
*/
zprop_register_hidden(ZFS_PROP_REMAPTXG, "remaptxg", PROP_TYPE_NUMBER,
PROP_READONLY, ZFS_TYPE_DATASET, "REMAPTXG");
PROP_READONLY, ZFS_TYPE_DATASET, "REMAPTXG", sfeatures);
/* oddball properties */
zprop_register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0,
NULL, PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK,
"<date>", "CREATION", B_FALSE, B_TRUE, NULL);
"<date>", "CREATION", B_FALSE, B_TRUE, NULL, sfeatures);
zfs_mod_list_supported_free(sfeatures);
}
boolean_t

View File

@ -65,90 +65,105 @@ zpool_prop_init(void)
{ NULL }
};
struct zfs_mod_supported_features *sfeatures =
zfs_mod_list_supported(ZFS_SYSFS_POOL_PROPERTIES);
/* string properties */
zprop_register_string(ZPOOL_PROP_ALTROOT, "altroot", NULL, PROP_DEFAULT,
ZFS_TYPE_POOL, "<path>", "ALTROOT");
ZFS_TYPE_POOL, "<path>", "ALTROOT", sfeatures);
zprop_register_string(ZPOOL_PROP_BOOTFS, "bootfs", NULL, PROP_DEFAULT,
ZFS_TYPE_POOL, "<filesystem>", "BOOTFS");
ZFS_TYPE_POOL, "<filesystem>", "BOOTFS", sfeatures);
zprop_register_string(ZPOOL_PROP_CACHEFILE, "cachefile", NULL,
PROP_DEFAULT, ZFS_TYPE_POOL, "<file> | none", "CACHEFILE");
PROP_DEFAULT, ZFS_TYPE_POOL, "<file> | none", "CACHEFILE",
sfeatures);
zprop_register_string(ZPOOL_PROP_COMMENT, "comment", NULL,
PROP_DEFAULT, ZFS_TYPE_POOL, "<comment-string>", "COMMENT");
PROP_DEFAULT, ZFS_TYPE_POOL, "<comment-string>", "COMMENT",
sfeatures);
zprop_register_string(ZPOOL_PROP_COMPATIBILITY, "compatibility",
"off", PROP_DEFAULT, ZFS_TYPE_POOL,
"<file[,file...]> | off | legacy", "COMPATIBILITY");
"<file[,file...]> | off | legacy", "COMPATIBILITY", sfeatures);
/* readonly number properties */
zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<size>", "SIZE");
ZFS_TYPE_POOL, "<size>", "SIZE", sfeatures);
zprop_register_number(ZPOOL_PROP_FREE, "free", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<size>", "FREE");
ZFS_TYPE_POOL, "<size>", "FREE", sfeatures);
zprop_register_number(ZPOOL_PROP_FREEING, "freeing", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<size>", "FREEING");
ZFS_TYPE_POOL, "<size>", "FREEING", sfeatures);
zprop_register_number(ZPOOL_PROP_CHECKPOINT, "checkpoint", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "CKPOINT");
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "CKPOINT", sfeatures);
zprop_register_number(ZPOOL_PROP_LEAKED, "leaked", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<size>", "LEAKED");
ZFS_TYPE_POOL, "<size>", "LEAKED", sfeatures);
zprop_register_number(ZPOOL_PROP_ALLOCATED, "allocated", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "ALLOC");
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "ALLOC", sfeatures);
zprop_register_number(ZPOOL_PROP_EXPANDSZ, "expandsize", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "EXPANDSZ");
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "EXPANDSZ", sfeatures);
zprop_register_number(ZPOOL_PROP_FRAGMENTATION, "fragmentation", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<percent>", "FRAG");
PROP_READONLY, ZFS_TYPE_POOL, "<percent>", "FRAG", sfeatures);
zprop_register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<size>", "CAP");
ZFS_TYPE_POOL, "<size>", "CAP", sfeatures);
zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<guid>", "GUID");
ZFS_TYPE_POOL, "<guid>", "GUID", sfeatures);
zprop_register_number(ZPOOL_PROP_LOAD_GUID, "load_guid", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<load_guid>", "LOAD_GUID");
PROP_READONLY, ZFS_TYPE_POOL, "<load_guid>", "LOAD_GUID",
sfeatures);
zprop_register_number(ZPOOL_PROP_HEALTH, "health", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<state>", "HEALTH");
ZFS_TYPE_POOL, "<state>", "HEALTH", sfeatures);
zprop_register_number(ZPOOL_PROP_DEDUPRATIO, "dedupratio", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<1.00x or higher if deduped>",
"DEDUP");
"DEDUP", sfeatures);
/* default number properties */
zprop_register_number(ZPOOL_PROP_VERSION, "version", SPA_VERSION,
PROP_DEFAULT, ZFS_TYPE_POOL, "<version>", "VERSION");
PROP_DEFAULT, ZFS_TYPE_POOL, "<version>", "VERSION", sfeatures);
zprop_register_number(ZPOOL_PROP_ASHIFT, "ashift", 0, PROP_DEFAULT,
ZFS_TYPE_POOL, "<ashift, 9-16, or 0=default>", "ASHIFT");
ZFS_TYPE_POOL, "<ashift, 9-16, or 0=default>", "ASHIFT", sfeatures);
/* default index (boolean) properties */
zprop_register_index(ZPOOL_PROP_DELEGATION, "delegation", 1,
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "DELEGATION",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0,
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "REPLACE", boolean_table);
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "REPLACE", boolean_table,
sfeatures);
zprop_register_index(ZPOOL_PROP_LISTSNAPS, "listsnapshots", 0,
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "LISTSNAPS",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(ZPOOL_PROP_AUTOEXPAND, "autoexpand", 0,
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "EXPAND", boolean_table);
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "EXPAND", boolean_table,
sfeatures);
zprop_register_index(ZPOOL_PROP_READONLY, "readonly", 0,
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "RDONLY", boolean_table);
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "RDONLY", boolean_table,
sfeatures);
zprop_register_index(ZPOOL_PROP_MULTIHOST, "multihost", 0,
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "MULTIHOST",
boolean_table);
boolean_table, sfeatures);
/* default index properties */
zprop_register_index(ZPOOL_PROP_FAILUREMODE, "failmode",
ZIO_FAILURE_MODE_WAIT, PROP_DEFAULT, ZFS_TYPE_POOL,
"wait | continue | panic", "FAILMODE", failuremode_table);
"wait | continue | panic", "FAILMODE", failuremode_table,
sfeatures);
zprop_register_index(ZPOOL_PROP_AUTOTRIM, "autotrim",
SPA_AUTOTRIM_DEFAULT, PROP_DEFAULT, ZFS_TYPE_POOL,
"on | off", "AUTOTRIM", boolean_table);
"on | off", "AUTOTRIM", boolean_table, sfeatures);
/* hidden properties */
zprop_register_hidden(ZPOOL_PROP_NAME, "name", PROP_TYPE_STRING,
PROP_READONLY, ZFS_TYPE_POOL, "NAME");
PROP_READONLY, ZFS_TYPE_POOL, "NAME", sfeatures);
zprop_register_hidden(ZPOOL_PROP_MAXBLOCKSIZE, "maxblocksize",
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_POOL, "MAXBLOCKSIZE");
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_POOL, "MAXBLOCKSIZE",
sfeatures);
zprop_register_hidden(ZPOOL_PROP_TNAME, "tname", PROP_TYPE_STRING,
PROP_ONETIME, ZFS_TYPE_POOL, "TNAME");
PROP_ONETIME, ZFS_TYPE_POOL, "TNAME", sfeatures);
zprop_register_hidden(ZPOOL_PROP_MAXDNODESIZE, "maxdnodesize",
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_POOL, "MAXDNODESIZE");
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_POOL, "MAXDNODESIZE",
sfeatures);
zprop_register_hidden(ZPOOL_PROP_DEDUPDITTO, "dedupditto",
PROP_TYPE_NUMBER, PROP_DEFAULT, ZFS_TYPE_POOL, "DEDUPDITTO");
PROP_TYPE_NUMBER, PROP_DEFAULT, ZFS_TYPE_POOL, "DEDUPDITTO",
sfeatures);
zfs_mod_list_supported_free(sfeatures);
}
/*
@ -283,102 +298,110 @@ vdev_prop_init(void)
{ NULL }
};
struct zfs_mod_supported_features *sfeatures =
zfs_mod_list_supported(ZFS_SYSFS_VDEV_PROPERTIES);
/* string properties */
zprop_register_string(VDEV_PROP_COMMENT, "comment", NULL,
PROP_DEFAULT, ZFS_TYPE_VDEV, "<comment-string>", "COMMENT");
PROP_DEFAULT, ZFS_TYPE_VDEV, "<comment-string>", "COMMENT",
sfeatures);
zprop_register_string(VDEV_PROP_PATH, "path", NULL,
PROP_DEFAULT, ZFS_TYPE_VDEV, "<device-path>", "PATH");
PROP_DEFAULT, ZFS_TYPE_VDEV, "<device-path>", "PATH", sfeatures);
zprop_register_string(VDEV_PROP_DEVID, "devid", NULL,
PROP_READONLY, ZFS_TYPE_VDEV, "<devid>", "DEVID");
PROP_READONLY, ZFS_TYPE_VDEV, "<devid>", "DEVID", sfeatures);
zprop_register_string(VDEV_PROP_PHYS_PATH, "physpath", NULL,
PROP_READONLY, ZFS_TYPE_VDEV, "<physpath>", "PHYSPATH");
PROP_READONLY, ZFS_TYPE_VDEV, "<physpath>", "PHYSPATH", sfeatures);
zprop_register_string(VDEV_PROP_ENC_PATH, "encpath", NULL,
PROP_READONLY, ZFS_TYPE_VDEV, "<encpath>", "ENCPATH");
PROP_READONLY, ZFS_TYPE_VDEV, "<encpath>", "ENCPATH", sfeatures);
zprop_register_string(VDEV_PROP_FRU, "fru", NULL,
PROP_READONLY, ZFS_TYPE_VDEV, "<fru>", "FRU");
PROP_READONLY, ZFS_TYPE_VDEV, "<fru>", "FRU", sfeatures);
zprop_register_string(VDEV_PROP_PARENT, "parent", NULL,
PROP_READONLY, ZFS_TYPE_VDEV, "<parent>", "PARENT");
PROP_READONLY, ZFS_TYPE_VDEV, "<parent>", "PARENT", sfeatures);
zprop_register_string(VDEV_PROP_CHILDREN, "children", NULL,
PROP_READONLY, ZFS_TYPE_VDEV, "<child[,...]>", "CHILDREN");
PROP_READONLY, ZFS_TYPE_VDEV, "<child[,...]>", "CHILDREN",
sfeatures);
/* readonly number properties */
zprop_register_number(VDEV_PROP_SIZE, "size", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<size>", "SIZE");
ZFS_TYPE_VDEV, "<size>", "SIZE", sfeatures);
zprop_register_number(VDEV_PROP_FREE, "free", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<size>", "FREE");
ZFS_TYPE_VDEV, "<size>", "FREE", sfeatures);
zprop_register_number(VDEV_PROP_ALLOCATED, "allocated", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<size>", "ALLOC");
PROP_READONLY, ZFS_TYPE_VDEV, "<size>", "ALLOC", sfeatures);
zprop_register_number(VDEV_PROP_EXPANDSZ, "expandsize", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<size>", "EXPANDSZ");
PROP_READONLY, ZFS_TYPE_VDEV, "<size>", "EXPANDSZ", sfeatures);
zprop_register_number(VDEV_PROP_FRAGMENTATION, "fragmentation", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<percent>", "FRAG");
PROP_READONLY, ZFS_TYPE_VDEV, "<percent>", "FRAG", sfeatures);
zprop_register_number(VDEV_PROP_CAPACITY, "capacity", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<size>", "CAP");
ZFS_TYPE_VDEV, "<size>", "CAP", sfeatures);
zprop_register_number(VDEV_PROP_GUID, "guid", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<guid>", "GUID");
ZFS_TYPE_VDEV, "<guid>", "GUID", sfeatures);
zprop_register_number(VDEV_PROP_STATE, "state", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<state>", "STATE");
ZFS_TYPE_VDEV, "<state>", "STATE", sfeatures);
zprop_register_number(VDEV_PROP_BOOTSIZE, "bootsize", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<size>", "BOOTSIZE");
ZFS_TYPE_VDEV, "<size>", "BOOTSIZE", sfeatures);
zprop_register_number(VDEV_PROP_ASIZE, "asize", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<asize>", "ASIZE");
ZFS_TYPE_VDEV, "<asize>", "ASIZE", sfeatures);
zprop_register_number(VDEV_PROP_PSIZE, "psize", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<psize>", "PSIZE");
ZFS_TYPE_VDEV, "<psize>", "PSIZE", sfeatures);
zprop_register_number(VDEV_PROP_ASHIFT, "ashift", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<ashift>", "ASHIFT");
ZFS_TYPE_VDEV, "<ashift>", "ASHIFT", sfeatures);
zprop_register_number(VDEV_PROP_PARITY, "parity", 0, PROP_READONLY,
ZFS_TYPE_VDEV, "<parity>", "PARITY");
ZFS_TYPE_VDEV, "<parity>", "PARITY", sfeatures);
zprop_register_number(VDEV_PROP_NUMCHILDREN, "numchildren", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<number-of-children>", "NUMCHILD");
PROP_READONLY, ZFS_TYPE_VDEV, "<number-of-children>", "NUMCHILD",
sfeatures);
zprop_register_number(VDEV_PROP_READ_ERRORS, "read_errors", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<errors>", "RDERR");
PROP_READONLY, ZFS_TYPE_VDEV, "<errors>", "RDERR", sfeatures);
zprop_register_number(VDEV_PROP_WRITE_ERRORS, "write_errors", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<errors>", "WRERR");
PROP_READONLY, ZFS_TYPE_VDEV, "<errors>", "WRERR", sfeatures);
zprop_register_number(VDEV_PROP_CHECKSUM_ERRORS, "checksum_errors", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<errors>", "CKERR");
PROP_READONLY, ZFS_TYPE_VDEV, "<errors>", "CKERR", sfeatures);
zprop_register_number(VDEV_PROP_INITIALIZE_ERRORS,
"initialize_errors", 0, PROP_READONLY, ZFS_TYPE_VDEV, "<errors>",
"INITERR");
"INITERR", sfeatures);
zprop_register_number(VDEV_PROP_OPS_NULL, "null_ops", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "NULLOP");
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "NULLOP", sfeatures);
zprop_register_number(VDEV_PROP_OPS_READ, "read_ops", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "READOP");
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "READOP", sfeatures);
zprop_register_number(VDEV_PROP_OPS_WRITE, "write_ops", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "WRITEOP");
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "WRITEOP", sfeatures);
zprop_register_number(VDEV_PROP_OPS_FREE, "free_ops", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "FREEOP");
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "FREEOP", sfeatures);
zprop_register_number(VDEV_PROP_OPS_CLAIM, "claim_ops", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "CLAIMOP");
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "CLAIMOP", sfeatures);
zprop_register_number(VDEV_PROP_OPS_TRIM, "trim_ops", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "TRIMOP");
PROP_READONLY, ZFS_TYPE_VDEV, "<operations>", "TRIMOP", sfeatures);
zprop_register_number(VDEV_PROP_BYTES_NULL, "null_bytes", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "NULLBYTE");
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "NULLBYTE", sfeatures);
zprop_register_number(VDEV_PROP_BYTES_READ, "read_bytes", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "READBYTE");
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "READBYTE", sfeatures);
zprop_register_number(VDEV_PROP_BYTES_WRITE, "write_bytes", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "WRITEBYTE");
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "WRITEBYTE", sfeatures);
zprop_register_number(VDEV_PROP_BYTES_FREE, "free_bytes", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "FREEBYTE");
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "FREEBYTE", sfeatures);
zprop_register_number(VDEV_PROP_BYTES_CLAIM, "claim_bytes", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "CLAIMBYTE");
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "CLAIMBYTE", sfeatures);
zprop_register_number(VDEV_PROP_BYTES_TRIM, "trim_bytes", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "TRIMBYTE");
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "TRIMBYTE", sfeatures);
/* default numeric properties */
/* default index (boolean) properties */
zprop_register_index(VDEV_PROP_REMOVING, "removing", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "on | off", "REMOVING",
boolean_table);
boolean_table, sfeatures);
zprop_register_index(VDEV_PROP_ALLOCATING, "allocating", 1,
PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off", "ALLOCATING",
boolean_na_table);
boolean_na_table, sfeatures);
/* default index properties */
/* hidden properties */
zprop_register_hidden(VDEV_PROP_NAME, "name", PROP_TYPE_STRING,
PROP_READONLY, ZFS_TYPE_VDEV, "NAME");
PROP_READONLY, ZFS_TYPE_VDEV, "NAME", sfeatures);
zfs_mod_list_supported_free(sfeatures);
}
/*

View File

@ -71,7 +71,8 @@ zprop_get_numprops(zfs_type_t type)
}
static boolean_t
zfs_mod_supported_prop(const char *name, zfs_type_t type)
zfs_mod_supported_prop(const char *name, zfs_type_t type,
const struct zfs_mod_supported_features *sfeatures)
{
/*
* The zfs module spa_feature_table[], whether in-kernel or in libzpool,
@ -86,7 +87,8 @@ zfs_mod_supported_prop(const char *name, zfs_type_t type)
#else
return (zfs_mod_supported(type == ZFS_TYPE_POOL ?
ZFS_SYSFS_POOL_PROPERTIES : (type == ZFS_TYPE_VDEV ?
ZFS_SYSFS_VDEV_PROPERTIES : ZFS_SYSFS_DATASET_PROPERTIES), name));
ZFS_SYSFS_VDEV_PROPERTIES : ZFS_SYSFS_DATASET_PROPERTIES),
name, sfeatures));
#endif
}
@ -94,7 +96,8 @@ void
zprop_register_impl(int prop, const char *name, zprop_type_t type,
uint64_t numdefault, const char *strdefault, zprop_attr_t attr,
int objset_types, const char *values, const char *colname,
boolean_t rightalign, boolean_t visible, const zprop_index_t *idx_tbl)
boolean_t rightalign, boolean_t visible, const zprop_index_t *idx_tbl,
const struct zfs_mod_supported_features *sfeatures)
{
zprop_desc_t *prop_tbl = zprop_get_proptable(objset_types);
zprop_desc_t *pd;
@ -116,7 +119,8 @@ zprop_register_impl(int prop, const char *name, zprop_type_t type,
pd->pd_colname = colname;
pd->pd_rightalign = rightalign;
pd->pd_visible = visible;
pd->pd_zfs_mod_supported = zfs_mod_supported_prop(name, objset_types);
pd->pd_zfs_mod_supported =
zfs_mod_supported_prop(name, objset_types, sfeatures);
pd->pd_table = idx_tbl;
pd->pd_table_size = 0;
while (idx_tbl && (idx_tbl++)->pi_name != NULL)
@ -126,38 +130,40 @@ zprop_register_impl(int prop, const char *name, zprop_type_t type,
void
zprop_register_string(int prop, const char *name, const char *def,
zprop_attr_t attr, int objset_types, const char *values,
const char *colname)
const char *colname, const struct zfs_mod_supported_features *sfeatures)
{
zprop_register_impl(prop, name, PROP_TYPE_STRING, 0, def, attr,
objset_types, values, colname, B_FALSE, B_TRUE, NULL);
objset_types, values, colname, B_FALSE, B_TRUE, NULL, sfeatures);
}
void
zprop_register_number(int prop, const char *name, uint64_t def,
zprop_attr_t attr, int objset_types, const char *values,
const char *colname)
const char *colname, const struct zfs_mod_supported_features *sfeatures)
{
zprop_register_impl(prop, name, PROP_TYPE_NUMBER, def, NULL, attr,
objset_types, values, colname, B_TRUE, B_TRUE, NULL);
objset_types, values, colname, B_TRUE, B_TRUE, NULL, sfeatures);
}
void
zprop_register_index(int prop, const char *name, uint64_t def,
zprop_attr_t attr, int objset_types, const char *values,
const char *colname, const zprop_index_t *idx_tbl)
const char *colname, const zprop_index_t *idx_tbl,
const struct zfs_mod_supported_features *sfeatures)
{
zprop_register_impl(prop, name, PROP_TYPE_INDEX, def, NULL, attr,
objset_types, values, colname, B_FALSE, B_TRUE, idx_tbl);
objset_types, values, colname, B_FALSE, B_TRUE, idx_tbl, sfeatures);
}
void
zprop_register_hidden(int prop, const char *name, zprop_type_t type,
zprop_attr_t attr, int objset_types, const char *colname)
zprop_attr_t attr, int objset_types, const char *colname,
const struct zfs_mod_supported_features *sfeatures)
{
zprop_register_impl(prop, name, type, 0, NULL, attr,
objset_types, NULL, colname,
type == PROP_TYPE_NUMBER, B_FALSE, NULL);
type == PROP_TYPE_NUMBER, B_FALSE, NULL, sfeatures);
}