summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/zfs/dmu_objset.c26
-rw-r--r--module/zfs/dmu_recv.c24
-rw-r--r--module/zfs/dsl_dir.c26
-rw-r--r--module/zfs/zfs_ioctl.c11
4 files changed, 80 insertions, 7 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);
diff --git a/module/zfs/dmu_recv.c b/module/zfs/dmu_recv.c
index 4ac6f2f17..e05b5ad82 100644
--- a/module/zfs/dmu_recv.c
+++ b/module/zfs/dmu_recv.c
@@ -26,6 +26,7 @@
* Copyright 2014 HybridCluster. All rights reserved.
* Copyright 2016 RackTop Systems.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
*/
#include <sys/dmu.h>
@@ -79,6 +80,7 @@ recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
uint64_t fromguid, uint64_t featureflags)
{
uint64_t val;
+ uint64_t children;
int error;
dsl_pool_t *dp = ds->ds_dir->dd_pool;
boolean_t encrypted = ds->ds_dir->dd_crypto_obj != 0;
@@ -99,6 +101,15 @@ recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
if (error != ENOENT)
return (error == 0 ? EEXIST : error);
+ /* must not have children if receiving a ZVOL */
+ error = zap_count(dp->dp_meta_objset,
+ dsl_dir_phys(ds->ds_dir)->dd_child_dir_zapobj, &children);
+ if (error != 0)
+ return (error);
+ if (drba->drba_cookie->drc_drrb->drr_type != DMU_OST_ZFS &&
+ children > 0)
+ return (SET_ERROR(ZFS_ERR_WRONG_PARENT));
+
/*
* Check snapshot limit before receiving. We'll recheck again at the
* end, but might as well abort before receiving if we're already over
@@ -283,6 +294,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
} else if (error == ENOENT) {
/* target fs does not exist; must be a full backup or clone */
char buf[ZFS_MAX_DATASET_NAME_LEN];
+ objset_t *os;
/*
* If it's a non-clone incremental, we are missing the
@@ -352,6 +364,17 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
return (error);
}
+ /* can't recv below anything but filesystems (eg. no ZVOLs) */
+ error = dmu_objset_from_ds(ds, &os);
+ if (error != 0) {
+ dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ return (error);
+ }
+ if (dmu_objset_type(os) != DMU_OST_ZFS) {
+ dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ return (SET_ERROR(ZFS_ERR_WRONG_PARENT));
+ }
+
if (drba->drba_origin != NULL) {
dsl_dataset_t *origin;
@@ -381,6 +404,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
dsl_dataset_rele_flags(origin,
dsflags, FTAG);
}
+
dsl_dataset_rele_flags(ds, dsflags, FTAG);
error = 0;
}
diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c
index 5b6ce0420..b3b677fb8 100644
--- a/module/zfs/dsl_dir.c
+++ b/module/zfs/dsl_dir.c
@@ -25,6 +25,7 @@
* Copyright (c) 2014 Joyent, Inc. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
*/
#include <sys/dmu.h>
@@ -1888,6 +1889,8 @@ dsl_dir_rename_check(void *arg, dmu_tx_t *tx)
dsl_pool_t *dp = dmu_tx_pool(tx);
dsl_dir_t *dd, *newparent;
dsl_valid_rename_arg_t dvra;
+ dsl_dataset_t *parentds;
+ objset_t *parentos;
const char *mynewname;
int error;
@@ -1918,6 +1921,29 @@ dsl_dir_rename_check(void *arg, dmu_tx_t *tx)
return (SET_ERROR(EEXIST));
}
+ /* can't rename below anything but filesystems (eg. no ZVOLs) */
+ error = dsl_dataset_hold_obj(newparent->dd_pool,
+ dsl_dir_phys(newparent)->dd_head_dataset_obj, FTAG, &parentds);
+ if (error != 0) {
+ dsl_dir_rele(newparent, FTAG);
+ dsl_dir_rele(dd, FTAG);
+ return (error);
+ }
+ error = dmu_objset_from_ds(parentds, &parentos);
+ if (error != 0) {
+ dsl_dataset_rele(parentds, FTAG);
+ dsl_dir_rele(newparent, FTAG);
+ dsl_dir_rele(dd, FTAG);
+ return (error);
+ }
+ if (dmu_objset_type(parentos) != DMU_OST_ZFS) {
+ dsl_dataset_rele(parentds, FTAG);
+ dsl_dir_rele(newparent, FTAG);
+ dsl_dir_rele(dd, FTAG);
+ return (SET_ERROR(ZFS_ERR_WRONG_PARENT));
+ }
+ dsl_dataset_rele(parentds, FTAG);
+
ASSERT3U(strnlen(ddra->ddra_newname, ZFS_MAX_DATASET_NAME_LEN),
<, ZFS_MAX_DATASET_NAME_LEN);
ASSERT3U(strnlen(ddra->ddra_oldname, ZFS_MAX_DATASET_NAME_LEN),
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index 0dfa01684..f4aea57d4 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -33,7 +33,7 @@
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2016 Toomas Soome <[email protected]>
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
- * Copyright (c) 2017, loli10K <[email protected]>. All rights reserved.
+ * Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
* Copyright (c) 2017 Datto Inc. All rights reserved.
* Copyright 2017 RackTop Systems.
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
@@ -3082,8 +3082,9 @@ zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
ASSERT(zplprops != NULL);
+ /* parent dataset must be a filesystem */
if (os != NULL && os->os_phys->os_type != DMU_OST_ZFS)
- return (SET_ERROR(EINVAL));
+ return (SET_ERROR(ZFS_ERR_WRONG_PARENT));
/*
* Pull out creator prop choices, if any.
@@ -3162,15 +3163,11 @@ zfs_fill_zplprops(const char *dataset, nvlist_t *createprops,
uint64_t zplver = ZPL_VERSION;
objset_t *os = NULL;
char parentname[ZFS_MAX_DATASET_NAME_LEN];
- char *cp;
spa_t *spa;
uint64_t spa_vers;
int error;
- (void) strlcpy(parentname, dataset, sizeof (parentname));
- cp = strrchr(parentname, '/');
- ASSERT(cp != NULL);
- cp[0] = '\0';
+ zfs_get_parent(dataset, parentname, sizeof (parentname));
if ((error = spa_open(dataset, &spa, FTAG)) != 0)
return (error);