Date: Tue, 8 Aug 2017 10:49:56 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r322229 - vendor-sys/illumos/dist/uts/common/fs/zfs vendor-sys/illumos/dist/uts/common/fs/zfs/sys vendor/illumos/dist/lib/libzfs/common vendor/illumos/dist/lib/libzfs_core/common Message-ID: <201708081049.v78AnuJW030931@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Tue Aug 8 10:49:56 2017 New Revision: 322229 URL: https://svnweb.freebsd.org/changeset/base/322229 Log: 7600 zfs rollback should pass target snapshot to kernel illumos/illumos-gate@77b171372ed21642e04c873ef1e87fe2365520df https://github.com/illumos/illumos-gate/commit/77b171372ed21642e04c873ef1e87fe2365520df https://www.illumos.org/issues/7600 At present, the kernel side code seems to blindly rollback to whatever happens to be the latest snapshot at the time when the rollback task is processed. The expected target's name should be passed to the kernel driver and the sync task should validate that the target exists and that it is the latest snapshot indeed. Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Author: Andriy Gapon <avg@FreeBSD.org> Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c Changes in other areas also in this revision: Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.c vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.h Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c Tue Aug 8 10:48:52 2017 (r322228) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c Tue Aug 8 10:49:56 2017 (r322229) @@ -2173,6 +2173,7 @@ dsl_dataset_handoff_check(dsl_dataset_t *ds, void *own typedef struct dsl_dataset_rollback_arg { const char *ddra_fsname; + const char *ddra_tosnap; void *ddra_owner; nvlist_t *ddra_result; } dsl_dataset_rollback_arg_t; @@ -2214,6 +2215,18 @@ dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx) return (SET_ERROR(EAGAIN)); } + /* + * If the expected target snapshot is specified, then check that + * the latest snapshot is it. + */ + if (ddra->ddra_tosnap != NULL) { + char namebuf[ZFS_MAX_DATASET_NAME_LEN]; + + dsl_dataset_name(ds->ds_prev, namebuf); + if (strcmp(namebuf, ddra->ddra_tosnap) != 0) + return (SET_ERROR(EXDEV)); + } + /* must not have any bookmarks after the most recent snapshot */ nvlist_t *proprequest = fnvlist_alloc(); fnvlist_add_boolean(proprequest, zfs_prop_to_name(ZFS_PROP_CREATETXG)); @@ -2315,11 +2328,13 @@ dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx) * notes above zfs_suspend_fs() for further details. */ int -dsl_dataset_rollback(const char *fsname, void *owner, nvlist_t *result) +dsl_dataset_rollback(const char *fsname, const char *tosnap, void *owner, + nvlist_t *result) { dsl_dataset_rollback_arg_t ddra; ddra.ddra_fsname = fsname; + ddra.ddra_tosnap = tosnap; ddra.ddra_owner = owner; ddra.ddra_result = result; Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h Tue Aug 8 10:48:52 2017 (r322228) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h Tue Aug 8 10:49:56 2017 (r322229) @@ -334,7 +334,8 @@ void dsl_dataset_set_refreservation_sync_impl(dsl_data void dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx); boolean_t dsl_dataset_is_zapified(dsl_dataset_t *ds); boolean_t dsl_dataset_has_resume_receive_state(dsl_dataset_t *ds); -int dsl_dataset_rollback(const char *fsname, void *owner, nvlist_t *result); +int dsl_dataset_rollback(const char *fsname, const char *tosnap, void *owner, + nvlist_t *result); void dsl_dataset_deactivate_feature(uint64_t dsobj, spa_feature_t f, dmu_tx_t *tx); Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c Tue Aug 8 10:48:52 2017 (r322228) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c Tue Aug 8 10:49:56 2017 (r322229) @@ -3636,18 +3636,29 @@ zfs_ioc_destroy(zfs_cmd_t *zc) /* * fsname is name of dataset to rollback (to most recent snapshot) * - * innvl is not used. + * innvl may contain name of expected target snapshot * * outnvl: "target" -> name of most recent snapshot * } */ /* ARGSUSED */ static int -zfs_ioc_rollback(const char *fsname, nvlist_t *args, nvlist_t *outnvl) +zfs_ioc_rollback(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) { zfsvfs_t *zfsvfs; + char *target = NULL; int error; + (void) nvlist_lookup_string(innvl, "target", &target); + if (target != NULL) { + int fslen = strlen(fsname); + + if (strncmp(fsname, target, fslen) != 0) + return (SET_ERROR(EINVAL)); + if (target[fslen] != '@') + return (SET_ERROR(EINVAL)); + } + if (getzfsvfs(fsname, &zfsvfs) == 0) { dsl_dataset_t *ds; @@ -3656,13 +3667,14 @@ zfs_ioc_rollback(const char *fsname, nvlist_t *args, n if (error == 0) { int resume_err; - error = dsl_dataset_rollback(fsname, zfsvfs, outnvl); + error = dsl_dataset_rollback(fsname, target, zfsvfs, + outnvl); resume_err = zfs_resume_fs(zfsvfs, ds); error = error ? error : resume_err; } VFS_RELE(zfsvfs->z_vfs); } else { - error = dsl_dataset_rollback(fsname, NULL, outnvl); + error = dsl_dataset_rollback(fsname, target, NULL, outnvl); } return (error); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708081049.v78AnuJW030931>