From af7cd3eb5ad447917a8ab2f4aa1d2227bc484c2b Mon Sep 17 00:00:00 2001 From: Rajesh Amaravathi Date: Mon, 25 Jun 2012 17:36:44 +0530 Subject: nfs: memory leak fixes * Fixes a leak of strdups in the parent_inode_loc_fill code path. * Introduces nfs_forget() to cleanup the ctx(addr of inode_q), a major leak involving inode_q hereby fixed. * Using the correct size to allocate fd_entry structures. * Free hashmatch in call_state during call state wipe and reassignment of the same. * Free cs->resolventry in the rename fop code path. Change-Id: I4ff556eba27f0b56ef824c0a86ab3d393d0d38c1 BUG: 835059 Signed-off-by: Rajesh Amaravathi Reviewed-on: http://review.gluster.com/3641 Tested-by: Gluster Build System Reviewed-by: Kaleb KEITHLEY Reviewed-by: Anand Avati --- xlators/nfs/server/src/nfs-common.c | 2 +- xlators/nfs/server/src/nfs.c | 20 +++++++++++++++++++- xlators/nfs/server/src/nfs3-helpers.c | 7 ++++--- xlators/nfs/server/src/nfs3.c | 9 +++++++-- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c index ab28f78e9..e65075ba5 100644 --- a/xlators/nfs/server/src/nfs-common.c +++ b/xlators/nfs/server/src/nfs-common.c @@ -322,7 +322,7 @@ nfs_parent_inode_loc_fill (inode_t *parent, inode_t *entryinode, char *entry, goto err; ret = nfs_loc_fill (loc, entryinode, parent, path); - + GF_FREE (path); err: return ret; } diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index 6f0e41328..8e5ec27a3 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -38,6 +38,7 @@ #include "inode.h" #include "mount3.h" #include "nfs3.h" +#include "nfs3-helpers.h" #include "nfs-mem-types.h" #include "statedump.h" @@ -798,7 +799,24 @@ out: return 0; } -struct xlator_cbks cbks = { }; +int32_t +nfs_forget (xlator_t *this, inode_t *inode) +{ + uint64_t ctx = 0; + + if (inode_ctx_del (inode, this, &ctx)) + return -1; + + if (ctx != GF_NFS3_FD_CACHED) + GF_FREE ((void *)ctx); + + return 0; +} + +struct xlator_cbks cbks = { + .forget = nfs_forget +}; + struct xlator_fops fops = { }; struct xlator_dumpops dumpops = { diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index 54e98b8ca..46c6de1b5 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -1844,7 +1844,6 @@ __nfs3_fdcache_remove_entry (struct nfs3_state *nfs3, struct nfs3_fd_entry *fde) return 0; } - int nfs3_fdcache_remove (struct nfs3_state *nfs3, fd_t *fd) { @@ -1897,7 +1896,7 @@ nfs3_fdcache_add (struct nfs3_state *nfs3, fd_t *fd) if ((!nfs3) || (!fd)) return -1; - fde = GF_CALLOC (1, sizeof (*fd), gf_nfs_mt_nfs3_fd_entry); + fde = GF_CALLOC (1, sizeof (*fde), gf_nfs_mt_nfs3_fd_entry); if (!fde) { gf_log (GF_NFS3, GF_LOG_ERROR, "fd entry allocation failed"); goto out; @@ -2870,8 +2869,10 @@ nfs3_fh_resolve_search_dir (nfs3_call_state_t *cs, gf_dirent_t *entries) if (ret == GF_NFS3_FHRESOLVE_FOUND) cs->entrymatch = gf_dirent_for_name (candidate->d_name); else if (ret == GF_NFS3_FHRESOLVE_DIRFOUND) { - if (cs->hashmatch) + if (cs->hashmatch) { gf_dirent_free (cs->hashmatch); + GF_FREE (cs->hashmatch); + } cs->hashmatch = gf_dirent_for_name (candidate->d_name); } } diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index f55717915..d8f9b74a2 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -418,6 +418,11 @@ nfs3_call_state_wipe (nfs3_call_state_t *cs) if (cs->pathname) GF_FREE (cs->pathname); + if (cs->hashmatch) { + gf_dirent_free (cs->hashmatch); + GF_FREE (cs->hashmatch); + } + if (!list_empty (&cs->entries.list)) gf_dirent_free (&cs->entries); @@ -1322,8 +1327,7 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name) nfs3err: if (ret < 0) { nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "LOOKUP", - stat, - -ret); + stat, -ret); nfs3_lookup_reply (req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); /* Ret must be 0 after this so that the caller does not @@ -3657,6 +3661,7 @@ nfs3_rename_resume_src (void *carg) */ nfs_loc_copy (&cs->oploc, &cs->resolvedloc); nfs_loc_wipe (&cs->resolvedloc); + GF_FREE (cs->resolventry); ret = nfs3_fh_resolve_and_resume (cs, &cs->fh, cs->pathname, nfs3_rename_resume_dst); -- cgit