Fix some krpc leaks for the NFSv4.1/pNFS client.

The NFSv4.1/pNFS client wasn't doing a newnfs_disconnect() call for the
connection to the Data Server (DS) under some circumstances. The main
effect of this was a leak of malloc'd structures in the krpc. This patch
adds the newnfs_disconnect() calls to fix this.
Detected during recent testing against the pNFS server under development.

MFC after:	2 weeks
This commit is contained in:
Rick Macklem 2017-04-22 20:55:39 +00:00
parent d55eb4ff7e
commit c20a721023
2 changed files with 18 additions and 5 deletions

View File

@ -5399,10 +5399,13 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp,
NFSCL_DEBUG(3, "DS connect=%d\n", error);
/* Now, do the exchangeid and create session. */
if (error == 0)
if (error == 0) {
error = nfsrpc_exchangeid(nmp, clp, nrp, NFSV4EXCH_USEPNFSDS,
&dsp, nrp->nr_cred, p);
NFSCL_DEBUG(3, "DS exchangeid=%d\n", error);
NFSCL_DEBUG(3, "DS exchangeid=%d\n", error);
if (error != 0)
newnfs_disconnect(nrp);
}
if (error == 0) {
dsp->nfsclds_sockp = nrp;
NFSLOCKMNT(nmp);
@ -5445,8 +5448,10 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp,
TAILQ_INSERT_TAIL(&nmp->nm_sess, dsp, nfsclds_list);
NFSUNLOCKMNT(nmp);
*dspp = dsp;
} else if (dsp != NULL)
} else if (dsp != NULL) {
newnfs_disconnect(nrp);
nfscl_freenfsclds(dsp);
}
return (error);
}

View File

@ -1643,8 +1643,12 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
NFSUNLOCKCLSTATE();
free(nmp->nm_clp, M_NFSCLCLIENT);
}
TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp)
TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
dsp->nfsclds_sockp != NULL)
newnfs_disconnect(dsp->nfsclds_sockp);
nfscl_freenfsclds(dsp);
}
FREE(nmp, M_NEWNFSMNT);
FREE(nam, M_SONAME);
return (error);
@ -1709,8 +1713,12 @@ nfs_unmount(struct mount *mp, int mntflags)
AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
mtx_destroy(&nmp->nm_sockreq.nr_mtx);
mtx_destroy(&nmp->nm_mtx);
TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp)
TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
dsp->nfsclds_sockp != NULL)
newnfs_disconnect(dsp->nfsclds_sockp);
nfscl_freenfsclds(dsp);
}
FREE(nmp, M_NEWNFSMNT);
out:
return (error);