mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
nfscl: Add optional support for slots marked bad
This patch adds support for session slots marked bad
to nfsv4_sequencelookup(). An additional boolean
argument indicates if the check for slots marked bad
should be done.
The "cred" argument added to nfscl_reqstart() by
commit 326bcf9394 is now passed into nfsv4_setquence()
so that it can optionally set the boolean argument
for nfsv4_sequencelookup(). When optionally enabled,
nfsv4_setsequence() will do a DestroySession when all
slots are marked bad.
Since the code that marks slots bad is not yet committed,
this patch should not result in a semantics change.
PR: 260011
MFC after: 2 weeks
This commit is contained in:
parent
dff31ae1c5
commit
40ada74ee1
5 changed files with 59 additions and 21 deletions
|
|
@ -1121,7 +1121,7 @@ tryagain:
|
||||||
if ((nd->nd_flag & ND_LOOPBADSESS) != 0) {
|
if ((nd->nd_flag & ND_LOOPBADSESS) != 0) {
|
||||||
reterr = nfsv4_sequencelookup(nmp, sep,
|
reterr = nfsv4_sequencelookup(nmp, sep,
|
||||||
&slotpos, &maxslot, &slotseq,
|
&slotpos, &maxslot, &slotseq,
|
||||||
sessionid);
|
sessionid, true);
|
||||||
if (reterr == 0) {
|
if (reterr == 0) {
|
||||||
/* Fill in new session info. */
|
/* Fill in new session info. */
|
||||||
NFSCL_DEBUG(1,
|
NFSCL_DEBUG(1,
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ static int nfs_bigrequest[NFSV42_NPROCS] = {
|
||||||
void
|
void
|
||||||
nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
|
nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
|
||||||
u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep,
|
u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep,
|
||||||
int vers, int minorvers, __unused struct ucred *cred)
|
int vers, int minorvers, struct ucred *cred)
|
||||||
{
|
{
|
||||||
struct mbuf *mb;
|
struct mbuf *mb;
|
||||||
u_int32_t *tl;
|
u_int32_t *tl;
|
||||||
|
|
@ -416,11 +416,17 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
|
||||||
*tl = txdr_unsigned(NFSV4OP_SEQUENCE);
|
*tl = txdr_unsigned(NFSV4OP_SEQUENCE);
|
||||||
if (sep == NULL) {
|
if (sep == NULL) {
|
||||||
sep = nfsmnt_mdssession(nmp);
|
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,
|
nfsv4_setsequence(nmp, nd, sep,
|
||||||
nfs_bigreply[procnum]);
|
nfs_bigreply[procnum], cred);
|
||||||
} else
|
} else
|
||||||
nfsv4_setsequence(nmp, nd, sep,
|
nfsv4_setsequence(nmp, nd, sep,
|
||||||
nfs_bigreply[procnum]);
|
nfs_bigreply[procnum], NULL);
|
||||||
}
|
}
|
||||||
if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
|
if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
|
||||||
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
|
|
@ -4769,14 +4775,23 @@ nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, int repstat,
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
|
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;
|
uint32_t *tl, slotseq = 0;
|
||||||
int error, maxslot, slotpos;
|
int error, maxslot, slotpos;
|
||||||
uint8_t sessionid[NFSX_V4SESSIONID];
|
uint8_t sessionid[NFSX_V4SESSIONID];
|
||||||
|
|
||||||
error = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, &slotseq,
|
if (cred != NULL) {
|
||||||
sessionid);
|
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_maxreq = sep->nfsess_maxreq;
|
||||||
nd->nd_maxresp = sep->nfsess_maxresp;
|
nd->nd_maxresp = sep->nfsess_maxresp;
|
||||||
|
|
||||||
|
|
@ -4813,12 +4828,18 @@ nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
|
||||||
nd->nd_flag |= ND_HASSEQUENCE;
|
nd->nd_flag |= ND_HASSEQUENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If fnd_init is true, ignore the badslots.
|
||||||
|
* If fnd_init is false, return NFSERR_SEQMISORDERED if all slots are bad.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep,
|
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;
|
int i, maxslot, slotpos;
|
||||||
uint64_t bitval;
|
uint64_t bitval;
|
||||||
|
bool fnd_ok;
|
||||||
|
|
||||||
/* Find an unused slot. */
|
/* Find an unused slot. */
|
||||||
slotpos = -1;
|
slotpos = -1;
|
||||||
|
|
@ -4832,14 +4853,18 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep,
|
||||||
mtx_unlock(&sep->nfsess_mtx);
|
mtx_unlock(&sep->nfsess_mtx);
|
||||||
return (NFSERR_BADSESSION);
|
return (NFSERR_BADSESSION);
|
||||||
}
|
}
|
||||||
|
fnd_ok = fnd_init;
|
||||||
bitval = 1;
|
bitval = 1;
|
||||||
for (i = 0; i < sep->nfsess_foreslots; i++) {
|
for (i = 0; i < sep->nfsess_foreslots; i++) {
|
||||||
if ((bitval & sep->nfsess_slots) == 0) {
|
if ((bitval & sep->nfsess_badslots) == 0 || fnd_init) {
|
||||||
slotpos = i;
|
fnd_ok = true;
|
||||||
sep->nfsess_slots |= bitval;
|
if ((bitval & sep->nfsess_slots) == 0) {
|
||||||
sep->nfsess_slotseq[i]++;
|
slotpos = i;
|
||||||
*slotseqp = sep->nfsess_slotseq[i];
|
sep->nfsess_slots |= bitval;
|
||||||
break;
|
sep->nfsess_slotseq[i]++;
|
||||||
|
*slotseqp = sep->nfsess_slotseq[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bitval <<= 1;
|
bitval <<= 1;
|
||||||
}
|
}
|
||||||
|
|
@ -4854,10 +4879,19 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep,
|
||||||
return (ESTALE);
|
return (ESTALE);
|
||||||
}
|
}
|
||||||
/* Wake up once/sec, to check for a forced dismount. */
|
/* Wake up once/sec, to check for a forced dismount. */
|
||||||
(void)mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx,
|
if (fnd_ok)
|
||||||
PZERO, "nfsclseq", hz);
|
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) */
|
/* Now, find the highest slot in use. (nfsc_slots is 64bits) */
|
||||||
bitval = 1;
|
bitval = 1;
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
|
|
@ -4869,6 +4903,9 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep,
|
||||||
mtx_unlock(&sep->nfsess_mtx);
|
mtx_unlock(&sep->nfsess_mtx);
|
||||||
*slotposp = slotpos;
|
*slotposp = slotpos;
|
||||||
*maxslotp = maxslot;
|
*maxslotp = maxslot;
|
||||||
|
|
||||||
|
if (!fnd_ok)
|
||||||
|
return (NFSERR_SEQMISORDERED);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -358,9 +358,9 @@ int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
|
||||||
struct mbuf **, uint16_t);
|
struct mbuf **, uint16_t);
|
||||||
void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **);
|
void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **);
|
||||||
void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
|
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 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);
|
void nfsv4_freeslot(struct nfsclsession *, int, bool);
|
||||||
struct ucred *nfsrv_getgrpscred(struct ucred *);
|
struct ucred *nfsrv_getgrpscred(struct ucred *);
|
||||||
struct nfsdevice *nfsv4_findmirror(struct nfsmount *);
|
struct nfsdevice *nfsv4_findmirror(struct nfsmount *);
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ struct nfsclsession {
|
||||||
SVCXPRT *nfsess_xprt; /* For backchannel callback */
|
SVCXPRT *nfsess_xprt; /* For backchannel callback */
|
||||||
uint32_t nfsess_slotseq[64]; /* Max for 64bit nm_slots */
|
uint32_t nfsess_slotseq[64]; /* Max for 64bit nm_slots */
|
||||||
uint64_t nfsess_slots;
|
uint64_t nfsess_slots;
|
||||||
|
uint64_t nfsess_badslots; /* Slots possibly broken */
|
||||||
uint32_t nfsess_sequenceid;
|
uint32_t nfsess_sequenceid;
|
||||||
uint32_t nfsess_maxcache; /* Max size for cached reply. */
|
uint32_t nfsess_maxcache; /* Max size for cached reply. */
|
||||||
uint32_t nfsess_maxreq; /* Max request size. */
|
uint32_t nfsess_maxreq; /* Max request size. */
|
||||||
|
|
|
||||||
|
|
@ -6637,8 +6637,8 @@ nfsv4_setcbsequence(struct nfsrv_descript *nd, struct nfsclient *clp,
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
sep = *sepp;
|
sep = *sepp;
|
||||||
(void)nfsv4_sequencelookup(NULL, &sep->sess_cbsess, slotposp, &maxslot,
|
nfsv4_sequencelookup(NULL, &sep->sess_cbsess, slotposp, &maxslot,
|
||||||
&slotseq, sessionid);
|
&slotseq, sessionid, true);
|
||||||
KASSERT(maxslot >= 0, ("nfsv4_setcbsequence neg maxslot"));
|
KASSERT(maxslot >= 0, ("nfsv4_setcbsequence neg maxslot"));
|
||||||
|
|
||||||
/* Build the Sequence arguments. */
|
/* Build the Sequence arguments. */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue