Fix memory leaks in zfsvfs_create_impl()

This patch simply fixes some small memory leaks that can happen
during error handling in zfsvfs_create_impl(). If the function
fails, it frees all the memory / references it created.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #8490
This commit is contained in:
Tom Caputi 2019-03-14 21:14:36 -04:00 committed by Brian Behlendorf
parent c742bf1e68
commit 04a3b0796c

View File

@ -1035,14 +1035,6 @@ zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os)
zfsvfs->z_xattr_sa = B_TRUE; zfsvfs->z_xattr_sa = B_TRUE;
} }
error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
&zfsvfs->z_attr_table);
if (error != 0)
return (error);
if (zfsvfs->z_version >= ZPL_VERSION_SA)
sa_register_update_callback(os, zfs_sa_upgrade);
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1,
&zfsvfs->z_root); &zfsvfs->z_root);
if (error != 0) if (error != 0)
@ -1116,6 +1108,14 @@ zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os)
else if (error != 0) else if (error != 0)
return (error); return (error);
error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
&zfsvfs->z_attr_table);
if (error != 0)
return (error);
if (zfsvfs->z_version >= ZPL_VERSION_SA)
sa_register_update_callback(os, zfs_sa_upgrade);
return (0); return (0);
} }
@ -1142,6 +1142,11 @@ zfsvfs_create(const char *osname, boolean_t readonly, zfsvfs_t **zfvp)
return (error); return (error);
} }
/*
* Note: zfsvfs is assumed to be malloc'd, and will be freed by this function
* on a failure. Do not pass in a statically allocated zfsvfs.
*/
int int
zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os) zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os)
{ {
@ -1174,7 +1179,7 @@ zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os)
error = zfsvfs_init(zfsvfs, os); error = zfsvfs_init(zfsvfs, os);
if (error != 0) { if (error != 0) {
*zfvp = NULL; *zfvp = NULL;
kmem_free(zfsvfs, sizeof (zfsvfs_t)); zfsvfs_free(zfsvfs);
return (error); return (error);
} }