From e460d6ff6b33db7a7df0cbaa7a0814b8dae34891 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 14 Jun 2017 16:27:54 +0000 Subject: [PATCH] 8264 want support for promoting datasets in libzfs_core illumos/illumos-gate@a4b8c9aa65a0a735aba318024a424a90d7b06c37 https://github.com/illumos/illumos-gate/commit/a4b8c9aa65a0a735aba318024a424a90d7b06c37 https://www.illumos.org/issues/8264 Oddly there is a lzc_clone function, but no lzc_promote function. Reviewed by: Andriy Gapon Reviewed by: Matthew Ahrens Reviewed by: Dan McDonald Approved by: Dan McDonald Author: Andrew Stormont --- uts/common/fs/zfs/zfs_ioctl.c | 39 ++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/uts/common/fs/zfs/zfs_ioctl.c b/uts/common/fs/zfs/zfs_ioctl.c index da22cb6c815..d93c1f02c3b 100644 --- a/uts/common/fs/zfs/zfs_ioctl.c +++ b/uts/common/fs/zfs/zfs_ioctl.c @@ -31,6 +31,7 @@ * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Toomas Soome + * Copyright 2017 RackTop Systems. */ /* @@ -4702,7 +4703,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 @@ -4710,16 +4710,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)); }