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"

Reply via email to