aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2014-04-17 10:06:37 -0700
committerBrian Behlendorf <[email protected]>2014-04-18 13:30:15 -0700
commit4fd762f8ad59f5840c790357a0e50f15cc9ccc08 (patch)
treeec50cf35c30976352ccfd38217a09010d71f7f7b /module
parente0b8f6290216a3d10af008a160617d89517fc631 (diff)
Fix zfsdev_ioctl() kmem leak warning
Due to an asymmetry in the kmem accounting a memory leak was being reported when it was only an accounting issue. All memory allocated with kmem_alloc() must be released with kmem_free() or it will not be properly accounted for. In this case the code used strfree() to release the memory allocated by kmem_alloc(). Presumably this was done because the size of the memory region wasn't available when the memory needed to be freed. To resolve this issue the code has been updated to use strdup() instead of kmem_alloc() to allocate the memory. Like strfree(), strdup() is not integrated with the memory accounting. This means we can use strfree() to release it like Illumos. SPL: kmem leaked 10/4368729 bytes address size data func:line ffff880067e9aa40 10 ZZZZZZZZZZ zfsdev_ioctl:5655 Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Tim Chase <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Closes #2262
Diffstat (limited to 'module')
-rw-r--r--module/zfs/zfs_ioctl.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index 0dfda1abf..5f97ea454 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -5584,7 +5584,7 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
{
zfs_cmd_t *zc;
uint_t vecnum;
- int error, rc, len = 0, flag = 0;
+ int error, rc, flag = 0;
const zfs_ioc_vec_t *vec;
char *saved_poolname = NULL;
nvlist_t *innvl = NULL;
@@ -5651,9 +5651,13 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
goto out;
/* legacy ioctls can modify zc_name */
- len = strcspn(zc->zc_name, "/@#") + 1;
- saved_poolname = kmem_alloc(len, KM_SLEEP);
- (void) strlcpy(saved_poolname, zc->zc_name, len);
+ saved_poolname = strdup(zc->zc_name);
+ if (saved_poolname == NULL) {
+ error = SET_ERROR(ENOMEM);
+ goto out;
+ } else {
+ saved_poolname[strcspn(saved_poolname, "/@#")] = '\0';
+ }
if (vec->zvec_func != NULL) {
nvlist_t *outnvl;
@@ -5721,7 +5725,7 @@ out:
(void) tsd_set(zfs_allow_log_key, saved_poolname);
} else {
if (saved_poolname != NULL)
- kmem_free(saved_poolname, len);
+ strfree(saved_poolname);
}
kmem_free(zc, sizeof (zfs_cmd_t));