#endif
extern boolean_t zfs_allocatable_devs(nvlist_t *);
+extern boolean_t zfs_special_devs(nvlist_t *);
extern void zpool_get_load_policy(nvlist_t *, zpool_load_policy_t *);
extern int zfs_zpl_version_map(int spa_version);
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)
{
#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);
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;
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))) {
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;
}
}
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) {
#
# DESCRIPTION:
-# Creating a pool with a special device succeeds.
+# Creating a pool with a special device succeeds, but only if
+# "feature@allocation_classes" is enabled.
#
verify_runnable "global"
log_onexit cleanup
log_must disk_setup
+for type in special dedup; do
+ log_mustnot zpool create -d $TESTPOOL $CLASS_DISK0 $type $CLASS_DISK1
+done
log_must zpool create $TESTPOOL raidz $ZPOOL_DISKS special mirror \
$CLASS_DISK0 $CLASS_DISK1
log_must display_status "$TESTPOOL"