aboutsummaryrefslogtreecommitdiff
path: root/uts
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2018-12-26 07:57:21 +0000
committerAndriy Gapon <avg@FreeBSD.org>2018-12-26 07:57:21 +0000
commit48114cb5bef6d2b4383107fbabd77fd0e52c3dee (patch)
tree71aa5fd62878eda001bfe2e28065cbb3d018a30e /uts
parent4cabda1b4daa904600d6699312955b40e2e2e5ab (diff)
downloadsrc-48114cb5bef6d2b4383107fbabd77fd0e52c3dee.tar.gz
src-48114cb5bef6d2b4383107fbabd77fd0e52c3dee.zip
9630 add lzc_rename and lzc_destroy to libzfs_core
illumos/illumos-gate@049ba636fa37a2892809192fc671bff9158a01cd https://github.com/illumos/illumos-gate/commit/049ba636fa37a2892809192fc671bff9158a01cd https://www.illumos.org/issues/9630 Rename and destroy are very useful operations that deserve to be in libzfs_core. And they are not hard to implement too. Reviewed by: Andy Stormont <astormont@racktopsystems.com> Reviewed by: Matt Ahrens <matt@delphix.com> Reviewed by: Serapheim Dimitropoulos <serapheim.dimitro@delphix.com> Approved by: Dan McDonald <danmcd@joyent.com> Author: Andriy Gapon <avg@FreeBSD.org>
Notes
Notes: svn path=/vendor-sys/illumos/dist/; revision=342469
Diffstat (limited to 'uts')
-rw-r--r--uts/common/fs/zfs/zfs_ioctl.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/uts/common/fs/zfs/zfs_ioctl.c b/uts/common/fs/zfs/zfs_ioctl.c
index 175938eeb888..0abdbe9badc3 100644
--- a/uts/common/fs/zfs/zfs_ioctl.c
+++ b/uts/common/fs/zfs/zfs_ioctl.c
@@ -3686,7 +3686,6 @@ zfs_ioc_pool_discard_checkpoint(const char *poolname, nvlist_t *innvl,
/*
* inputs:
* zc_name name of dataset to destroy
- * zc_objset_type type of objset
* zc_defer_destroy mark for deferred destroy
*
* outputs: none
@@ -3694,16 +3693,24 @@ zfs_ioc_pool_discard_checkpoint(const char *poolname, nvlist_t *innvl,
static int
zfs_ioc_destroy(zfs_cmd_t *zc)
{
+ objset_t *os;
+ dmu_objset_type_t ost;
int err;
- if (zc->zc_objset_type == DMU_OST_ZFS)
+ err = dmu_objset_hold(zc->zc_name, FTAG, &os);
+ if (err != 0)
+ return (err);
+ ost = dmu_objset_type(os);
+ dmu_objset_rele(os, FTAG);
+
+ if (ost == DMU_OST_ZFS)
zfs_unmount_snap(zc->zc_name);
if (strchr(zc->zc_name, '@'))
err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
else
err = dsl_destroy_head(zc->zc_name);
- if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0)
+ if (ost == DMU_OST_ZVOL && err == 0)
(void) zvol_remove_minor(zc->zc_name);
return (err);
}
@@ -3854,8 +3861,11 @@ recursive_unmount(const char *fsname, void *arg)
static int
zfs_ioc_rename(zfs_cmd_t *zc)
{
+ objset_t *os;
+ dmu_objset_type_t ost;
boolean_t recursive = zc->zc_cookie & 1;
char *at;
+ int err;
/* "zfs rename" from and to ...%recv datasets should both fail */
zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
@@ -3865,6 +3875,12 @@ zfs_ioc_rename(zfs_cmd_t *zc)
strchr(zc->zc_name, '%') || strchr(zc->zc_value, '%'))
return (SET_ERROR(EINVAL));
+ err = dmu_objset_hold(zc->zc_name, FTAG, &os);
+ if (err != 0)
+ return (err);
+ ost = dmu_objset_type(os);
+ dmu_objset_rele(os, FTAG);
+
at = strchr(zc->zc_name, '@');
if (at != NULL) {
/* snaps must be in same fs */
@@ -3873,7 +3889,7 @@ zfs_ioc_rename(zfs_cmd_t *zc)
if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
return (SET_ERROR(EXDEV));
*at = '\0';
- if (zc->zc_objset_type == DMU_OST_ZFS) {
+ if (ost == DMU_OST_ZFS) {
error = dmu_objset_find(zc->zc_name,
recursive_unmount, at + 1,
recursive ? DS_FIND_CHILDREN : 0);
@@ -3888,7 +3904,7 @@ zfs_ioc_rename(zfs_cmd_t *zc)
return (error);
} else {
- if (zc->zc_objset_type == DMU_OST_ZVOL)
+ if (ost == DMU_OST_ZVOL)
(void) zvol_remove_minor(zc->zc_name);
return (dsl_dir_rename(zc->zc_name, zc->zc_value));
}