From owner-svn-src-projects@FreeBSD.ORG Sun Jan 29 01:01:42 2012 Return-Path: <owner-svn-src-projects@FreeBSD.ORG> Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 56A4C1065786; Sun, 29 Jan 2012 01:01:42 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3F4B48FC18; Sun, 29 Jan 2012 01:01:42 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q0T11g1Q009023; Sun, 29 Jan 2012 01:01:42 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q0T11g2f009016; Sun, 29 Jan 2012 01:01:42 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201201290101.q0T11g2f009016@svn.freebsd.org> From: Rick Macklem <rmacklem@FreeBSD.org> Date: Sun, 29 Jan 2012 01:01:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r230713 - in projects/nfsv4.1-client/sys/fs: nfs nfsclient X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" <svn-src-projects.freebsd.org> List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, <mailto:svn-src-projects-request@freebsd.org?subject=unsubscribe> List-Archive: <http://lists.freebsd.org/pipermail/svn-src-projects> List-Post: <mailto:svn-src-projects@freebsd.org> List-Help: <mailto:svn-src-projects-request@freebsd.org?subject=help> List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, <mailto:svn-src-projects-request@freebsd.org?subject=subscribe> X-List-Received-Date: Sun, 29 Jan 2012 01:01:42 -0000 Author: rmacklem Date: Sun Jan 29 01:01:41 2012 New Revision: 230713 URL: http://svn.freebsd.org/changeset/base/230713 Log: Try and fix the NFSv4.1 client so that it performs server crash recovery correctly. Mainly required the addition of NFSERR_BADSESSION to the NFSv4.0 errors (NFSERR_STALECLIENTID, NFSERR_STALESTATEID) that indicate recovery is required. Also needed to re-initialize the session slot fields and an extra argument to nfsrpc_setclient(), so that it doesn't do a RECLAIM_COMPLETE for the recovery case. Tested minimally against the Linux NFSv4.1 server. Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clport.c projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Sun Jan 29 01:01:35 2012 (r230712) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Sun Jan 29 01:01:41 2012 (r230713) @@ -975,6 +975,7 @@ if (j >= 10000) printf("n2op=%d n2st=%d\ * reply, so that recovery isn't initiated. */ if ((nd->nd_repstat == NFSERR_STALECLIENTID || + nd->nd_repstat == NFSERR_BADSESSION || nd->nd_repstat == NFSERR_STALESTATEID) && rep != NULL && (rep->r_flags & R_DONTRECOVER)) nd->nd_repstat = NFSERR_STALEDONTRECOVER; Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Sun Jan 29 01:01:35 2012 (r230712) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Sun Jan 29 01:01:41 2012 (r230713) @@ -367,7 +367,7 @@ int nfsrpc_closerpc(struct nfsrv_descrip struct nfsclopen *, struct ucred *, NFSPROC_T *, int); int nfsrpc_openconfirm(vnode_t, u_int8_t *, int, struct nfsclopen *, struct ucred *, NFSPROC_T *); -int nfsrpc_setclient(struct nfsmount *, struct nfsclclient *, +int nfsrpc_setclient(struct nfsmount *, struct nfsclclient *, int, struct ucred *, NFSPROC_T *); int nfsrpc_getattr(vnode_t, struct ucred *, NFSPROC_T *, struct nfsvattr *, void *); Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h Sun Jan 29 01:01:35 2012 (r230712) +++ projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h Sun Jan 29 01:01:41 2012 (r230713) @@ -148,7 +148,9 @@ #define NFSERR_CBPATHDOWN 10048 /* NFSv4.1 specific errors. */ +#define NFSERR_BADSESSION 10052 #define NFSERR_BADSLOT 10053 +#define NFSERR_COMPLETEALREADY 10054 #define NFSERR_LAYOUTTRYLATER 10058 #define NFSERR_SEQMISORDERED 10063 #define NFSERR_SEQUENCEPOS 10064 Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clport.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clport.c Sun Jan 29 01:01:35 2012 (r230712) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clport.c Sun Jan 29 01:01:41 2012 (r230713) @@ -1119,6 +1119,7 @@ nfscl_maperr(struct thread *td, int erro case NFSERR_STALESTATEID: case NFSERR_EXPIRED: case NFSERR_BADSTATEID: + case NFSERR_BADSESSION: printf("nfsv4 recover err returned %d\n", error); return (EIO); case NFSERR_BADHANDLE: Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Sun Jan 29 01:01:35 2012 (r230712) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Sun Jan 29 01:01:41 2012 (r230713) @@ -89,6 +89,7 @@ static int nfsrpc_getlayout(struct nfsmo nfsv4stateid_t *, struct ucred *, NFSPROC_T *); static int nfsrpc_fillsa(struct nfsmount *, struct nfsclds *, struct sockaddr_storage *, NFSPROC_T *); +static void nfscl_initsessionslots(struct nfsclsession *); /* * nfs null call from vfs. @@ -326,7 +327,8 @@ else printf(" fhl=0\n"); op->nfso_opencnt++; nfscl_openrelease(op, error, newone); if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID || - error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) { + error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || + error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_open"); } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && clidrev != 0) { @@ -335,6 +337,7 @@ else printf(" fhl=0\n"); } } while (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || + error == NFSERR_BADSESSION || ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && expireret == 0 && clidrev != 0 && retrycnt < 4)); if (error && retrycnt >= 4) @@ -519,14 +522,15 @@ nfsrpc_openrpc(struct nfsmount *nmp, vno if (ndp != NULL) FREE((caddr_t)ndp, M_NFSCLDELEG); if (ret == NFSERR_STALECLIENTID || - ret == NFSERR_STALEDONTRECOVER) + ret == NFSERR_STALEDONTRECOVER || + ret == NFSERR_BADSESSION) error = ret; } } } if (nd->nd_repstat != 0 && error == 0) error = nd->nd_repstat; - if (error == NFSERR_STALECLIENTID) + if (error == NFSERR_STALECLIENTID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(op->nfso_own->nfsow_clp); nfsmout: if (!error) @@ -570,7 +574,7 @@ nfsrpc_opendowngrade(vnode_t vp, u_int32 } if (nd->nd_repstat && error == 0) error = nd->nd_repstat; - if (error == NFSERR_STALESTATEID) + if (error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(op->nfso_own->nfsow_clp); nfsmout: mbuf_freem(nd->nd_mrep); @@ -725,7 +729,7 @@ nfsrpc_closerpc(struct nfsrv_descript *n if (nd->nd_repstat == 0) NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); error = nd->nd_repstat; - if (error == NFSERR_STALESTATEID) + if (error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(op->nfso_own->nfsow_clp); nfsmout: mbuf_freem(nd->nd_mrep); @@ -766,7 +770,7 @@ nfsrpc_openconfirm(vnode_t vp, u_int8_t op->nfso_stateid.other[2] = *tl; } error = nd->nd_repstat; - if (error == NFSERR_STALESTATEID) + if (error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(op->nfso_own->nfsow_clp); nfsmout: mbuf_freem(nd->nd_mrep); @@ -778,7 +782,7 @@ nfsmout: * when a mount has just occurred and when the server replies NFSERR_EXPIRED. */ APPLESTATIC int -nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, +nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, int reclaim, struct ucred *cred, NFSPROC_T *p) { u_int32_t *tl; @@ -799,13 +803,19 @@ nfsrpc_setclient(struct nfsmount *nmp, s error = nfsrpc_exchangeid(nmp, clp, &nmp->nm_sess, NFSV4EXCH_USEPNFSMDS | NFSV4EXCH_USENONPNFS, cred, p); if (error) printf("exch=%d\n",error); - if (error == 0) + if (error == 0) { + nfscl_initsessionslots(&nmp->nm_sess); error = nfsrpc_createsession(nmp, &nmp->nm_sess, cred, p); if (error) printf("aft crs=%d\n",error); - if (error == 0) + } + if (error == 0 && reclaim == 0) { error = nfsrpc_reclaimcomplete(nmp, cred, p); if (error) printf("aft reclcom=%d\n",error); + if (error == NFSERR_COMPLETEALREADY) + /* Ignore this error. */ + error = 0; + } return (error); } nfscl_reqstart(nd, NFSPROC_SETCLIENTID, nmp, NULL, 0, NULL, NULL); @@ -1042,7 +1052,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr else error = nfsrpc_setaclrpc(vp, cred, p, aclp, &stateid, stuff); - if (error == NFSERR_STALESTATEID) + if (error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(nmp->nm_clp); if (lckp != NULL) nfscl_lockderef(lckp); @@ -1050,7 +1060,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr (void) nfsrpc_close(vp, 0, p); if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || - error == NFSERR_OLDSTATEID) { + error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_setattr"); } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && clidrev != 0) { @@ -1059,6 +1069,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || + error == NFSERR_BADSESSION || (error == NFSERR_OLDSTATEID && retrycnt < 20) || ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && expireret == 0 && clidrev != 0 && retrycnt < 4)); @@ -1288,13 +1299,13 @@ nfsrpc_read(vnode_t vp, struct uio *uiop NFSV4OPEN_ACCESSREAD, newcred, p, &stateid, &lckp); error = nfsrpc_readrpc(vp, uiop, newcred, &stateid, p, nap, attrflagp, stuff); - if (error == NFSERR_STALESTATEID) + if (error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(nmp->nm_clp); if (lckp != NULL) nfscl_lockderef(lckp); if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || - error == NFSERR_OLDSTATEID) { + error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_read"); } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && clidrev != 0) { @@ -1303,6 +1314,7 @@ nfsrpc_read(vnode_t vp, struct uio *uiop retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || + error == NFSERR_BADSESSION || (error == NFSERR_OLDSTATEID && retrycnt < 20) || ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && expireret == 0 && clidrev != 0 && retrycnt < 4)); @@ -1456,13 +1468,13 @@ nfsrpc_write(vnode_t vp, struct uio *uio else error = nfsrpc_writerpc(vp, uiop, iomode, must_commit, newcred, &stateid, p, nap, attrflagp, stuff); - if (error == NFSERR_STALESTATEID) + if (error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(nmp->nm_clp); if (lckp != NULL) nfscl_lockderef(lckp); if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || - error == NFSERR_OLDSTATEID) { + error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_write"); } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && clidrev != 0) { @@ -1470,13 +1482,13 @@ nfsrpc_write(vnode_t vp, struct uio *uio } retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_DELAY || - ((error == NFSERR_STALESTATEID || + ((error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION || error == NFSERR_STALEDONTRECOVER) && called_from_strategy == 0) || (error == NFSERR_OLDSTATEID && retrycnt < 20) || ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && expireret == 0 && clidrev != 0 && retrycnt < 4)); if (error != 0 && (retrycnt >= 4 || - ((error == NFSERR_STALESTATEID || + ((error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION || error == NFSERR_STALEDONTRECOVER) && called_from_strategy != 0))) error = EIO; if (NFSHASNFSV4(nmp)) @@ -1790,7 +1802,8 @@ nfsrpc_create(vnode_t dvp, char *name, i (*nfhpp)->nfh_fh, (*nfhpp)->nfh_len, cred, p, &dp); nfscl_ownerrelease(owp, error, newone, unlocked); if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID || - error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) { + error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || + error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_open"); } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && clidrev != 0) { @@ -1799,6 +1812,7 @@ nfsrpc_create(vnode_t dvp, char *name, i } } while (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || + error == NFSERR_BADSESSION || ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && expireret == 0 && clidrev != 0 && retrycnt < 4)); if (error && retrycnt >= 4) @@ -2054,7 +2068,8 @@ nfsrpc_createv4(vnode_t dvp, char *name, if (dp != NULL) FREE((caddr_t)dp, M_NFSCLDELEG); if (ret == NFSERR_STALECLIENTID || - ret == NFSERR_STALEDONTRECOVER) + ret == NFSERR_STALEDONTRECOVER || + ret == NFSERR_BADSESSION) error = ret; } } @@ -2063,7 +2078,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, } if (nd->nd_repstat != 0 && error == 0) error = nd->nd_repstat; - if (error == NFSERR_STALECLIENTID) + if (error == NFSERR_STALECLIENTID || error == NFSERR_BADSESSION) nfscl_initiate_recovery(owp->nfsow_clp); nfsmout: if (!error) @@ -3646,7 +3661,8 @@ nfsrpc_advlock(vnode_t vp, off_t size, i error = nd->nd_repstat; if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || error == NFSERR_STALEDONTRECOVER || - error == NFSERR_STALECLIENTID || error == NFSERR_DELAY) { + error == NFSERR_STALECLIENTID || error == NFSERR_DELAY || + error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_advlock"); } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && clidrev != 0) { @@ -3656,6 +3672,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, i } while (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID || error == NFSERR_DELAY || error == NFSERR_STALEDONTRECOVER || error == NFSERR_STALESTATEID || + error == NFSERR_BADSESSION || ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) && expireret == 0 && clidrev != 0 && retrycnt < 4)); if (error && retrycnt >= 4) @@ -3729,7 +3746,8 @@ nfsrpc_lockt(struct nfsrv_descript *nd, error = EBADRPC; if (!error) error = nfsm_advance(nd, NFSM_RNDUP(size), -1); - } else if (nd->nd_repstat == NFSERR_STALECLIENTID) + } else if (nd->nd_repstat == NFSERR_STALECLIENTID || + nd->nd_repstat == NFSERR_BADSESSION) nfscl_initiate_recovery(clp); nfsmout: mbuf_freem(nd->nd_mrep); @@ -3776,7 +3794,8 @@ nfsrpc_locku(struct nfsrv_descript *nd, lp->nfsl_stateid.other[0] = *tl++; lp->nfsl_stateid.other[1] = *tl++; lp->nfsl_stateid.other[2] = *tl; - } else if (nd->nd_repstat == NFSERR_STALESTATEID) + } else if (nd->nd_repstat == NFSERR_STALESTATEID || + nd->nd_repstat == NFSERR_BADSESSION) nfscl_initiate_recovery(lp->nfsl_open->nfso_own->nfsow_clp); nfsmout: mbuf_freem(nd->nd_mrep); @@ -3856,7 +3875,8 @@ nfsrpc_lock(struct nfsrv_descript *nd, s error = EBADRPC; if (!error) error = nfsm_advance(nd, NFSM_RNDUP(size), -1); - } else if (nd->nd_repstat == NFSERR_STALESTATEID) + } else if (nd->nd_repstat == NFSERR_STALESTATEID || + nd->nd_repstat == NFSERR_BADSESSION) nfscl_initiate_recovery(lp->nfsl_open->nfso_own->nfsow_clp); nfsmout: mbuf_freem(nd->nd_mrep); @@ -5013,9 +5033,11 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru if (error == 0) error = nfsrpc_exchangeid(nmp, clp, &dsp->nfsclds_sess, NFSV4EXCH_USEPNFSDS, dsp->nfsclds_sock.nr_cred, p); - if (error == 0) + if (error == 0) { + nfscl_initsessionslots(&dsp->nfsclds_sess); error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, dsp->nfsclds_sock.nr_cred, p); + } if (error != 0) { NFSFREECRED(dsp->nfsclds_sock.nr_cred); free(dsp->nfsclds_sock.nr_nam, M_SONAME); @@ -5048,3 +5070,21 @@ nfsrpc_reclaimcomplete(struct nfsmount * return (error); } +/* + * Initialize the slot tables for a session. + */ +static void +nfscl_initsessionslots(struct nfsclsession *sep) +{ + int i; + + for (i = 0; i < NFSV4_CBSLOTS; i++) { + if (sep->nfsess_cbslots[i].nfssl_reply != NULL) + m_freem(sep->nfsess_cbslots[i].nfssl_reply); + NFSBZERO(&sep->nfsess_cbslots[i], sizeof(struct nfsslot)); + } + for (i = 0; i < 64; i++) + sep->nfsess_slotseq[i] = 0; + sep->nfsess_slots = 0; +} + Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c Sun Jan 29 01:01:35 2012 (r230712) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c Sun Jan 29 01:01:41 2012 (r230713) @@ -830,13 +830,15 @@ nfscl_getcl(struct mount *mp, struct ucr clidinusedelay = 120; trystalecnt = 3; do { - error = nfsrpc_setclient(nmp, clp, cred, p); + error = nfsrpc_setclient(nmp, clp, 0, cred, p); if (error == NFSERR_STALECLIENTID || error == NFSERR_STALEDONTRECOVER || + error == NFSERR_BADSESSION || error == NFSERR_CLIDINUSE) { (void) nfs_catnap(PZERO, error, "nfs_setcl"); } } while (((error == NFSERR_STALECLIENTID || + error == NFSERR_BADSESSION || error == NFSERR_STALEDONTRECOVER) && --trystalecnt > 0) || (error == NFSERR_CLIDINUSE && --clidinusedelay > 0)); if (error) { @@ -1840,7 +1842,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, cred, p); + (void)nfsrpc_setclient(nmp, clp, 0, cred, p); nfscl_cleanclient(clp); nmp->nm_clp = NULL; NFSFREECRED(cred); @@ -1851,8 +1853,9 @@ nfscl_umount(struct nfsmount *nmp, NFSPR /* * This function is called when a server replies with NFSERR_STALECLIENTID - * or NFSERR_STALESTATEID. It traverses the clientid lists, doing Opens - * and Locks with reclaim. If these fail, it deletes the corresponding state. + * NFSERR_STALESTATEID or NFSERR_BADSESSION. It traverses the clientid lists, + * doing Opens and Locks with reclaim. If these fail, it deletes the + * corresponding state. */ static void nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p) @@ -1888,8 +1891,9 @@ nfscl_recover(struct nfsclclient *clp, s panic("nfscl recover"); trycnt = 5; do { - error = nfsrpc_setclient(nmp, clp, cred, p); + error = nfsrpc_setclient(nmp, clp, 1, cred, p); } while ((error == NFSERR_STALECLIENTID || + error == NFSERR_BADSESSION || error == NFSERR_STALEDONTRECOVER) && --trycnt > 0); if (error) { nfscl_cleanclient(clp); @@ -1908,9 +1912,10 @@ nfscl_recover(struct nfsclclient *clp, s * Mark requests already queued on the server, so that they don't * initiate another recovery cycle. Any requests already in the * queue that handle state information will have the old stale - * clientid/stateid and will get a NFSERR_STALESTATEID or - * NFSERR_STALECLIENTID reply from the server. This will be - * translated to NFSERR_STALEDONTRECOVER when R_DONTRECOVER is set. + * clientid/stateid and will get a NFSERR_STALESTATEID, + * NFSERR_STALECLIENTID or NFSERR_BADSESSION reply from the server. + * This will be translated to NFSERR_STALEDONTRECOVER when + * R_DONTRECOVER is set. */ s = splsoftclock(); NFSLOCKREQ(); @@ -2209,8 +2214,9 @@ nfscl_hasexpired(struct nfsclclient *clp cred = newnfs_getcred(); trycnt = 5; do { - error = nfsrpc_setclient(nmp, clp, cred, p); + error = nfsrpc_setclient(nmp, clp, 0, cred, p); } while ((error == NFSERR_STALECLIENTID || + error == NFSERR_BADSESSION || error == NFSERR_STALEDONTRECOVER) && --trycnt > 0); if (error) { /* @@ -2447,7 +2453,8 @@ nfscl_renewthread(struct nfsclclient *cl error = nfsrpc_renew(clp, cred, p); if (error == NFSERR_CBPATHDOWN) cbpathdown = 1; - else if (error == NFSERR_STALECLIENTID) { + else if (error == NFSERR_STALECLIENTID || + error == NFSERR_BADSESSION) { NFSLOCKCLSTATE(); clp->nfsc_flags |= NFSCLFLAGS_RECOVER; NFSUNLOCKCLSTATE(); @@ -2618,8 +2625,8 @@ tryagain: } /* - * Initiate state recovery. Called when NFSERR_STALECLIENTID or - * NFSERR_STALESTATEID is received. + * Initiate state recovery. Called when NFSERR_STALECLIENTID, + * NFSERR_STALESTATEID or NFSERR_BADSESSION is received. */ APPLESTATIC void nfscl_initiate_recovery(struct nfsclclient *clp) @@ -3574,7 +3581,8 @@ nfscl_recalldeleg(struct nfsclclient *cl ret = nfscl_moveopen(vp, clp, nmp, lop, owp, dp, cred, p); if (ret == NFSERR_STALECLIENTID || - ret == NFSERR_STALEDONTRECOVER) { + ret == NFSERR_STALEDONTRECOVER || + ret == NFSERR_BADSESSION) { if (gotvp) vrele(vp); return (ret); @@ -3605,7 +3613,8 @@ nfscl_recalldeleg(struct nfsclclient *cl if (ret) { nfscl_freeopenowner(owp, 0); if (ret == NFSERR_STALECLIENTID || - ret == NFSERR_STALEDONTRECOVER) { + ret == NFSERR_STALEDONTRECOVER || + ret == NFSERR_BADSESSION) { if (gotvp) vrele(vp); return (ret); @@ -3629,7 +3638,8 @@ nfscl_recalldeleg(struct nfsclclient *cl ret = nfscl_relock(vp, clp, nmp, lp, lckp, cred, p); if (ret == NFSERR_STALESTATEID || ret == NFSERR_STALEDONTRECOVER || - ret == NFSERR_STALECLIENTID) { + ret == NFSERR_STALECLIENTID || + ret == NFSERR_BADSESSION) { if (gotvp) vrele(vp); return (ret);