Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix pool creation with feature@allocation_classes disabled #9429

Merged
merged 1 commit into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/zfs_comutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ extern "C" {
#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);
Expand Down
28 changes: 28 additions & 0 deletions module/zcommon/zfs_comutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))) {
Expand All @@ -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;
}
}

Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@

#
# 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"
Expand All @@ -31,6 +32,9 @@ log_assert $claim
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"
Expand Down