diff options
author | Andriy Gapon <[email protected]> | 2017-07-27 15:58:52 +0300 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-02-09 10:27:58 -0800 |
commit | 13342832252c43a0b372b41cb6319377d160bc15 (patch) | |
tree | 30491cef588261c1fa986f1416c8e3def4dcf5de /module/zfs/zfs_ioctl.c | |
parent | cc63068e95ee725cce03b1b7ce50179825a6cda5 (diff) |
OpenZFS 8520 - lzc_rollback
8520 lzc_rollback_to should support rolling back to origin
7198 libzfs should gracefully handle EINVAL from lzc_rollback
lzc_rollback_to() should support rolling back to a clone's origin.
The current checks in zfs_ioc_rollback() would not allow that
because the origin snapshot belongs to a different filesystem.
The overly restrictive check was in introduced in 7600, but it
was not a regression as none of the existing tools provided a
way to rollback to the origin.
Authored by: Andriy Gapon <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Approved by: Dan McDonald <[email protected]>
Ported-by: Brian Behlendorf <[email protected]>
OpenZFS-issue: https://www.illumos.org/issues/8520
OpenZFS-issue: https://www.illumos.org/issues/7198
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/78a5a1a25a
Closes #7150
Diffstat (limited to 'module/zfs/zfs_ioctl.c')
-rw-r--r-- | module/zfs/zfs_ioctl.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index cc7155a78..fcd2fca12 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -3773,11 +3773,14 @@ zfs_ioc_rollback(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) (void) nvlist_lookup_string(innvl, "target", &target); if (target != NULL) { - int fslen = strlen(fsname); + const char *cp = strchr(target, '@'); - if (strncmp(fsname, target, fslen) != 0) - return (SET_ERROR(EINVAL)); - if (target[fslen] != '@') + /* + * The snap name must contain an @, and the part after it must + * contain only valid characters. + */ + if (cp == NULL || + zfs_component_namecheck(cp + 1, NULL, NULL) != 0) return (SET_ERROR(EINVAL)); } |