--- sys/fs/nfs/nfs_var.h.orig 2022-07-09 08:19:49.000000000 -0700 +++ sys/fs/nfs/nfs_var.h 2022-07-09 08:49:48.540884000 -0700 @@ -315,7 +315,8 @@ void nfsrc_trimcache(uint64_t, uint32_t, int); /* nfs_commonsubs.c */ void nfscl_reqstart(struct nfsrv_descript *, int, struct nfsmount *, - u_int8_t *, int, u_int32_t **, struct nfsclsession *, int, int); + u_int8_t *, int, u_int32_t **, struct nfsclsession *, int, int, + struct ucred *); void nfsm_stateidtom(struct nfsrv_descript *, nfsv4stateid_t *, int); void nfscl_fillsattr(struct nfsrv_descript *, struct vattr *, vnode_t, int, u_int32_t); @@ -355,14 +356,16 @@ int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, str struct mbuf **, uint16_t); void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **); void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *, - struct nfsclsession *, int); + struct nfsclsession *, int, struct ucred *); int nfsv4_sequencelookup(struct nfsmount *, struct nfsclsession *, int *, - int *, uint32_t *, uint8_t *); + int *, uint32_t *, uint8_t *, bool); void nfsv4_freeslot(struct nfsclsession *, int, bool); struct ucred *nfsrv_getgrpscred(struct ucred *); struct nfsdevice *nfsv4_findmirror(struct nfsmount *); void nfsm_set(struct nfsrv_descript *, u_int); struct mbuf *nfsm_add_ext_pgs(struct mbuf *, int, int *); +int nfsrpc_destroysession(struct nfsmount *, struct nfsclsession *, + struct ucred *, NFSPROC_T *); /* nfs_clcomsubs.c */ void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int); @@ -529,8 +532,6 @@ int nfsrpc_exchangeid(struct nfsmount *, struct nfsclc int nfsrpc_createsession(struct nfsmount *, struct nfsclsession *, struct nfssockreq *, struct nfsclds *, uint32_t, int, struct ucred *, NFSPROC_T *); -int nfsrpc_destroysession(struct nfsmount *, struct nfsclclient *, - struct ucred *, NFSPROC_T *); int nfsrpc_destroyclient(struct nfsmount *, struct nfsclclient *, struct ucred *, NFSPROC_T *); int nfsrpc_getdeviceinfo(struct nfsmount *, uint8_t *, int, uint32_t *, --- sys/fs/nfs/nfs_commonkrpc.c.orig 2022-07-09 08:19:48.000000000 -0700 +++ sys/fs/nfs/nfs_commonkrpc.c 2022-07-09 08:51:33.526299000 -0700 @@ -919,16 +919,15 @@ tryagain: } else if (stat == RPC_TIMEDOUT) { NFSINCRGLOBAL(nfsstatsv1.rpctimeouts); error = ETIMEDOUT; +printf("Etimedout!\n"); } else if (stat == RPC_VERSMISMATCH) { NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); error = EOPNOTSUPP; } else if (stat == RPC_PROGVERSMISMATCH) { NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); error = EPROTONOSUPPORT; - } else if (stat == RPC_INTR) { - error = EINTR; } else if (stat == RPC_CANTSEND || stat == RPC_CANTRECV || - stat == RPC_SYSTEMERROR) { + stat == RPC_SYSTEMERROR || stat == RPC_INTR) { /* Check for a session slot that needs to be free'd. */ if ((nd->nd_flag & (ND_NFSV41 | ND_HASSLOTID)) == (ND_NFSV41 | ND_HASSLOTID) && nmp != NULL && @@ -949,14 +948,20 @@ tryagain: * this slot will result in an NFSERR_SEQMISORDERED * error and not a bogus cached RPC reply. */ +printf("Disable slot=%d\n", nd->nd_slotid); mtx_lock(&sep->nfsess_mtx); sep->nfsess_slotseq[nd->nd_slotid] += 10; + sep->nfsess_badslots |= (0x1ULL << nd->nd_slotid); mtx_unlock(&sep->nfsess_mtx); /* And free the slot. */ nfsv4_freeslot(sep, nd->nd_slotid, false); } - NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); - error = ENXIO; + if (stat == RPC_INTR) + error = EINTR; + else { + NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); + error = ENXIO; + } } else { NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); error = EACCES; @@ -1019,8 +1024,16 @@ tryagain: * If the first op is Sequence, free up the slot. */ if ((nmp != NULL && i == NFSV4OP_SEQUENCE && j != 0) || - (clp != NULL && i == NFSV4OP_CBSEQUENCE && j != 0)) + (clp != NULL && i == NFSV4OP_CBSEQUENCE && j != 0)) { NFSCL_DEBUG(1, "failed seq=%d\n", j); + if (sep != NULL && i == NFSV4OP_SEQUENCE && + j == NFSERR_SEQMISORDERED) { + mtx_lock(&sep->nfsess_mtx); + sep->nfsess_badslots |= + (0x1ULL << nd->nd_slotid); + mtx_unlock(&sep->nfsess_mtx); + } + } if (((nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) || (clp != NULL && i == NFSV4OP_CBSEQUENCE && j == 0)) && sep != NULL) { @@ -1039,11 +1052,35 @@ tryagain: retseq = fxdr_unsigned(uint32_t, *tl++); slot = fxdr_unsigned(int, *tl++); if ((nd->nd_flag & ND_HASSLOTID) != 0) { - if (slot != nd->nd_slotid) { + if (slot >= NFSV4_SLOTS || + (i == NFSV4OP_CBSEQUENCE && + slot >= NFSV4_CBSLOTS)) { printf("newnfs_request:" - " Wrong session " - "slot=%d\n", slot); + " Bogus slot\n"); slot = nd->nd_slotid; + } else if (slot != + nd->nd_slotid) { + printf("newnfs_request:" + " Wrong session " + "srvslot=%d " + "slot=%d\n", slot, + nd->nd_slotid); + if (i == NFSV4OP_SEQUENCE) { + /* + * Mark both slots as + * bad, because we do + * not know if the + * server has advanced + * the sequence# for + * either of them. + */ + sep->nfsess_badslots |= + (0x1ULL << slot); + sep->nfsess_badslots |= + (0x1ULL << + nd->nd_slotid); + } + slot = nd->nd_slotid; } } else if (slot != 0) { printf("newnfs_request: Bad " @@ -1096,6 +1133,7 @@ tryagain: sep = NFSMNT_MDSSESSION(nmp); if (bcmp(sep->nfsess_sessionid, nd->nd_sequence, NFSX_V4SESSIONID) == 0) { +printf("nfs_commonkrpc: initiate recovery\n"); /* Initiate recovery. */ sep->nfsess_defunct = 1; NFSCL_DEBUG(1, "Marked defunct\n"); @@ -1121,7 +1159,7 @@ tryagain: if ((nd->nd_flag & ND_LOOPBADSESS) != 0) { reterr = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, &slotseq, - sessionid); + sessionid, true); if (reterr == 0) { /* Fill in new session info. */ NFSCL_DEBUG(1, --- sys/fs/nfs/nfscl.h.orig 2022-01-25 15:13:03.000000000 -0800 +++ sys/fs/nfs/nfscl.h 2022-07-09 08:38:16.554057000 -0700 @@ -49,10 +49,10 @@ struct nfsv4node { /* * Just a macro to convert the nfscl_reqstart arguments. */ -#define NFSCL_REQSTART(n, p, v) \ +#define NFSCL_REQSTART(n, p, v, c) \ nfscl_reqstart((n), (p), VFSTONFS((v)->v_mount), \ VTONFS(v)->n_fhp->nfh_fh, VTONFS(v)->n_fhp->nfh_len, NULL, \ - NULL, 0, 0) + NULL, 0, 0, (c)) /* * These two macros convert between a lease duration and renew interval. --- sys/fs/nfs/nfs_commonsubs.c.orig 2022-07-09 08:19:49.000000000 -0700 +++ sys/fs/nfs/nfs_commonsubs.c 2022-07-09 08:38:16.602555000 -0700 @@ -323,7 +323,7 @@ static int nfs_bigrequest[NFSV42_NPROCS] = { void nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep, - int vers, int minorvers) + int vers, int minorvers, struct ucred *cred) { struct mbuf *mb; u_int32_t *tl; @@ -416,11 +416,17 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, *tl = txdr_unsigned(NFSV4OP_SEQUENCE); if (sep == NULL) { sep = nfsmnt_mdssession(nmp); + /* + * For MDS mount sessions, check for bad + * slots. If the caller does not want this + * check to be done, the "cred" argument can + * be passed in as NULL. + */ nfsv4_setsequence(nmp, nd, sep, - nfs_bigreply[procnum]); + nfs_bigreply[procnum], cred); } else nfsv4_setsequence(nmp, nd, sep, - nfs_bigreply[procnum]); + nfs_bigreply[procnum], NULL); } if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) { NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); @@ -4773,14 +4779,23 @@ nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot */ void nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd, - struct nfsclsession *sep, int dont_replycache) + struct nfsclsession *sep, int dont_replycache, struct ucred *cred) { uint32_t *tl, slotseq = 0; int error, maxslot, slotpos; uint8_t sessionid[NFSX_V4SESSIONID]; - error = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, &slotseq, - sessionid); + if (cred != NULL) { + error = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, + &slotseq, sessionid, false); + if (error == NFSERR_SEQMISORDERED) { + /* If all slots are bad, Destroy the session. */ + nfsrpc_destroysession(nmp, sep, cred, curthread); + error = 0; + } + } else + error = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, + &slotseq, sessionid, true); nd->nd_maxreq = sep->nfsess_maxreq; nd->nd_maxresp = sep->nfsess_maxresp; @@ -4817,17 +4832,24 @@ nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_d nd->nd_flag |= ND_HASSEQUENCE; } +/* + * If fnd_init is true, ignore the badslots. + * If fnd_init is false, return NFSERR_SEQMISORDERED of all slots are bad. + */ int nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep, - int *slotposp, int *maxslotp, uint32_t *slotseqp, uint8_t *sessionid) + int *slotposp, int *maxslotp, uint32_t *slotseqp, uint8_t *sessionid, + bool fnd_init) { int i, maxslot, slotpos; uint64_t bitval; + bool fnd_ok; /* Find an unused slot. */ slotpos = -1; maxslot = -1; mtx_lock(&sep->nfsess_mtx); +if (sep->nfsess_badslots != 0) printf("bad slots=0x%lx\n", sep->nfsess_badslots); do { if (nmp != NULL && sep->nfsess_defunct != 0) { /* Just return the bad session. */ @@ -4836,14 +4858,18 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsc mtx_unlock(&sep->nfsess_mtx); return (NFSERR_BADSESSION); } + fnd_ok = fnd_init; bitval = 1; for (i = 0; i < sep->nfsess_foreslots; i++) { - if ((bitval & sep->nfsess_slots) == 0) { - slotpos = i; - sep->nfsess_slots |= bitval; - sep->nfsess_slotseq[i]++; - *slotseqp = sep->nfsess_slotseq[i]; - break; + if ((bitval & sep->nfsess_badslots) == 0 || fnd_init) { + fnd_ok = true; + if ((bitval & sep->nfsess_slots) == 0) { + slotpos = i; + sep->nfsess_slots |= bitval; + sep->nfsess_slotseq[i]++; + *slotseqp = sep->nfsess_slotseq[i]; + break; + } } bitval <<= 1; } @@ -4858,10 +4884,19 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsc return (ESTALE); } /* Wake up once/sec, to check for a forced dismount. */ - (void)mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx, - PZERO, "nfsclseq", hz); + if (fnd_ok) + mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx, + PZERO, "nfsclseq", hz); } - } while (slotpos == -1); + } while (slotpos == -1 && fnd_ok); + /* + * If all slots are bad, just return slot 0 and NFSERR_SEQMISORDERED. + * The caller will do a DestroySession, so that the session's use + * will get a NFSERR_BADSESSION reply from the server. + */ + if (!fnd_ok) + slotpos = 0; + /* Now, find the highest slot in use. (nfsc_slots is 64bits) */ bitval = 1; for (i = 0; i < 64; i++) { @@ -4873,6 +4908,11 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsc mtx_unlock(&sep->nfsess_mtx); *slotposp = slotpos; *maxslotp = maxslot; + + if (!fnd_ok) +{ printf("ret seqmis\n"); + return (NFSERR_SEQMISORDERED); +} return (0); } @@ -4988,4 +5028,32 @@ nfsm_add_ext_pgs(struct mbuf *m, int maxextsiz, int *b mp = m; } return (mp); +} + +/* + * Do the NFSv4.1 Destroy Session. + */ +int +nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclsession *tsep, + struct ucred *cred, NFSPROC_T *p) +{ + uint32_t *tl; + struct nfsrv_descript nfsd; + struct nfsrv_descript *nd = &nfsd; + int error; + + nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL, 0, + 0, NULL); + NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID); + if (tsep == NULL) + tsep = nfsmnt_mdssession(nmp); + bcopy(tsep->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); + if (error != 0) + return (error); + error = nd->nd_repstat; + m_freem(nd->nd_mrep); + return (error); } --- sys/fs/nfs/nfsclstate.h.orig 2022-07-09 08:19:49.000000000 -0700 +++ sys/fs/nfs/nfsclstate.h 2022-07-09 08:38:16.584945000 -0700 @@ -67,6 +67,7 @@ struct nfsclsession { SVCXPRT *nfsess_xprt; /* For backchannel callback */ uint32_t nfsess_slotseq[64]; /* Max for 64bit nm_slots */ uint64_t nfsess_slots; + uint64_t nfsess_badslots; /* Slots possibly broken */ uint32_t nfsess_sequenceid; uint32_t nfsess_maxcache; /* Max size for cached reply. */ uint32_t nfsess_maxreq; /* Max request size. */ --- sys/fs/nfsclient/nfs_clrpcops.c.orig 2022-07-09 08:19:49.000000000 -0700 +++ sys/fs/nfsclient/nfs_clrpcops.c 2022-07-11 18:17:37.314933000 -0700 @@ -239,7 +239,7 @@ nfsrpc_null(vnode_t vp, struct ucred *cred, NFSPROC_T int error; struct nfsrv_descript nfsd, *nd = &nfsd; - NFSCL_REQSTART(nd, NFSPROC_NULL, vp); + NFSCL_REQSTART(nd, NFSPROC_NULL, vp, NULL); error = nfscl_request(nd, vp, p, cred, NULL); if (nd->nd_repstat && !error) error = nd->nd_repstat; @@ -308,7 +308,7 @@ nfsrpc_accessrpc(vnode_t vp, u_int32_t mode, struct uc *attrflagp = 0; supported = mode; - NFSCL_REQSTART(nd, NFSPROC_ACCESS, vp); + NFSCL_REQSTART(nd, NFSPROC_ACCESS, vp, cred); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(mode); if (nd->nd_flag & ND_NFSV4) { @@ -512,7 +512,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int dp = *dpp; *dpp = NULL; - nfscl_reqstart(nd, NFSPROC_OPEN, nmp, nfhp, fhlen, NULL, NULL, 0, 0); + nfscl_reqstart(nd, NFSPROC_OPEN, nmp, nfhp, fhlen, NULL, NULL, 0, 0, + cred); NFSM_BUILD(tl, u_int32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); *tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH); @@ -705,7 +706,7 @@ nfsrpc_opendowngrade(vnode_t vp, u_int32_t mode, struc struct nfsrv_descript nfsd, *nd = &nfsd; int error; - NFSCL_REQSTART(nd, NFSPROC_OPENDOWNGRADE, vp); + NFSCL_REQSTART(nd, NFSPROC_OPENDOWNGRADE, vp, cred); NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID + 3 * NFSX_UNSIGNED); if (NFSHASNFSV4N(VFSTONFS(vp->v_mount))) *tl++ = 0; @@ -870,7 +871,7 @@ nfsrpc_closerpc(struct nfsrv_descript *nd, struct nfsm int error; nfscl_reqstart(nd, NFSPROC_CLOSE, nmp, op->nfso_fh, - op->nfso_fhlen, NULL, NULL, 0, 0); + op->nfso_fhlen, NULL, NULL, 0, 0, cred); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID); if (NFSHASNFSV4N(nmp)) { *tl++ = 0; @@ -916,7 +917,7 @@ nfsrpc_openconfirm(vnode_t vp, u_int8_t *nfhp, int fhl if (NFSHASNFSV4N(nmp)) return (0); /* No confirmation for NFSv4.1. */ nfscl_reqstart(nd, NFSPROC_OPENCONFIRM, nmp, nfhp, fhlen, NULL, NULL, - 0, 0); + 0, 0, NULL); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID); *tl++ = op->nfso_stateid.seqid; *tl++ = op->nfso_stateid.other[0]; @@ -987,7 +988,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli dsp->nfsclds_sess.nfsess_clientid = odsp->nfsclds_sess.nfsess_clientid; dsp->nfsclds_sess.nfsess_sequenceid = - odsp->nfsclds_sess.nfsess_sequenceid; + odsp->nfsclds_sess.nfsess_sequenceid + 1; dsp->nfsclds_flags = odsp->nfsclds_flags; if (dsp->nfsclds_servownlen > 0) memcpy(dsp->nfsclds_serverown, @@ -1061,10 +1062,12 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli */ tsep = NULL; if (TAILQ_FIRST(&nmp->nm_sess) != NULL) { + /* + * Mark the old session defunct. Needed + * when called from nfscl_hasexpired(). + */ tsep = NFSMNT_MDSSESSION(nmp); - if (tsep->nfsess_defunct == 0) - printf("nfsrpc_setclient: " - "nfsess_defunct not set\n"); + tsep->nfsess_defunct = 1; } TAILQ_INSERT_HEAD(&nmp->nm_sess, dsp, nfsclds_list); @@ -1107,7 +1110,8 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli tsep = NFSMNT_MDSSESSION(nmp); NFSUNLOCKMNT(nmp); - nfscl_reqstart(nd, NFSPROC_SETCLIENTID, nmp, NULL, 0, NULL, NULL, 0, 0); + nfscl_reqstart(nd, NFSPROC_SETCLIENTID, nmp, NULL, 0, NULL, NULL, 0, 0, + NULL); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(nfsboottime.tv_sec); *tl = txdr_unsigned(clp->nfsc_rev); @@ -1177,7 +1181,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli * and confirm it. */ nfscl_reqstart(nd, NFSPROC_SETCLIENTIDCFRM, nmp, NULL, 0, NULL, - NULL, 0, 0); + NULL, 0, 0, NULL); NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED); *tl++ = tsep->nfsess_clientid.lval[0]; *tl++ = tsep->nfsess_clientid.lval[1]; @@ -1208,7 +1212,7 @@ nfsrpc_getattr(vnode_t vp, struct ucred *cred, NFSPROC int error; nfsattrbit_t attrbits; - NFSCL_REQSTART(nd, NFSPROC_GETATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_GETATTR, vp, cred); if (nd->nd_flag & ND_NFSV4) { NFSGETATTR_ATTRBIT(&attrbits); (void) nfsrv_putattrbit(nd, &attrbits); @@ -1236,7 +1240,8 @@ nfsrpc_getattrnovp(struct nfsmount *nmp, u_int8_t *fhp int error, vers = NFS_VER2; nfsattrbit_t attrbits; - nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, fhp, fhlen, NULL, NULL, 0, 0); + nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, fhp, fhlen, NULL, NULL, 0, 0, + cred); if (nd->nd_flag & ND_NFSV4) { vers = NFS_VER4; NFSGETATTR_ATTRBIT(&attrbits); @@ -1334,8 +1339,12 @@ nfsrpc_setattr(vnode_t vp, struct vattr *vap, NFSACL_T error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_setattr"); } else if ((error == NFSERR_EXPIRED || - error == NFSERR_BADSTATEID) && clidrev != 0) { + ((!NFSHASINT(nmp) || !NFSHASNFSV4N(nmp)) && + error == NFSERR_BADSTATEID)) && clidrev != 0) { expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p); + } else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp) && + NFSHASNFSV4N(nmp)) { + error = EIO; } retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || @@ -1362,7 +1371,7 @@ nfsrpc_setattrrpc(vnode_t vp, struct vattr *vap, nfsattrbit_t attrbits; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_SETATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_SETATTR, vp, cred); if (nd->nd_flag & ND_NFSV4) nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); vap->va_type = vnode_vtype(vp); @@ -1430,9 +1439,9 @@ nfsrpc_lookup(vnode_t dvp, char *name, int len, struct if (NFSHASNFSV4(nmp) && len == 2 && name[0] == '.' && name[1] == '.') { lookupp = 1; - NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, dvp); + NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, dvp, cred); } else { - NFSCL_REQSTART(nd, NFSPROC_LOOKUP, dvp); + NFSCL_REQSTART(nd, NFSPROC_LOOKUP, dvp, cred); (void) nfsm_strtom(nd, name, len); } if (nd->nd_flag & ND_NFSV4) { @@ -1508,7 +1517,7 @@ nfsrpc_readlink(vnode_t vp, struct uio *uiop, struct u int error, len, cangetattr = 1; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_READLINK, vp); + NFSCL_REQSTART(nd, NFSPROC_READLINK, vp, cred); if (nd->nd_flag & ND_NFSV4) { /* * And do a Getattr op. @@ -1596,8 +1605,12 @@ nfsrpc_read(vnode_t vp, struct uio *uiop, struct ucred error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_read"); } else if ((error == NFSERR_EXPIRED || - error == NFSERR_BADSTATEID) && clidrev != 0) { + ((!NFSHASINT(nmp) || !NFSHASNFSV4N(nmp)) && + error == NFSERR_BADSTATEID)) && clidrev != 0) { expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p); + } else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp) && + NFSHASNFSV4N(nmp)) { + error = EIO; } retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || @@ -1644,7 +1657,7 @@ nfsrpc_readrpc(vnode_t vp, struct uio *uiop, struct uc while (tsiz > 0) { *attrflagp = 0; len = (tsiz > rsize) ? rsize : tsiz; - NFSCL_REQSTART(nd, NFSPROC_READ, vp); + NFSCL_REQSTART(nd, NFSPROC_READ, vp, cred); if (nd->nd_flag & ND_NFSV4) nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED * 3); @@ -1768,8 +1781,12 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_write"); } else if ((error == NFSERR_EXPIRED || - error == NFSERR_BADSTATEID) && clidrev != 0) { + ((!NFSHASINT(nmp) || !NFSHASNFSV4N(nmp)) && + error == NFSERR_BADSTATEID)) && clidrev != 0) { expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p); + } else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp) && + NFSHASNFSV4N(nmp)) { + error = EIO; } retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_DELAY || @@ -1828,9 +1845,9 @@ nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iom *attrflagp = 0; len = (tsiz > wsize) ? wsize : tsiz; if (do_append) - NFSCL_REQSTART(nd, NFSPROC_APPENDWRITE, vp); + NFSCL_REQSTART(nd, NFSPROC_APPENDWRITE, vp, cred); else - NFSCL_REQSTART(nd, NFSPROC_WRITE, vp); + NFSCL_REQSTART(nd, NFSPROC_WRITE, vp, cred); if (nd->nd_flag & ND_NFSV4) { if (do_append) { NFSZERO_ATTRBIT(&attrbits); @@ -2035,7 +2052,7 @@ nfsrpc_mknod(vnode_t dvp, char *name, int namelen, str *dattrflagp = 0; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_MKNOD, dvp); + NFSCL_REQSTART(nd, NFSPROC_MKNOD, dvp, cred); if (nd->nd_flag & ND_NFSV4) { if (vtyp == VBLK || vtyp == VCHR) { NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); @@ -2185,7 +2202,7 @@ nfsrpc_createv23(vnode_t dvp, char *name, int namelen, *dattrflagp = 0; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_CREATE, dvp); + NFSCL_REQSTART(nd, NFSPROC_CREATE, dvp, cred); (void) nfsm_strtom(nd, name, namelen); if (nd->nd_flag & ND_NFSV3) { NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); @@ -2247,7 +2264,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, *dattrflagp = 0; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_CREATE, dvp); + NFSCL_REQSTART(nd, NFSPROC_CREATE, dvp, cred); /* * For V4, this is actually an Open op. */ @@ -2488,7 +2505,7 @@ tryagain: if (NFSHASNFSV4(nmp) && ret == 0) { ret = nfscl_removedeleg(vp, p, &dstateid); if (ret == 1) { - NFSCL_REQSTART(nd, NFSPROC_RETDELEGREMOVE, vp); + NFSCL_REQSTART(nd, NFSPROC_RETDELEGREMOVE, vp, cred); NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID + NFSX_UNSIGNED); if (NFSHASNFSV4N(nmp)) @@ -2509,7 +2526,7 @@ tryagain: ret = 0; } if (ret == 0) - NFSCL_REQSTART(nd, NFSPROC_REMOVE, dvp); + NFSCL_REQSTART(nd, NFSPROC_REMOVE, dvp, cred); (void) nfsm_strtom(nd, name, namelen); error = nfscl_request(nd, dvp, p, cred, dstuff); if (error) @@ -2569,11 +2586,11 @@ tryagain: ret = nfscl_renamedeleg(fvp, &fdstateid, &gotfd, tvp, &tdstateid, &gottd, p); if (gotfd && gottd) { - NFSCL_REQSTART(nd, NFSPROC_RETDELEGRENAME2, fvp); + NFSCL_REQSTART(nd, NFSPROC_RETDELEGRENAME2, fvp, cred); } else if (gotfd) { - NFSCL_REQSTART(nd, NFSPROC_RETDELEGRENAME1, fvp); + NFSCL_REQSTART(nd, NFSPROC_RETDELEGRENAME1, fvp, cred); } else if (gottd) { - NFSCL_REQSTART(nd, NFSPROC_RETDELEGRENAME1, tvp); + NFSCL_REQSTART(nd, NFSPROC_RETDELEGRENAME1, tvp, cred); } if (gotfd) { NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID); @@ -2617,7 +2634,7 @@ tryagain: ret = 0; } if (ret == 0) - NFSCL_REQSTART(nd, NFSPROC_RENAME, fdvp); + NFSCL_REQSTART(nd, NFSPROC_RENAME, fdvp, cred); if (nd->nd_flag & ND_NFSV4) { NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_GETATTR); @@ -2716,7 +2733,7 @@ nfsrpc_link(vnode_t dvp, vnode_t vp, char *name, int n *dattrflagp = 0; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_LINK, vp); + NFSCL_REQSTART(nd, NFSPROC_LINK, vp, cred); if (nd->nd_flag & ND_NFSV4) { NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_PUTFH); @@ -2783,7 +2800,7 @@ nfsrpc_symlink(vnode_t dvp, char *name, int namelen, c slen = strlen(target); if (slen > NFS_MAXPATHLEN || namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_SYMLINK, dvp); + NFSCL_REQSTART(nd, NFSPROC_SYMLINK, dvp, cred); if (nd->nd_flag & ND_NFSV4) { NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFLNK); @@ -2846,7 +2863,7 @@ nfsrpc_mkdir(vnode_t dvp, char *name, int namelen, str fhp = VTONFS(dvp)->n_fhp; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_MKDIR, dvp); + NFSCL_REQSTART(nd, NFSPROC_MKDIR, dvp, cred); if (nd->nd_flag & ND_NFSV4) { NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFDIR); @@ -2918,7 +2935,7 @@ nfsrpc_rmdir(vnode_t dvp, char *name, int namelen, str *dattrflagp = 0; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_RMDIR, dvp); + NFSCL_REQSTART(nd, NFSPROC_RMDIR, dvp, cred); (void) nfsm_strtom(nd, name, namelen); error = nfscl_request(nd, dvp, p, cred, dstuff); if (error) @@ -3035,7 +3052,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 * Joy, oh joy. For V4 we get to hand craft '.' and '..'. */ if (uiop->uio_offset == 0) { - NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, vp); + NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, vp, cred); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(NFSV4OP_GETFH); *tl = txdr_unsigned(NFSV4OP_GETATTR); @@ -3152,7 +3169,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 */ while (more_dirs && bigenough) { *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_READDIR, vp); + NFSCL_REQSTART(nd, NFSPROC_READDIR, vp, cred); if (nd->nd_flag & ND_NFSV2) { NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = cookie.lval[1]; @@ -3479,7 +3496,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui * Joy, oh joy. For V4 we get to hand craft '.' and '..'. */ if (uiop->uio_offset == 0) { - NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, vp); + NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, vp, cred); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(NFSV4OP_GETFH); *tl = txdr_unsigned(NFSV4OP_GETATTR); @@ -3601,7 +3618,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui */ while (more_dirs && bigenough) { *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_READDIRPLUS, vp); + NFSCL_REQSTART(nd, NFSPROC_READDIRPLUS, vp, cred); NFSM_BUILD(tl, u_int32_t *, 6 * NFSX_UNSIGNED); *tl++ = cookie.lval[0]; *tl++ = cookie.lval[1]; @@ -3957,7 +3974,7 @@ nfsrpc_commit(vnode_t vp, u_quad_t offset, int cnt, st struct nfsmount *nmp = VFSTONFS(vp->v_mount); *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_COMMIT, vp); + NFSCL_REQSTART(nd, NFSPROC_COMMIT, vp, cred); NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); txdr_hyper(offset, tl); tl += 2; @@ -4177,7 +4194,7 @@ nfsrpc_lockt(struct nfsrv_descript *nd, vnode_t vp, struct nfsclsession *tsep; nmp = VFSTONFS(vp->v_mount); - NFSCL_REQSTART(nd, NFSPROC_LOCKT, vp); + NFSCL_REQSTART(nd, NFSPROC_LOCKT, vp, cred); NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED); if (fl->l_type == F_RDLCK) *tl++ = txdr_unsigned(NFSV4LOCKT_READ); @@ -4248,7 +4265,7 @@ nfsrpc_locku(struct nfsrv_descript *nd, struct nfsmoun int error; nfscl_reqstart(nd, NFSPROC_LOCKU, nmp, lp->nfsl_open->nfso_fh, - lp->nfsl_open->nfso_fhlen, NULL, NULL, 0, 0); + lp->nfsl_open->nfso_fhlen, NULL, NULL, 0, 0, cred); NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID + 6 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(type); *tl = txdr_unsigned(lp->nfsl_seqid); @@ -4300,7 +4317,8 @@ nfsrpc_lock(struct nfsrv_descript *nd, struct nfsmount uint8_t own[NFSV4CL_LOCKNAMELEN + NFSX_V4FHMAX]; struct nfsclsession *tsep; - nfscl_reqstart(nd, NFSPROC_LOCK, nmp, nfhp, fhlen, NULL, NULL, 0, 0); + nfscl_reqstart(nd, NFSPROC_LOCK, nmp, nfhp, fhlen, NULL, NULL, 0, 0, + cred); NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED); if (type == F_RDLCK) *tl++ = txdr_unsigned(NFSV4LOCKT_READ); @@ -4395,7 +4413,7 @@ nfsrpc_statfs(vnode_t vp, struct nfsstatfs *sbp, struc /* * For V4, you actually do a getattr. */ - NFSCL_REQSTART(nd, NFSPROC_GETATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_GETATTR, vp, cred); NFSSTATFS_GETATTRBIT(&attrbits); (void) nfsrv_putattrbit(nd, &attrbits); nd->nd_flag |= ND_USEGSSNAME; @@ -4418,7 +4436,7 @@ nfsrpc_statfs(vnode_t vp, struct nfsstatfs *sbp, struc if (error) goto nfsmout; } else { - NFSCL_REQSTART(nd, NFSPROC_FSSTAT, vp); + NFSCL_REQSTART(nd, NFSPROC_FSSTAT, vp, NULL); error = nfscl_request(nd, vp, p, cred, stuff); if (error) return (error); @@ -4474,7 +4492,7 @@ nfsrpc_pathconf(vnode_t vp, struct nfsv3_pathconf *pc, /* * For V4, you actually do a getattr. */ - NFSCL_REQSTART(nd, NFSPROC_GETATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_GETATTR, vp, cred); NFSPATHCONF_GETATTRBIT(&attrbits); (void) nfsrv_putattrbit(nd, &attrbits); nd->nd_flag |= ND_USEGSSNAME; @@ -4491,7 +4509,7 @@ nfsrpc_pathconf(vnode_t vp, struct nfsv3_pathconf *pc, error = nd->nd_repstat; } } else { - NFSCL_REQSTART(nd, NFSPROC_PATHCONF, vp); + NFSCL_REQSTART(nd, NFSPROC_PATHCONF, vp, NULL); error = nfscl_request(nd, vp, p, cred, stuff); if (error) return (error); @@ -4527,7 +4545,7 @@ nfsrpc_fsinfo(vnode_t vp, struct nfsfsinfo *fsp, struc int error; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_FSINFO, vp); + NFSCL_REQSTART(nd, NFSPROC_FSINFO, vp, NULL); error = nfscl_request(nd, vp, p, cred, stuff); if (error) return (error); @@ -4574,10 +4592,10 @@ nfsrpc_renew(struct nfsclclient *clp, struct nfsclds * return (0); if (dsp == NULL) nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL, NULL, 0, - 0); + 0, cred); else nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL, - &dsp->nfsclds_sess, 0, 0); + &dsp->nfsclds_sess, 0, 0, NULL); if (!NFSHASNFSV4N(nmp)) { /* NFSv4.1 just uses a Sequence Op and not a Renew. */ NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); @@ -4624,11 +4642,11 @@ nfsrpc_rellockown(struct nfsmount *nmp, struct nfscllo if (NFSHASNFSV4N(nmp)) { /* For NFSv4.1, do a FreeStateID. */ nfscl_reqstart(nd, NFSPROC_FREESTATEID, nmp, NULL, 0, NULL, - NULL, 0, 0); + NULL, 0, 0, cred); nfsm_stateidtom(nd, &lp->nfsl_stateid, NFSSTATEID_PUTSTATEID); } else { nfscl_reqstart(nd, NFSPROC_RELEASELCKOWN, nmp, NULL, 0, NULL, - NULL, 0, 0); + NULL, 0, 0, NULL); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0]; @@ -4662,7 +4680,7 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpat u_int32_t *opcntp; nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL, 0, - 0); + 0, NULL); cp = dirpath; cnt = 0; do { @@ -4729,7 +4747,7 @@ nfsrpc_delegreturn(struct nfscldeleg *dp, struct ucred int error; nfscl_reqstart(nd, NFSPROC_DELEGRETURN, nmp, dp->nfsdl_fh, - dp->nfsdl_fhlen, NULL, NULL, 0, 0); + dp->nfsdl_fhlen, NULL, NULL, 0, 0, cred); NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID); if (NFSHASNFSV4N(nmp)) *tl++ = 0; @@ -4763,7 +4781,7 @@ nfsrpc_getacl(vnode_t vp, struct ucred *cred, NFSPROC_ if (nfsrv_useacl == 0 || !NFSHASNFSV4(nmp)) return (EOPNOTSUPP); - NFSCL_REQSTART(nd, NFSPROC_GETACL, vp); + NFSCL_REQSTART(nd, NFSPROC_GETACL, vp, cred); NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL); (void) nfsrv_putattrbit(nd, &attrbits); @@ -4809,7 +4827,7 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucred *cred, NFSPR if (!NFSHASNFSV4(nmp)) return (EOPNOTSUPP); - NFSCL_REQSTART(nd, NFSPROC_SETACL, vp); + NFSCL_REQSTART(nd, NFSPROC_SETACL, vp, cred); nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL); @@ -4842,7 +4860,7 @@ nfsrpc_exchangeid(struct nfsmount *nmp, struct nfsclcl if (minorvers == 0) minorvers = nmp->nm_minorvers; nfscl_reqstart(nd, NFSPROC_EXCHANGEID, nmp, NULL, 0, NULL, NULL, - NFS_VER4, minorvers); + NFS_VER4, minorvers, NULL); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(nfsboottime.tv_sec); /* Client owner */ *tl = txdr_unsigned(clp->nfsc_rev); @@ -4938,7 +4956,7 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsc else minorvers = NFSV41_MINORVERSION; nfscl_reqstart(nd, NFSPROC_CREATESESSION, nmp, NULL, 0, NULL, NULL, - NFS_VER4, minorvers); + NFS_VER4, minorvers, NULL); NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED); *tl++ = sep->nfsess_clientid.lval[0]; *tl++ = sep->nfsess_clientid.lval[1]; @@ -5056,34 +5074,6 @@ nfsmout: } /* - * Do the NFSv4.1 Destroy Session. - */ -int -nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclclient *clp, - struct ucred *cred, NFSPROC_T *p) -{ - uint32_t *tl; - struct nfsrv_descript nfsd; - struct nfsrv_descript *nd = &nfsd; - int error; - struct nfsclsession *tsep; - - nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL, 0, - 0); - NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID); - tsep = nfsmnt_mdssession(nmp); - bcopy(tsep->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); - if (error != 0) - return (error); - error = nd->nd_repstat; - m_freem(nd->nd_mrep); - return (error); -} - -/* * Do the NFSv4.1 Destroy Client. */ int @@ -5097,7 +5087,7 @@ nfsrpc_destroyclient(struct nfsmount *nmp, struct nfsc struct nfsclsession *tsep; nfscl_reqstart(nd, NFSPROC_DESTROYCLIENT, nmp, NULL, 0, NULL, NULL, 0, - 0); + 0, NULL); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0]; @@ -5126,7 +5116,7 @@ nfsrpc_layoutget(struct nfsmount *nmp, uint8_t *fhp, i int error; nfscl_reqstart(nd, NFSPROC_LAYOUTGET, nmp, fhp, fhlen, NULL, NULL, 0, - 0); + 0, cred); nfsrv_setuplayoutget(nd, iomode, offset, len, minlen, stateidp, layouttype, layoutlen, 0); nd->nd_flag |= ND_USEGSSNAME; @@ -5170,7 +5160,7 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *de ndi = NULL; gotdspp = NULL; nfscl_reqstart(nd, NFSPROC_GETDEVICEINFO, nmp, NULL, 0, NULL, NULL, 0, - 0); + 0, cred); NFSM_BUILD(tl, uint32_t *, NFSX_V4DEVICEID + 3 * NFSX_UNSIGNED); NFSBCOPY(deviceid, tl, NFSX_V4DEVICEID); tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); @@ -5391,7 +5381,7 @@ nfsrpc_layoutcommit(struct nfsmount *nmp, uint8_t *fh, int error; nfscl_reqstart(nd, NFSPROC_LAYOUTCOMMIT, nmp, fh, fhlen, NULL, NULL, - 0, 0); + 0, 0, cred); NFSM_BUILD(tl, uint32_t *, 5 * NFSX_UNSIGNED + 3 * NFSX_HYPER + NFSX_STATEID); txdr_hyper(off, tl); @@ -5442,7 +5432,7 @@ nfsrpc_layoutreturn(struct nfsmount *nmp, uint8_t *fh, int error; nfscl_reqstart(nd, NFSPROC_LAYOUTRETURN, nmp, fh, fhlen, NULL, NULL, - 0, 0); + 0, 0, cred); NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED); if (reclaim != 0) *tl++ = newnfs_true; @@ -5528,7 +5518,7 @@ nfsrpc_layouterror(struct nfsmount *nmp, uint8_t *fh, int error; nfscl_reqstart(nd, NFSPROC_LAYOUTERROR, nmp, fh, fhlen, NULL, NULL, - 0, 0); + 0, 0, cred); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_HYPER + NFSX_STATEID + NFSX_V4DEVICEID + 3 * NFSX_UNSIGNED); txdr_hyper(offset, tl); tl += 2; @@ -5837,7 +5827,7 @@ nfsrpc_reclaimcomplete(struct nfsmount *nmp, struct uc int error; nfscl_reqstart(nd, NFSPROC_RECLAIMCOMPL, nmp, NULL, 0, NULL, NULL, 0, - 0); + 0, cred); NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = newnfs_false; nd->nd_flag |= ND_USEGSSNAME; @@ -5866,6 +5856,7 @@ nfscl_initsessionslots(struct nfsclsession *sep) for (i = 0; i < 64; i++) sep->nfsess_slotseq[i] = 0; sep->nfsess_slots = 0; + sep->nfsess_badslots = 0; } /* @@ -6460,7 +6451,8 @@ nfsrpc_readds(vnode_t vp, struct uio *uiop, nfsv4state nd->nd_mrep = NULL; if (vers == 0 || vers == NFS_VER4) { nfscl_reqstart(nd, NFSPROC_READDS, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); vers = NFS_VER4; NFSCL_DEBUG(4, "nfsrpc_readds: vers4 minvers=%d\n", minorvers); if (flex != 0) @@ -6469,7 +6461,8 @@ nfsrpc_readds(vnode_t vp, struct uio *uiop, nfsv4state nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSEQIDZERO); } else { nfscl_reqstart(nd, NFSPROC_READ, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READ]); NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READDS]); NFSCL_DEBUG(4, "nfsrpc_readds: vers3\n"); @@ -6536,7 +6529,8 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomo nd->nd_mrep = NULL; if (vers == 0 || vers == NFS_VER4) { nfscl_reqstart(nd, NFSPROC_WRITEDS, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); NFSCL_DEBUG(4, "nfsrpc_writeds: vers4 minvers=%d\n", minorvers); vers = NFS_VER4; if (flex != 0) @@ -6546,7 +6540,8 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomo NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED); } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writeds: vers3\n"); @@ -6669,7 +6664,8 @@ nfsrpc_writedsmir(vnode_t vp, int *iomode, int *must_c nd->nd_mrep = NULL; if (vers == 0 || vers == NFS_VER4) { nfscl_reqstart(nd, NFSPROC_WRITEDS, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); vers = NFS_VER4; NFSCL_DEBUG(4, "nfsrpc_writedsmir: vers4 minvers=%d\n", minorvers); @@ -6677,7 +6673,8 @@ nfsrpc_writedsmir(vnode_t vp, int *iomode, int *must_c NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED); } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writedsmir: vers3\n"); @@ -6897,11 +6894,13 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, nd->nd_mrep = NULL; if (vers == 0 || vers == NFS_VER4) { nfscl_reqstart(nd, NFSPROC_COMMITDS, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); vers = NFS_VER4; } else { nfscl_reqstart(nd, NFSPROC_COMMIT, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, + NULL); NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMIT]); NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMITDS]); } @@ -7016,7 +7015,7 @@ nfsrpc_advise(vnode_t vp, off_t offset, uint64_t cnt, NFSSETBIT_ATTRBIT(&hints, NFSV4IOHINT_DONTNEED); else return (0); - NFSCL_REQSTART(nd, NFSPROC_IOADVISE, vp); + NFSCL_REQSTART(nd, NFSPROC_IOADVISE, vp, cred); nfsm_stateidtom(nd, NULL, NFSSTATEID_PUTALLZERO); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_HYPER); txdr_hyper(offset, tl); @@ -7060,7 +7059,7 @@ nfsrpc_adviseds(vnode_t vp, uint64_t offset, int cnt, return (0); nd->nd_mrep = NULL; nfscl_reqstart(nd, NFSPROC_IOADVISEDS, nmp, fhp->nfh_fh, - fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers, NULL); vers = NFS_VER4; NFSCL_DEBUG(4, "nfsrpc_adviseds: vers=%d minvers=%d\n", vers, minorvers); @@ -7199,9 +7198,11 @@ nfsrpc_allocate(vnode_t vp, off_t off, off_t len, stru error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_allocate"); - } else if ((error == NFSERR_EXPIRED || - error == NFSERR_BADSTATEID) && clidrev != 0) { + } else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) && + error == NFSERR_BADSTATEID)) && clidrev != 0) { expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p); + } else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) { + error = EIO; } retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_DELAY || @@ -7230,7 +7231,7 @@ nfsrpc_allocaterpc(vnode_t vp, off_t off, off_t len, n nfsattrbit_t attrbits; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_ALLOCATE, vp); + NFSCL_REQSTART(nd, NFSPROC_ALLOCATE, vp, cred); nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_HYPER + NFSX_UNSIGNED); txdr_hyper(off, tl); tl += 2; @@ -7718,7 +7719,7 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, *dpp = NULL; *laystatp = ENXIO; nfscl_reqstart(nd, NFSPROC_OPENLAYGET, nmp, nfhp, fhlen, NULL, NULL, - 0, 0); + 0, 0, cred); NFSM_BUILD(tl, uint32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); *tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH); @@ -7903,7 +7904,7 @@ nfsrpc_createlayout(vnode_t dvp, char *name, int namel *dattrflagp = 0; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); - NFSCL_REQSTART(nd, NFSPROC_CREATELAYGET, dvp); + NFSCL_REQSTART(nd, NFSPROC_CREATELAYGET, dvp, cred); /* * For V4, this is actually an Open op. */ @@ -8300,10 +8301,12 @@ nfsrpc_copy_file_range(vnode_t invp, off_t *inoffp, vn error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_cfr"); - } else if ((error == NFSERR_EXPIRED || - error == NFSERR_BADSTATEID) && clidrev != 0) { + } else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) && + error == NFSERR_BADSTATEID)) && clidrev != 0) { expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, curthread); + } else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) { + error = EIO; } retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_DELAY || @@ -8344,7 +8347,7 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outv *lenp = 0; if (len > nfs_maxcopyrange) len = nfs_maxcopyrange; - NFSCL_REQSTART(nd, NFSPROC_COPY, invp); + NFSCL_REQSTART(nd, NFSPROC_COPY, invp, cred); NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_GETATTR); NFSGETATTR_ATTRBIT(&attrbits); @@ -8477,10 +8480,12 @@ nfsrpc_seek(vnode_t vp, off_t *offp, bool *eofp, int c error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) { (void) nfs_catnap(PZERO, error, "nfs_seek"); - } else if ((error == NFSERR_EXPIRED || - error == NFSERR_BADSTATEID) && clidrev != 0) { + } else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) && + error == NFSERR_BADSTATEID)) && clidrev != 0) { expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, curthread); + } else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) { + error = EIO; } retrycnt++; } while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || @@ -8509,7 +8514,7 @@ nfsrpc_seekrpc(vnode_t vp, off_t *offp, nfsv4stateid_t nfsattrbit_t attrbits; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_SEEK, vp); + NFSCL_REQSTART(nd, NFSPROC_SEEK, vp, cred); nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED); txdr_hyper(*offp, tl); tl += 2; @@ -8553,7 +8558,7 @@ nfsrpc_getextattr(vnode_t vp, const char *name, struct uint32_t len, len2; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_GETEXTATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_GETEXTATTR, vp, cred); nfsm_strtom(nd, name, strlen(name)); NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_GETATTR); @@ -8623,7 +8628,7 @@ nfsrpc_setextattr(vnode_t vp, const char *name, struct nfsattrbit_t attrbits; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_SETEXTATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_SETEXTATTR, vp, cred); if (uiop->uio_resid > nd->nd_maxreq) { /* nd_maxreq is set by NFSCL_REQSTART(). */ m_freem(nd->nd_mreq); @@ -8671,7 +8676,7 @@ nfsrpc_rmextattr(vnode_t vp, const char *name, struct nfsattrbit_t attrbits; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_RMEXTATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_RMEXTATTR, vp, cred); nfsm_strtom(nd, name, strlen(name)); NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_GETATTR); @@ -8711,7 +8716,7 @@ nfsrpc_listextattr(vnode_t vp, uint64_t *cookiep, stru u_char c; *attrflagp = 0; - NFSCL_REQSTART(nd, NFSPROC_LISTEXTATTR, vp); + NFSCL_REQSTART(nd, NFSPROC_LISTEXTATTR, vp, cred); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED); txdr_hyper(*cookiep, tl); tl += 2; *tl++ = txdr_unsigned(*lenp); @@ -8885,7 +8890,7 @@ nfsrpc_bindconnsess(CLIENT *cl, void *arg, struct ucre int error; nfscl_reqstart(nd, NFSPROC_BINDCONNTOSESS, NULL, NULL, 0, NULL, NULL, - NFS_VER4, rcp->minorvers); + NFS_VER4, rcp->minorvers, NULL); NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 2 * NFSX_UNSIGNED); memcpy(tl, rcp->sessionid, NFSX_V4SESSIONID); tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; --- sys/fs/nfsclient/nfs_clstate.c.orig 2022-07-09 08:19:49.000000000 -0700 +++ sys/fs/nfsclient/nfs_clstate.c 2022-07-09 08:38:16.521619000 -0700 @@ -2089,7 +2089,7 @@ nfscl_umount(struct nfsmount *nmp, NFSPROC_T *p, struc nfscl_delegreturnall(clp, p, dhp); cred = newnfs_getcred(); if (NFSHASNFSV4N(nmp)) { - (void)nfsrpc_destroysession(nmp, clp, cred, p); + (void)nfsrpc_destroysession(nmp, NULL, cred, p); (void)nfsrpc_destroyclient(nmp, clp, cred, p); } else (void)nfsrpc_setclient(nmp, clp, 0, NULL, cred, p); --- sys/fs/nfsserver/nfs_nfsdstate.c.orig 2022-07-09 08:19:49.000000000 -0700 +++ sys/fs/nfsserver/nfs_nfsdstate.c 2022-07-09 08:38:16.621287000 -0700 @@ -6638,7 +6638,7 @@ nfsv4_setcbsequence(struct nfsrv_descript *nd, struct return (error); sep = *sepp; (void)nfsv4_sequencelookup(NULL, &sep->sess_cbsess, slotposp, &maxslot, - &slotseq, sessionid); + &slotseq, sessionid, true); KASSERT(maxslot >= 0, ("nfsv4_setcbsequence neg maxslot")); /* Build the Sequence arguments. */ --- sys/fs/nfsserver/nfs_nfsdport.c.orig 2022-07-09 08:19:49.000000000 -0700 +++ sys/fs/nfsserver/nfs_nfsdport.c 2022-07-09 08:48:36.841795000 -0700 @@ -5235,7 +5235,7 @@ nfsrv_readdsrpc(fhandle_t *fhp, off_t off, int len, st st.other[2] = 0x55555555; st.seqid = 0xffffffff; nfscl_reqstart(nd, NFSPROC_READDS, nmp, (u_int8_t *)fhp, sizeof(*fhp), - NULL, NULL, 0, 0); + NULL, NULL, 0, 0, cred); nfsm_stateidtom(nd, &st, NFSSTATEID_PUTSTATEID); NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED * 3); txdr_hyper(off, tl); @@ -5343,7 +5343,7 @@ nfsrv_writedsdorpc(struct nfsmount *nmp, fhandle_t *fh nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO); nfscl_reqstart(nd, NFSPROC_WRITE, nmp, (u_int8_t *)fhp, - sizeof(fhandle_t), NULL, NULL, 0, 0); + sizeof(fhandle_t), NULL, NULL, 0, 0, cred); /* * Use a stateid where other is an alternating 01010 pattern and @@ -5565,7 +5565,7 @@ nfsrv_allocatedsdorpc(struct nfsmount *nmp, fhandle_t nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO); nfscl_reqstart(nd, NFSPROC_ALLOCATE, nmp, (u_int8_t *)fhp, - sizeof(fhandle_t), NULL, NULL, 0, 0); + sizeof(fhandle_t), NULL, NULL, 0, 0, cred); /* * Use a stateid where other is an alternating 01010 pattern and @@ -5719,7 +5719,7 @@ nfsrv_setattrdsdorpc(fhandle_t *fhp, struct ucred *cre st.other[2] = 0x55555555; st.seqid = 0xffffffff; nfscl_reqstart(nd, NFSPROC_SETATTR, nmp, (u_int8_t *)fhp, sizeof(*fhp), - NULL, NULL, 0, 0); + NULL, NULL, 0, 0, cred); nfsm_stateidtom(nd, &st, NFSSTATEID_PUTSTATEID); nfscl_fillsattr(nd, &nap->na_vattr, vp, NFSSATTR_FULL, 0); @@ -5904,7 +5904,7 @@ nfsrv_setacldsdorpc(fhandle_t *fhp, struct ucred *cred st.other[2] = 0x55555555; st.seqid = 0xffffffff; nfscl_reqstart(nd, NFSPROC_SETACL, nmp, (u_int8_t *)fhp, sizeof(*fhp), - NULL, NULL, 0, 0); + NULL, NULL, 0, 0, cred); nfsm_stateidtom(nd, &st, NFSSTATEID_PUTSTATEID); NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL); @@ -6039,7 +6039,7 @@ nfsrv_getattrdsrpc(fhandle_t *fhp, struct ucred *cred, NFSD_DEBUG(4, "in nfsrv_getattrdsrpc\n"); nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO); nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, (u_int8_t *)fhp, - sizeof(fhandle_t), NULL, NULL, 0, 0); + sizeof(fhandle_t), NULL, NULL, 0, 0, cred); NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_CHANGE); @@ -6107,7 +6107,7 @@ nfsrv_seekdsrpc(fhandle_t *fhp, off_t *offp, int conte st.seqid = 0xffffffff; nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO); nfscl_reqstart(nd, NFSPROC_SEEKDS, nmp, (u_int8_t *)fhp, - sizeof(fhandle_t), NULL, NULL, 0, 0); + sizeof(fhandle_t), NULL, NULL, 0, 0, cred); nfsm_stateidtom(nd, &st, NFSSTATEID_PUTSTATEID); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + NFSX_UNSIGNED); txdr_hyper(*offp, tl); tl += 2;