svn commit: r230561 - in projects/nfsv4.1-client/sys/fs: nfs
nfsclient
Rick Macklem
rmacklem at FreeBSD.org
Thu Jan 26 03:40:33 UTC 2012
Author: rmacklem
Date: Thu Jan 26 03:40:32 2012
New Revision: 230561
URL: http://svn.freebsd.org/changeset/base/230561
Log:
To avoid crashes during forced dismounts, the NFSv4.1 session structure
needed to be moved from the clientid (nfsclclient) structure to the
nfsmount structure. The crashes happened because the clientid structure
was being free'd too early in the forced umount.
Modified:
projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c
projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h
projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c
projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c
projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c
projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c
projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h
Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Thu Jan 26 00:49:05 2012 (r230560)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Thu Jan 26 03:40:32 2012 (r230561)
@@ -797,9 +797,9 @@ tryagain:
nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t);
nd->nd_repstat = 0;
if (nd->nd_procnum != NFSPROC_NULL) {
- /* If sep == NULL, set it to the default in nfsclclient. */
- if (sep == NULL && nmp != NULL && nmp->nm_clp != NULL)
- sep = &nmp->nm_clp->nfsc_sess;
+ /* If sep == NULL, set it to the default in nmp. */
+ if (sep == NULL && nmp != NULL)
+ sep = &nmp->nm_sess;
/*
* and now the actual NFS xdr.
*/
Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Thu Jan 26 00:49:05 2012 (r230560)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Thu Jan 26 03:40:32 2012 (r230561)
@@ -87,7 +87,6 @@ struct nfsclclient {
struct nfscldevinfohead nfsc_devinfo;
struct nfscldevinfohash nfsc_devinfohash[NFSCLDEVINFOHASHSIZE];
struct nfsv4lock nfsc_lock;
- struct nfsclsession nfsc_sess;
struct proc *nfsc_renewthread;
struct nfsmount *nfsc_nmp;
time_t nfsc_expire;
@@ -100,16 +99,6 @@ struct nfsclclient {
u_int8_t nfsc_id[1]; /* Malloc'd to correct length */
};
-#define nfsc_mtx nfsc_sess.nfsess_mtx
-#define nfsc_cbslots nfsc_sess.nfsess_cbslots
-#define nfsc_clientid nfsc_sess.nfsess_clientid
-#define nfsc_slotseq nfsc_sess.nfsess_slotseq
-#define nfsc_slots nfsc_sess.nfsess_slots
-#define nfsc_sequenceid nfsc_sess.nfsess_sequenceid
-#define nfsc_foreslots nfsc_sess.nfsess_foreslots
-#define nfsc_backslots nfsc_sess.nfsess_backslots
-#define nfsc_sessionid nfsc_sess.nfsess_sessionid
-
/*
* Bits for nfsc_flags.
*/
Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c Thu Jan 26 00:49:05 2012 (r230560)
+++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c Thu Jan 26 03:40:32 2012 (r230561)
@@ -192,7 +192,7 @@ nfscl_reqstart(struct nfsrv_descript *nd
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
*tl = txdr_unsigned(NFSV4OP_SEQUENCE);
if (sep == NULL)
- nfsv4_setsequence(nd, &nmp->nm_clp->nfsc_sess,
+ nfsv4_setsequence(nd, &nmp->nm_sess,
nfs_bigreply[procnum]);
else
nfsv4_setsequence(nd, sep,
Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Thu Jan 26 00:49:05 2012 (r230560)
+++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Thu Jan 26 03:40:32 2012 (r230561)
@@ -367,8 +367,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vno
*tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid);
*tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH);
*tl++ = txdr_unsigned((mode >> NFSLCK_SHIFT) & NFSV4OPEN_DENYBOTH);
- *tl++ = op->nfso_own->nfsow_clp->nfsc_clientid.lval[0];
- *tl = op->nfso_own->nfsow_clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl = nmp->nm_sess.nfsess_clientid.lval[1];
(void) nfsm_strtom(nd, op->nfso_own->nfsow_owner, NFSV4CL_LOCKNAMELEN);
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV4OPEN_NOCREATE);
@@ -796,11 +796,11 @@ nfsrpc_setclient(struct nfsmount *nmp, s
NFSSETBOOTTIME(nfsboottime);
clp->nfsc_rev = rev++;
if (NFSHASNFSV4N(nmp)) {
- error = nfsrpc_exchangeid(nmp, clp, &clp->nfsc_sess,
+ error = nfsrpc_exchangeid(nmp, clp, &nmp->nm_sess,
NFSV4EXCH_USEPNFSMDS | NFSV4EXCH_USENONPNFS, cred, p);
if (error) printf("exch=%d\n",error);
if (error == 0)
- error = nfsrpc_createsession(nmp, &clp->nfsc_sess, cred,
+ error = nfsrpc_createsession(nmp, &nmp->nm_sess, cred,
p);
if (error) printf("aft crs=%d\n",error);
return (error);
@@ -864,8 +864,8 @@ if (error) printf("aft crs=%d\n",error);
return (error);
if (nd->nd_repstat == 0) {
NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
- clp->nfsc_clientid.lval[0] = *tl++;
- clp->nfsc_clientid.lval[1] = *tl++;
+ nmp->nm_sess.nfsess_clientid.lval[0] = *tl++;
+ nmp->nm_sess.nfsess_clientid.lval[1] = *tl++;
confirm.lval[0] = *tl++;
confirm.lval[1] = *tl;
mbuf_freem(nd->nd_mrep);
@@ -877,8 +877,8 @@ if (error) printf("aft crs=%d\n",error);
nfscl_reqstart(nd, NFSPROC_SETCLIENTIDCFRM, nmp, NULL, 0, NULL,
NULL);
NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
- *tl++ = clp->nfsc_clientid.lval[0];
- *tl++ = clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[1];
*tl++ = confirm.lval[0];
*tl = confirm.lval[1];
nd->nd_flag |= ND_USEGSSNAME;
@@ -1876,7 +1876,9 @@ nfsrpc_createv4(vnode_t dvp, char *name,
nfsattrbit_t attrbits;
nfsv4stateid_t stateid;
u_int32_t rflags;
+ struct nfsmount *nmp;
+ nmp = VFSTONFS(dvp->v_mount);
*unlockedp = 0;
*nfhpp = NULL;
*dpp = NULL;
@@ -1893,8 +1895,8 @@ nfsrpc_createv4(vnode_t dvp, char *name,
*tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE |
NFSV4OPEN_ACCESSREAD);
*tl++ = txdr_unsigned(NFSV4OPEN_DENYNONE);
- *tl++ = owp->nfsow_clp->nfsc_clientid.lval[0];
- *tl = owp->nfsow_clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl = nmp->nm_sess.nfsess_clientid.lval[1];
(void) nfsm_strtom(nd, owp->nfsow_owner, NFSV4CL_LOCKNAMELEN);
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV4OPEN_CREATE);
@@ -3670,7 +3672,9 @@ nfsrpc_lockt(struct nfsrv_descript *nd,
int error, type, size;
uint8_t own[NFSV4CL_LOCKNAMELEN + NFSX_V4FHMAX];
struct nfsnode *np;
+ struct nfsmount *nmp;
+ nmp = VFSTONFS(vp->v_mount);
NFSCL_REQSTART(nd, NFSPROC_LOCKT, vp);
NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED);
if (fl->l_type == F_RDLCK)
@@ -3681,8 +3685,8 @@ nfsrpc_lockt(struct nfsrv_descript *nd,
tl += 2;
txdr_hyper(len, tl);
tl += 2;
- *tl++ = clp->nfsc_clientid.lval[0];
- *tl = clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl = nmp->nm_sess.nfsess_clientid.lval[1];
nfscl_filllockowner(id, own, flags);
np = VTONFS(vp);
NFSBCOPY(np->n_fhp->nfh_fh, &own[NFSV4CL_LOCKNAMELEN],
@@ -3810,8 +3814,8 @@ nfsrpc_lock(struct nfsrv_descript *nd, s
*tl++ = lp->nfsl_open->nfso_stateid.other[1];
*tl++ = lp->nfsl_open->nfso_stateid.other[2];
*tl++ = txdr_unsigned(lp->nfsl_seqid);
- *tl++ = lp->nfsl_open->nfso_own->nfsow_clp->nfsc_clientid.lval[0];
- *tl = lp->nfsl_open->nfso_own->nfsow_clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl = nmp->nm_sess.nfsess_clientid.lval[1];
NFSBCOPY(lp->nfsl_owner, own, NFSV4CL_LOCKNAMELEN);
NFSBCOPY(nfhp, &own[NFSV4CL_LOCKNAMELEN], fhlen);
(void)nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN + fhlen);
@@ -4055,8 +4059,8 @@ nfsrpc_renew(struct nfsclclient *clp, st
if (!NFSHASNFSV4N(nmp)) {
/* NFSv4.1 just uses a Sequence Op and not a Renew. */
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = clp->nfsc_clientid.lval[0];
- *tl = clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl = nmp->nm_sess.nfsess_clientid.lval[1];
}
nd->nd_flag |= ND_USEGSSNAME;
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
@@ -4089,8 +4093,8 @@ nfsrpc_rellockown(struct nfsmount *nmp,
nfscl_reqstart(nd, NFSPROC_RELEASELCKOWN, nmp, NULL, 0, NULL,
NULL);
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = nmp->nm_clp->nfsc_clientid.lval[0];
- *tl = nmp->nm_clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl = nmp->nm_sess.nfsess_clientid.lval[1];
NFSBCOPY(lp->nfsl_owner, own, NFSV4CL_LOCKNAMELEN);
NFSBCOPY(fh, &own[NFSV4CL_LOCKNAMELEN], fhlen);
(void)nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN + fhlen);
@@ -4443,7 +4447,7 @@ nfsrpc_destroysession(struct nfsmount *n
nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL);
NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID);
- bcopy(clp->nfsc_sessionid, tl, NFSX_V4SESSIONID);
+ bcopy(nmp->nm_sess.nfsess_sessionid, tl, NFSX_V4SESSIONID);
nd->nd_flag |= ND_USEGSSNAME;
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
@@ -4468,8 +4472,8 @@ nfsrpc_destroyclient(struct nfsmount *nm
nfscl_reqstart(nd, NFSPROC_DESTROYCLIENT, nmp, NULL, 0, NULL, NULL);
NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = clp->nfsc_clientid.lval[0];
- *tl = clp->nfsc_clientid.lval[1];
+ *tl++ = nmp->nm_sess.nfsess_clientid.lval[0];
+ *tl = nmp->nm_sess.nfsess_clientid.lval[1];
nd->nd_flag |= ND_USEGSSNAME;
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c Thu Jan 26 00:49:05 2012 (r230560)
+++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c Thu Jan 26 03:40:32 2012 (r230561)
@@ -729,8 +729,6 @@ nfscl_getcl(struct mount *mp, struct ucr
MALLOC(newclp, struct nfsclclient *,
sizeof (struct nfsclclient) + idlen - 1, M_NFSCLCLIENT,
M_WAITOK | M_ZERO);
- mtx_init(&newclp->nfsc_mtx, "ClientID lock", NULL,
- MTX_DEF | MTX_DUPOK);
}
NFSLOCKCLSTATE();
/*
@@ -740,10 +738,8 @@ nfscl_getcl(struct mount *mp, struct ucr
*/
if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
NFSUNLOCKCLSTATE();
- if (newclp != NULL) {
- mtx_destroy(&newclp->nfsc_mtx);
+ if (newclp != NULL)
free(newclp, M_NFSCLCLIENT);
- }
return (EBADF);
}
clp = nmp->nm_clp;
@@ -777,10 +773,8 @@ nfscl_getcl(struct mount *mp, struct ucr
nfscl_start_renewthread(clp);
} else {
NFSUNLOCKCLSTATE();
- if (newclp != NULL) {
- mtx_destroy(&newclp->nfsc_mtx);
+ if (newclp != NULL)
free(newclp, M_NFSCLCLIENT);
- }
}
NFSLOCKCLSTATE();
while ((clp->nfsc_flags & NFSCLFLAGS_HASCLIENTID) == 0 && !igotlock &&
@@ -1781,7 +1775,7 @@ nfscl_umount(struct nfsmount *nmp, NFSPR
{
struct nfsclclient *clp;
struct ucred *cred;
- int i, igotlock;
+ int igotlock;
/*
* For the case that matters, this is the thread that set
@@ -1850,10 +1844,7 @@ nfscl_umount(struct nfsmount *nmp, NFSPR
nfscl_cleanclient(clp);
nmp->nm_clp = NULL;
NFSFREECRED(cred);
- for (i = 0; i < NFSV4_CBSLOTS; i++)
- if (clp->nfsc_cbslots[i].nfssl_reply != NULL)
- m_freem(clp->nfsc_cbslots[i].nfssl_reply);
- FREE((caddr_t)clp, M_NFSCLCLIENT);
+ free(clp, M_NFSCLCLIENT);
} else
NFSUNLOCKCLSTATE();
}
@@ -3205,8 +3196,9 @@ printf("cbrecall\n");
error = NFSERR_SEQUENCEPOS;
if (error == 0)
error = nfsv4_seqsession(seqid, slotid,
- highslot, clp->nfsc_cbslots, &rep,
- clp->nfsc_backslots);
+ highslot,
+ clp->nfsc_nmp->nm_sess.nfsess_cbslots, &rep,
+ clp->nfsc_nmp->nm_sess.nfsess_backslots);
NFSUNLOCKCLSTATE();
if (error == 0) {
gotseq_ok = 1;
@@ -3273,7 +3265,8 @@ out:
NFSLOCKCLSTATE();
clp = nfscl_getclntsess(sessionid);
if (clp != NULL) {
- nfsv4_seqsess_cacherep(slotid, clp->nfsc_cbslots, rep);
+ nfsv4_seqsess_cacherep(slotid,
+ clp->nfsc_nmp->nm_sess.nfsess_cbslots, rep);
NFSUNLOCKCLSTATE();
} else {
NFSUNLOCKCLSTATE();
@@ -3335,8 +3328,8 @@ nfscl_getmnt(int minorvers, uint8_t *ses
if (minorvers == NFSV4_MINORVERSION) {
if (clp->nfsc_cbident == cbident)
break;
- } else if (!NFSBCMP(clp->nfsc_sessionid, sessionid,
- NFSX_V4SESSIONID))
+ } else if (!NFSBCMP(clp->nfsc_nmp->nm_sess.nfsess_sessionid,
+ sessionid, NFSX_V4SESSIONID))
break;
}
if (clp == NULL) {
@@ -3377,7 +3370,8 @@ nfscl_getclntsess(uint8_t *sessionid)
struct nfsclclient *clp;
LIST_FOREACH(clp, &nfsclhead, nfsc_list)
- if (!NFSBCMP(clp->nfsc_sessionid, sessionid, NFSX_V4SESSIONID))
+ if (!NFSBCMP(clp->nfsc_nmp->nm_sess.nfsess_sessionid, sessionid,
+ NFSX_V4SESSIONID))
break;
return (clp);
}
Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c Thu Jan 26 00:49:05 2012 (r230560)
+++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c Thu Jan 26 03:40:32 2012 (r230561)
@@ -1169,7 +1169,7 @@ mountnfs(struct nfs_args *argp, struct m
{
struct nfsmount *nmp;
struct nfsnode *np;
- int error, trycnt, ret;
+ int error, i, trycnt, ret;
struct nfsvattr nfsva;
struct nfsclclient *clp;
uint32_t lease;
@@ -1230,6 +1230,7 @@ printf("in mnt\n");
}
nmp->nm_sockreq.nr_cred = crhold(cred);
mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
+ mtx_init(&nmp->nm_sess.nfsess_mtx, "nfssession", NULL, MTX_DEF);
mp->mnt_data = nmp;
nmp->nm_getinfo = nfs_getnlminfo;
nmp->nm_vinvalbuf = ncl_vinvalbuf;
@@ -1419,12 +1420,17 @@ bad:
newnfs_disconnect(&nmp->nm_sockreq);
crfree(nmp->nm_sockreq.nr_cred);
mtx_destroy(&nmp->nm_sockreq.nr_mtx);
+ mtx_destroy(&nmp->nm_sess.nfsess_mtx);
mtx_destroy(&nmp->nm_mtx);
if (nmp->nm_clp != NULL) {
NFSLOCKCLSTATE();
LIST_REMOVE(nmp->nm_clp, nfsc_list);
NFSUNLOCKCLSTATE();
free(nmp->nm_clp, M_NFSCLCLIENT);
+ for (i = 0; i < NFSV4_CBSLOTS; i++)
+ if (nmp->nm_sess.nfsess_cbslots[i].nfssl_reply != NULL)
+ m_freem(
+ nmp->nm_sess.nfsess_cbslots[i].nfssl_reply);
}
FREE(nmp, M_NEWNFSMNT);
FREE(nam, M_SONAME);
@@ -1439,7 +1445,7 @@ nfs_unmount(struct mount *mp, int mntfla
{
struct thread *td;
struct nfsmount *nmp;
- int error, flags = 0, trycnt = 0;
+ int error, flags = 0, i, trycnt = 0;
td = curthread;
@@ -1480,6 +1486,10 @@ nfs_unmount(struct mount *mp, int mntfla
mtx_destroy(&nmp->nm_sockreq.nr_mtx);
mtx_destroy(&nmp->nm_mtx);
+ mtx_destroy(&nmp->nm_sess.nfsess_mtx);
+ for (i = 0; i < NFSV4_CBSLOTS; i++)
+ if (nmp->nm_sess.nfsess_cbslots[i].nfssl_reply != NULL)
+ m_freem(nmp->nm_sess.nfsess_cbslots[i].nfssl_reply);
FREE(nmp, M_NEWNFSMNT);
out:
return (error);
Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h Thu Jan 26 00:49:05 2012 (r230560)
+++ projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h Thu Jan 26 03:40:32 2012 (r230561)
@@ -69,6 +69,7 @@ struct nfsmount {
int nm_negnametimeo; /* timeout for -ve entries (sec) */
/* Newnfs additions */
+ struct nfsclsession nm_sess; /* Session for NFSv4.1 mount. */
struct nfsclclient *nm_clp;
uid_t nm_uid; /* Uid for SetClientID etc. */
u_int64_t nm_clval; /* identifies which clientid */
More information about the svn-src-projects
mailing list