diff options
Diffstat (limited to 'module/zfs/dmu_objset.c')
-rw-r--r-- | module/zfs/dmu_objset.c | 26 |
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); |