git: dc78533a5204 - main - nfsd: fix NFSv4.0 seqid handling for ERELOOKUP
Rick Macklem
rmacklem at FreeBSD.org
Fri Jan 1 22:24:12 UTC 2021
The branch main has been updated by rmacklem:
URL: https://cgit.FreeBSD.org/src/commit/?id=dc78533a5204ae487bf9b27badb134ffa40733ab
commit dc78533a5204ae487bf9b27badb134ffa40733ab
Author: Rick Macklem <rmacklem at FreeBSD.org>
AuthorDate: 2021-01-01 22:21:51 +0000
Commit: Rick Macklem <rmacklem at 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);
More information about the dev-commits-src-main
mailing list