summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorTim Chase <[email protected]>2013-12-23 14:06:34 -0600
committerBrian Behlendorf <[email protected]>2014-01-07 09:00:26 -0800
commitfb8e608d9dacf2f6703da8c853f6086e4dd79824 (patch)
treeebd6b931056bc41da0006c4c112aa5974832c909 /module
parent5d862cb0d9a4b6dcc97a88fa0d5a7a717566e5ab (diff)
Fix the creation of ZPOOL_HIST_CMD pool history entries.
Move the libzfs_fini() after the zpool_log_history() call so the ZPOOL_HIST_CMD entry can get written. Fix the handling of saved_poolname in zfsdev_ioctl() which was broken as part of the stack-reduction work in a16878805388c4d96cb8a294de965071d138a47b. Since ZoL destroys the TSD data in which the previously successful ioctl()'s pool name is stored following every vop, the ZFS_IOC_LOG_HISTORY ioctl has a very important restriction: it can only successfully write a long entry following a successful ioctl() if no intervening vops have been performed. Some of zfs subcommands do perform intervening vops and to do the logging themselves. At the moment, the "create" and "clone" subcommands have been modified appropriately. Signed-off-by: Tim Chase <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #1998
Diffstat (limited to 'module')
-rw-r--r--module/zfs/zfs_ioctl.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index bf212dee8..a061978dc 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -5558,9 +5558,9 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
{
zfs_cmd_t *zc;
uint_t vecnum;
- int error, rc, len, flag = 0;
+ int error, rc, len = 0, flag = 0;
const zfs_ioc_vec_t *vec;
- char *saved_poolname;
+ char *saved_poolname = NULL;
nvlist_t *innvl = NULL;
vecnum = cmd - ZFS_IOC_FIRST;
@@ -5576,7 +5576,6 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
return (-SET_ERROR(EINVAL));
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP | KM_NODEBUG);
- saved_poolname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
if (error != 0) {
@@ -5626,9 +5625,9 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
goto out;
/* legacy ioctls can modify zc_name */
- (void) strlcpy(saved_poolname, zc->zc_name, sizeof (saved_poolname));
- len = strcspn(saved_poolname, "/@") + 1;
- saved_poolname[len] = '\0';
+ len = strcspn(zc->zc_name, "/@#") + 1;
+ saved_poolname = kmem_alloc(len, KM_SLEEP);
+ (void) strlcpy(saved_poolname, zc->zc_name, len);
if (vec->zvec_func != NULL) {
nvlist_t *outnvl;
@@ -5693,10 +5692,12 @@ out:
char *s = tsd_get(zfs_allow_log_key);
if (s != NULL)
strfree(s);
- (void) tsd_set(zfs_allow_log_key, strdup(saved_poolname));
+ (void) tsd_set(zfs_allow_log_key, saved_poolname);
+ } else {
+ if (saved_poolname != NULL)
+ kmem_free(saved_poolname, len);
}
- kmem_free(saved_poolname, MAXNAMELEN);
kmem_free(zc, sizeof (zfs_cmd_t));
return (-error);
}