The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=dc78533a5204ae487bf9b27badb134ffa40733ab
commit dc78533a5204ae487bf9b27badb134ffa40733ab Author: Rick Macklem <rmack...@freebsd.org> AuthorDate: 2021-01-01 22:21:51 +0000 Commit: Rick Macklem <rmack...@freebsd.org> CommitDate: 2021-01-01 22:21:51 +0000 nfsd: fix NFSv4.0 seqid handling for ERELOOKUP Commit 774a36851e0e 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. --- sys/fs/nfs/nfs.h | 1 + sys/fs/nfsserver/nfs_nfsdsocket.c | 2 ++ sys/fs/nfsserver/nfs_nfsdstate.c | 5 +++++ 3 files changed, 8 insertions(+) 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); _______________________________________________ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"