summaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_ioctl.c
diff options
context:
space:
mode:
authorGiuseppe Di Natale <[email protected]>2017-06-26 16:56:09 -0700
committerBrian Behlendorf <[email protected]>2017-06-26 16:56:09 -0700
commitd12f91fde3c6a7d1aa71967b3480faac6c853051 (patch)
treeeb04ad4ac4f5cbf2d7e45a20f1047da24a41b16a /module/zfs/zfs_ioctl.c
parent7517376f939d788a2622c84fe1f502799a74a0ae (diff)
OpenZFS 8264 - want support for promoting datasets in libzfs_core
Authored by: Andrew Stormont <[email protected]> Reviewed by: Andriy Gapon <[email protected]> Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Dan McDonald <[email protected]> Approved by: Dan McDonald <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Ported-by: Giuseppe Di Natale <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/8264 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/a4b8c9a Closes #6254
Diffstat (limited to 'module/zfs/zfs_ioctl.c')
-rw-r--r--module/zfs/zfs_ioctl.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index 4fda36c7f..8cdfe31a2 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -35,6 +35,7 @@
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2017, loli10K <[email protected]>. All rights reserved.
* Copyright (c) 2017 Datto Inc.
+ * Copyright 2017 RackTop Systems.
*/
/*
@@ -4963,7 +4964,6 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc)
/*
* inputs:
* zc_name name of filesystem
- * zc_value name of origin snapshot
*
* outputs:
* zc_string name of conflicting snapshot, if there is one
@@ -4971,16 +4971,49 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc)
static int
zfs_ioc_promote(zfs_cmd_t *zc)
{
+ dsl_pool_t *dp;
+ dsl_dataset_t *ds, *ods;
+ char origin[ZFS_MAX_DATASET_NAME_LEN];
char *cp;
+ int error;
+
+ error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
+ if (error != 0)
+ return (error);
+
+ error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &ds);
+ if (error != 0) {
+ dsl_pool_rele(dp, FTAG);
+ return (error);
+ }
+
+ if (!dsl_dir_is_clone(ds->ds_dir)) {
+ dsl_dataset_rele(ds, FTAG);
+ dsl_pool_rele(dp, FTAG);
+ return (SET_ERROR(EINVAL));
+ }
+
+ error = dsl_dataset_hold_obj(dp,
+ dsl_dir_phys(ds->ds_dir)->dd_origin_obj, FTAG, &ods);
+ if (error != 0) {
+ dsl_dataset_rele(ds, FTAG);
+ dsl_pool_rele(dp, FTAG);
+ return (error);
+ }
+
+ dsl_dataset_name(ods, origin);
+ dsl_dataset_rele(ods, FTAG);
+ dsl_dataset_rele(ds, FTAG);
+ dsl_pool_rele(dp, FTAG);
/*
* We don't need to unmount *all* the origin fs's snapshots, but
* it's easier.
*/
- cp = strchr(zc->zc_value, '@');
+ cp = strchr(origin, '@');
if (cp)
*cp = '\0';
- (void) dmu_objset_find(zc->zc_value,
+ (void) dmu_objset_find(origin,
zfs_unmount_snap_cb, NULL, DS_FIND_SNAPSHOTS);
return (dsl_dataset_promote(zc->zc_name, zc->zc_string));
}