summaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_ioctl.c
diff options
context:
space:
mode:
authorLOLi <[email protected]>2017-07-28 23:12:34 +0200
committerBrian Behlendorf <[email protected]>2017-07-28 14:12:34 -0700
commit650258d7c786b8e62ca847a926f6f038cd3e5d94 (patch)
treefa73fa616fd82d562bc143efcd8e25e94aa7e2bf /module/zfs/zfs_ioctl.c
parentf06f53fa3f566056fd3a03737032f1bd6bcf48bc (diff)
zfs promote|rename .../%recv should be an error
If we are in the middle of an incremental 'zfs receive', the child .../%recv will exist. If we run 'zfs promote' .../%recv, it will "work", but then zfs gets confused about the status of the new dataset. Attempting to do this promote should be an error. Similarly renaming .../%recv datasets should not be allowed. Reviewed-by: Giuseppe Di Natale <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: loli10K <[email protected]> Closes #4843 Closes #6339
Diffstat (limited to 'module/zfs/zfs_ioctl.c')
-rw-r--r--module/zfs/zfs_ioctl.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index d195eded7..21fefe57f 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -3738,9 +3738,12 @@ zfs_ioc_rename(zfs_cmd_t *zc)
boolean_t recursive = zc->zc_cookie & 1;
char *at;
+ /* "zfs rename" from and to ...%recv datasets should both fail */
+ zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
- if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
- strchr(zc->zc_value, '%'))
+ if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0 ||
+ dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
+ strchr(zc->zc_name, '%') || strchr(zc->zc_value, '%'))
return (SET_ERROR(EINVAL));
at = strchr(zc->zc_name, '@');
@@ -5002,6 +5005,11 @@ zfs_ioc_promote(zfs_cmd_t *zc)
char *cp;
int error;
+ zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
+ if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0 ||
+ strchr(zc->zc_name, '%'))
+ return (SET_ERROR(EINVAL));
+
error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
if (error != 0)
return (error);