nfsd: fix NFSv4.0 seqid handling for ERELOOKUP
Commit 774a36851e
fixed the NFS server so that it could handle
ERELOOKUP returns from VOP calls by redoing the operation/RPC.
However, for NFSv4.0, redoing an Open would increment
the open_owner's seqid multiple times, breaking the protocol.
This patch sets a new flag called ND_ERELOOKUP on the RPC when
a redo is in progress. Then the code that increments the seqid
avoids the seqid increment/check when the flag is set, since
it indicates this has already been done for the Open.
This commit is contained in:
parent
774a36851e
commit
dc78533a52
@ -721,6 +721,7 @@ struct nfsrv_descript {
|
||||
#define ND_EXTLS 0x8000000000
|
||||
#define ND_EXTLSCERT 0x10000000000
|
||||
#define ND_EXTLSCERTUSER 0x20000000000
|
||||
#define ND_ERELOOKUP 0x40000000000
|
||||
|
||||
/*
|
||||
* ND_GSS should be the "or" of all GSS type authentications.
|
||||
|
@ -1212,8 +1212,10 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
|
||||
*/
|
||||
nfsm_trimtrailing(nd, mb, bpos, bextpg, bextpgsiz);
|
||||
nd->nd_repstat = 0;
|
||||
nd->nd_flag |= ND_ERELOOKUP;
|
||||
goto tryagain;
|
||||
}
|
||||
nd->nd_flag &= ~ND_ERELOOKUP;
|
||||
|
||||
if (statsinprog != 0) {
|
||||
nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
|
||||
|
@ -4016,6 +4016,11 @@ nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid,
|
||||
printf("refcnt=%d\n", stp->ls_op->rc_refcnt);
|
||||
panic("nfsrvstate op refcnt");
|
||||
}
|
||||
|
||||
/* If ND_ERELOOKUP is set, the seqid has already been handled. */
|
||||
if ((nd->nd_flag & ND_ERELOOKUP) != 0)
|
||||
goto out;
|
||||
|
||||
if ((stp->ls_seq + 1) == seqid) {
|
||||
if (stp->ls_op)
|
||||
nfsrvd_derefcache(stp->ls_op);
|
||||
|
Loading…
Reference in New Issue
Block a user