FreeBSD Bugzilla – Attachment 182948 Details for
Bug 219581
NFSv4.1 client recovery from NFSERR_BADSESSION errors from Solaris server
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
do CreateSession with extant ClientID first for BADSESSION recovery
creatsessfirst.patch (text/plain), 6.91 KB, created by
Rick Macklem
on 2017-05-26 22:04:26 UTC
(
hide
)
Description:
do CreateSession with extant ClientID first for BADSESSION recovery
Filename:
MIME Type:
Creator:
Rick Macklem
Created:
2017-05-26 22:04:26 UTC
Size:
6.91 KB
patch
obsolete
>--- fs/nfs/nfs_var.h.orig 2017-05-26 17:26:36.190031000 -0400 >+++ fs/nfs/nfs_var.h 2017-05-26 17:27:05.894831000 -0400 >@@ -401,7 +401,7 @@ int nfsrpc_closerpc(struct nfsrv_descrip > int nfsrpc_openconfirm(vnode_t, u_int8_t *, int, struct nfsclopen *, > struct ucred *, NFSPROC_T *); > int nfsrpc_setclient(struct nfsmount *, struct nfsclclient *, int, >- struct ucred *, NFSPROC_T *); >+ struct ucred *, NFSPROC_T *, int *); > int nfsrpc_getattr(vnode_t, struct ucred *, NFSPROC_T *, > struct nfsvattr *, void *); > int nfsrpc_getattrnovp(struct nfsmount *, u_int8_t *, int, int, >--- fs/nfsclient/nfs_clstate.c.orig 2017-05-26 17:26:51.520438000 -0400 >+++ fs/nfsclient/nfs_clstate.c 2017-05-26 17:27:05.915325000 -0400 >@@ -903,7 +903,7 @@ nfscl_getcl(struct mount *mp, struct ucr > clidinusedelay = 120; > trystalecnt = 3; > do { >- error = nfsrpc_setclient(nmp, clp, 0, cred, p); >+ error = nfsrpc_setclient(nmp, clp, 0, cred, p, NULL); > if (error == NFSERR_STALECLIENTID || > error == NFSERR_STALEDONTRECOVER || > error == NFSERR_BADSESSION || >@@ -1933,7 +1933,7 @@ nfscl_umount(struct nfsmount *nmp, NFSPR > (void)nfsrpc_destroysession(nmp, clp, cred, p); > (void)nfsrpc_destroyclient(nmp, clp, cred, p); > } else >- (void)nfsrpc_setclient(nmp, clp, 0, cred, p); >+ (void)nfsrpc_setclient(nmp, clp, 0, cred, p, NULL); > nfscl_cleanclient(clp); > nmp->nm_clp = NULL; > NFSFREECRED(cred); >@@ -1963,7 +1963,7 @@ nfscl_recover(struct nfsclclient *clp, s > struct nfsreq *rep; > u_int64_t len; > u_int32_t delegtype = NFSV4OPEN_DELEGATEWRITE, mode; >- int i, igotlock = 0, error, trycnt, firstlock; >+ int i, igotlock = 0, error, trycnt, firstlock, retok; > struct nfscllayout *lyp, *nlyp; > > /* >@@ -1993,8 +1993,10 @@ nfscl_recover(struct nfsclclient *clp, s > LIST_INIT(&clp->nfsc_layouthash[i]); > > trycnt = 5; >+ retok = 0; >+ tcred = NULL; > do { >- error = nfsrpc_setclient(nmp, clp, 1, cred, p); >+ error = nfsrpc_setclient(nmp, clp, 1, cred, p, &retok); > } while ((error == NFSERR_STALECLIENTID || > error == NFSERR_BADSESSION || > error == NFSERR_STALEDONTRECOVER) && --trycnt > 0); >@@ -2026,6 +2028,10 @@ nfscl_recover(struct nfsclclient *clp, s > } > NFSUNLOCKREQ(); > >+ /* If nfsrpc_setclient() sets retok != 0, no more recovery is needed. */ >+ if (retok != 0) >+ goto out; >+ > /* > * Now, mark all delegations "need reclaim". > */ >@@ -2259,12 +2265,14 @@ nfscl_recover(struct nfsclclient *clp, s > if (NFSHASNFSV4N(nmp)) > (void)nfsrpc_reclaimcomplete(nmp, cred, p); > >+out: > NFSLOCKCLSTATE(); > clp->nfsc_flags &= ~NFSCLFLAGS_RECVRINPROG; > wakeup(&clp->nfsc_flags); > nfsv4_unlock(&clp->nfsc_lock, 0); > NFSUNLOCKCLSTATE(); >- NFSFREECRED(tcred); >+ if (tcred != NULL) >+ NFSFREECRED(tcred); > } > > /* >@@ -2313,7 +2321,7 @@ nfscl_hasexpired(struct nfsclclient *clp > cred = newnfs_getcred(); > trycnt = 5; > do { >- error = nfsrpc_setclient(nmp, clp, 0, cred, p); >+ error = nfsrpc_setclient(nmp, clp, 0, cred, p, NULL); > } while ((error == NFSERR_STALECLIENTID || > error == NFSERR_BADSESSION || > error == NFSERR_STALEDONTRECOVER) && --trycnt > 0); >--- fs/nfsclient/nfs_clrpcops.c.orig 2017-05-26 17:26:51.522899000 -0400 >+++ fs/nfsclient/nfs_clrpcops.c 2017-05-26 17:27:05.930762000 -0400 >@@ -818,7 +818,7 @@ nfsmout: > */ > APPLESTATIC int > nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, int reclaim, >- struct ucred *cred, NFSPROC_T *p) >+ struct ucred *cred, NFSPROC_T *p, int *retokp) > { > u_int32_t *tl; > struct nfsrv_descript nfsd; >@@ -830,26 +830,72 @@ nfsrpc_setclient(struct nfsmount *nmp, s > nfsquad_t confirm; > u_int32_t lease; > static u_int32_t rev = 0; >- struct nfsclds *dsp; >+ struct nfsclds *dsp, *odsp; > struct in6_addr a6; > struct nfsclsession *tsep; > >+ if (retokp != NULL) >+ *retokp = 0; > if (nfsboottime.tv_sec == 0) > NFSSETBOOTTIME(nfsboottime); > clp->nfsc_rev = rev++; > if (NFSHASNFSV4N(nmp)) { >- /* >- * Either there was no previous session or the >- * previous session has failed, so... >- * do an ExchangeID followed by the CreateSession. >- */ >- error = nfsrpc_exchangeid(nmp, clp, &nmp->nm_sockreq, >- NFSV4EXCH_USEPNFSMDS | NFSV4EXCH_USENONPNFS, &dsp, cred, p); >- NFSCL_DEBUG(1, "aft exch=%d\n", error); >- if (error == 0) >+ error = NFSERR_BADSESSION; >+ dsp = NULL; >+ NFSLOCKMNT(nmp); >+ odsp = TAILQ_FIRST(&nmp->nm_sess); >+ NFSUNLOCKMNT(nmp); >+ if (odsp != NULL) { >+ /* >+ * When a session already exists, first try a >+ * CreateSession with the extant ClientID. >+ */ >+ dsp = malloc(sizeof(struct nfsclds) + >+ odsp->nfsclds_servownlen + 1, M_NFSCLDS, >+ M_WAITOK | M_ZERO); >+ dsp->nfsclds_expire = NFSD_MONOSEC + clp->nfsc_renew; >+ dsp->nfsclds_servownlen = odsp->nfsclds_servownlen; >+ dsp->nfsclds_sess.nfsess_clientid = >+ odsp->nfsclds_sess.nfsess_clientid; >+ dsp->nfsclds_sess.nfsess_sequenceid = >+ odsp->nfsclds_sess.nfsess_sequenceid; >+ dsp->nfsclds_flags = odsp->nfsclds_flags; >+ if (dsp->nfsclds_servownlen > 0) >+ bcopy(odsp->nfsclds_serverown, >+ dsp->nfsclds_serverown, >+ dsp->nfsclds_servownlen + 1); >+ mtx_init(&dsp->nfsclds_mtx, "nfsds", NULL, MTX_DEF); >+ mtx_init(&dsp->nfsclds_sess.nfsess_mtx, "nfssession", >+ NULL, MTX_DEF); >+ nfscl_initsessionslots(&dsp->nfsclds_sess); > error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, > &nmp->nm_sockreq, > dsp->nfsclds_sess.nfsess_sequenceid, 1, cred, p); >+ NFSCL_DEBUG(1, "create session for extant " >+ "ClientID=%d\n", error); >+ if (error != 0) { >+ nfscl_freenfsclds(dsp); >+ dsp = NULL; >+ } else if (retokp != NULL) >+ *retokp = 1; >+ } >+ if (error != 0) { >+ /* >+ * Either there was no previous session or the >+ * CreateSession attempt failed, so... >+ * Do an ExchangeID followed by the CreateSession. >+ */ >+ error = nfsrpc_exchangeid(nmp, clp, &nmp->nm_sockreq, >+ NFSV4EXCH_USEPNFSMDS | NFSV4EXCH_USENONPNFS, &dsp, >+ cred, p); >+ NFSCL_DEBUG(1, "aft exch=%d\n", error); >+ if (error == 0) >+ error = nfsrpc_createsession(nmp, >+ &dsp->nfsclds_sess, &nmp->nm_sockreq, >+ dsp->nfsclds_sess.nfsess_sequenceid, 1, >+ cred, p); >+ NFSCL_DEBUG(1, "aft createsess=%d\n", error); >+ } > if (error == 0) { > NFSLOCKMNT(nmp); > /* >@@ -860,8 +906,7 @@ nfsrpc_setclient(struct nfsmount *nmp, s > tsep = NULL; > if (TAILQ_FIRST(&nmp->nm_sess) != NULL) > tsep = NFSMNT_MDSSESSION(nmp); >- TAILQ_INSERT_HEAD(&nmp->nm_sess, dsp, >- nfsclds_list); >+ TAILQ_INSERT_HEAD(&nmp->nm_sess, dsp, nfsclds_list); > /* > * Wake up RPCs waiting for a slot on the > * old session. These will then fail with >@@ -874,9 +919,8 @@ nfsrpc_setclient(struct nfsmount *nmp, s > wakeup(&tsep->nfsess_slots); > wakeup(&nmp->nm_sess); > NFSUNLOCKMNT(nmp); >- } else >+ } else if (dsp != NULL) > nfscl_freenfsclds(dsp); >- NFSCL_DEBUG(1, "aft createsess=%d\n", error); > if (error == 0 && reclaim == 0) { > error = nfsrpc_reclaimcomplete(nmp, cred, p); > NFSCL_DEBUG(1, "aft reclaimcomp=%d\n", error);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 219581
: 182948