summaryrefslogtreecommitdiffstats
path: root/module/zfs/dmu_objset.c
diff options
context:
space:
mode:
Diffstat (limited to 'module/zfs/dmu_objset.c')
-rw-r--r--module/zfs/dmu_objset.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c
index a8304c18d..fa80e3a61 100644
--- a/module/zfs/dmu_objset.c
+++ b/module/zfs/dmu_objset.c
@@ -29,6 +29,7 @@
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright 2017 Nexenta Systems, Inc.
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
+ * Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -1118,6 +1119,8 @@ dmu_objset_create_check(void *arg, dmu_tx_t *tx)
dmu_objset_create_arg_t *doca = arg;
dsl_pool_t *dp = dmu_tx_pool(tx);
dsl_dir_t *pdd;
+ dsl_dataset_t *parentds;
+ objset_t *parentos;
const char *tail;
int error;
@@ -1146,7 +1149,30 @@ dmu_objset_create_check(void *arg, dmu_tx_t *tx)
error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
doca->doca_cred);
+ if (error != 0) {
+ dsl_dir_rele(pdd, FTAG);
+ return (error);
+ }
+ /* can't create below anything but filesystems (eg. no ZVOLs) */
+ error = dsl_dataset_hold_obj(pdd->dd_pool,
+ dsl_dir_phys(pdd)->dd_head_dataset_obj, FTAG, &parentds);
+ if (error != 0) {
+ dsl_dir_rele(pdd, FTAG);
+ return (error);
+ }
+ error = dmu_objset_from_ds(parentds, &parentos);
+ if (error != 0) {
+ dsl_dataset_rele(parentds, FTAG);
+ dsl_dir_rele(pdd, FTAG);
+ return (error);
+ }
+ if (dmu_objset_type(parentos) != DMU_OST_ZFS) {
+ dsl_dataset_rele(parentds, FTAG);
+ dsl_dir_rele(pdd, FTAG);
+ return (SET_ERROR(ZFS_ERR_WRONG_PARENT));
+ }
+ dsl_dataset_rele(parentds, FTAG);
dsl_dir_rele(pdd, FTAG);
return (error);