Date: Fri, 1 Jan 2021 22:24:12 GMT From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: dc78533a5204 - main - nfsd: fix NFSv4.0 seqid handling for ERELOOKUP Message-ID: <202101012224.101MOCWf089723@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=dc78533a5204ae487bf9b27badb134ffa40733ab commit dc78533a5204ae487bf9b27badb134ffa40733ab Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2021-01-01 22:21:51 +0000 Commit: Rick Macklem <rmacklem@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101012224.101MOCWf089723>