summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorloli10K <[email protected]>2019-10-11 01:39:41 +0200
committerBrian Behlendorf <[email protected]>2019-10-10 16:39:41 -0700
commit715c996d3b5e45897ff165f2e6610e1b57da47e4 (patch)
tree4c600a53be1551d992a0ea222cb60e93f28234f3 /module
parent2516a8782158a1d420aa00ce5f470a33cc7ec2ca (diff)
Fix pool creation with feature@allocation_classes disabled
When "feature@allocation_classes" is not enabled on the pool no vdev with "special" or "dedup" allocation type should be allowed to exist in the vdev tree. Reviewed-by: Pavel Zakharov <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: loli10K <[email protected]> Closes #9427 Closes #9429
Diffstat (limited to 'module')
-rw-r--r--module/zcommon/zfs_comutil.c28
-rw-r--r--module/zfs/spa.c10
2 files changed, 38 insertions, 0 deletions
diff --git a/module/zcommon/zfs_comutil.c b/module/zcommon/zfs_comutil.c
index 5daa6907c..a3ff7d8e6 100644
--- a/module/zcommon/zfs_comutil.c
+++ b/module/zcommon/zfs_comutil.c
@@ -64,6 +64,33 @@ zfs_allocatable_devs(nvlist_t *nv)
return (B_FALSE);
}
+/*
+ * Are there special vdevs?
+ */
+boolean_t
+zfs_special_devs(nvlist_t *nv)
+{
+ char *bias;
+ uint_t c;
+ nvlist_t **child;
+ uint_t children;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0) {
+ return (B_FALSE);
+ }
+ for (c = 0; c < children; c++) {
+ if (nvlist_lookup_string(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS,
+ &bias) == 0) {
+ if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0 ||
+ strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0) {
+ return (B_TRUE);
+ }
+ }
+ }
+ return (B_FALSE);
+}
+
void
zpool_get_load_policy(nvlist_t *nvl, zpool_load_policy_t *zlpp)
{
@@ -223,6 +250,7 @@ zfs_dataset_name_hidden(const char *name)
#if defined(_KERNEL)
EXPORT_SYMBOL(zfs_allocatable_devs);
+EXPORT_SYMBOL(zfs_special_devs);
EXPORT_SYMBOL(zpool_get_load_policy);
EXPORT_SYMBOL(zfs_zpl_version_map);
EXPORT_SYMBOL(zfs_spa_version_map);
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index 529ffc03d..facd5eda8 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -5620,6 +5620,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
uint64_t version, obj;
boolean_t has_features;
boolean_t has_encryption;
+ boolean_t has_allocclass;
spa_feature_t feat;
char *feat_name;
char *poolname;
@@ -5664,6 +5665,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
has_features = B_FALSE;
has_encryption = B_FALSE;
+ has_allocclass = B_FALSE;
for (nvpair_t *elem = nvlist_next_nvpair(props, NULL);
elem != NULL; elem = nvlist_next_nvpair(props, elem)) {
if (zpool_prop_feature(nvpair_name(elem))) {
@@ -5673,6 +5675,8 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
VERIFY0(zfeature_lookup_name(feat_name, &feat));
if (feat == SPA_FEATURE_ENCRYPTION)
has_encryption = B_TRUE;
+ if (feat == SPA_FEATURE_ALLOCATION_CLASSES)
+ has_allocclass = B_TRUE;
}
}
@@ -5686,6 +5690,12 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
return (error);
}
}
+ if (!has_allocclass && zfs_special_devs(nvroot)) {
+ spa_deactivate(spa);
+ spa_remove(spa);
+ mutex_exit(&spa_namespace_lock);
+ return (ENOTSUP);
+ }
if (has_features || nvlist_lookup_uint64(props,
zpool_prop_to_name(ZPOOL_PROP_VERSION), &version) != 0) {