diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index f6acb807fc6e..44b6042a2ce7 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -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. diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index 1a54914fc9dc..530ebb8a8cc8 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -1212,8 +1212,10 @@ tryagain: */ 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, diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index f80b386ae839..1f6e8b7ef526 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -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);