The branch main has been updated by rmacklem:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7a606f280a3e174dcdd12736b7b976903809eb9c

commit 7a606f280a3e174dcdd12736b7b976903809eb9c
Author:     Rick Macklem <rmack...@freebsd.org>
AuthorDate: 2021-04-05 01:15:54 +0000
Commit:     Rick Macklem <rmack...@freebsd.org>
CommitDate: 2021-04-05 01:15:54 +0000

    nfsd: make the server repeat CB_RECALL every couple of seconds
    
    Commit 01ae8969a9ee stopped the NFSv4.1/4.2 server from implicitly
    binding the back channel to a new TCP connection so that it
    conforms to RFC5661, for NFSv4.1/4.2. An effect of this
    for the Linux NFS client is that it will do a
    BindConnectionToSession when it sees NFSV4SEQ_CBPATHDOWN
    set in a sequence reply. This will fix the back channel, but the
    first attempt at a callback like CB_RECALL will already have
    failed. Without this patch, a CB_RECALL will not be retried
    and that can result in a 5 minute delay until the delegation
    times out.
    
    This patch modifies the code so that it will retry the
    CB_RECALL every couple of seconds, often avoiding the
    5 minute delay.
    
    This is not critical for correct behaviour, but avoids
    the 5 minute delay for the case where the Linux client
    re-binds the back channel via BindConnectionToSession.
    
    MFC after:      2 weeks
---
 sys/fs/nfs/nfsrvstate.h          |  2 ++
 sys/fs/nfsserver/nfs_nfsdstate.c | 20 ++++++++++++++------
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/sys/fs/nfs/nfsrvstate.h b/sys/fs/nfs/nfsrvstate.h
index 2d60e8e8141f..427d5b132281 100644
--- a/sys/fs/nfs/nfsrvstate.h
+++ b/sys/fs/nfs/nfsrvstate.h
@@ -220,6 +220,7 @@ struct nfsstate {
                        time_t          expiry;
                        time_t          limit;
                        u_int64_t       compref;
+                       time_t          last;
                } deleg;
        } ls_un;
        struct nfslockfile      *ls_lfp;        /* Back pointer */
@@ -238,6 +239,7 @@ struct nfsstate {
 #define        ls_delegtime            ls_un.deleg.expiry
 #define        ls_delegtimelimit       ls_un.deleg.limit
 #define        ls_compref              ls_un.deleg.compref
+#define        ls_lastrecall           ls_un.deleg.last
 
 /*
  * Nfs lock structure.
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 1cf0dcee99e9..fa7bb3ba9f56 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -3070,6 +3070,7 @@ tryagain:
                new_deleg->ls_clp = clp;
                new_deleg->ls_filerev = filerev;
                new_deleg->ls_compref = nd->nd_compref;
+               new_deleg->ls_lastrecall = 0;
                LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file);
                LIST_INSERT_HEAD(NFSSTATEHASH(clp,
                    new_deleg->ls_stateid), new_deleg, ls_hash);
@@ -3191,6 +3192,7 @@ tryagain:
                        new_deleg->ls_clp = clp;
                        new_deleg->ls_filerev = filerev;
                        new_deleg->ls_compref = nd->nd_compref;
+                       new_deleg->ls_lastrecall = 0;
                        nfsrv_writedelegcnt++;
                        LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file);
                        LIST_INSERT_HEAD(NFSSTATEHASH(clp,
@@ -3261,6 +3263,7 @@ tryagain:
                        new_deleg->ls_clp = clp;
                        new_deleg->ls_filerev = filerev;
                        new_deleg->ls_compref = nd->nd_compref;
+                       new_deleg->ls_lastrecall = 0;
                        LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file);
                        LIST_INSERT_HEAD(NFSSTATEHASH(clp,
                            new_deleg->ls_stateid), new_deleg, ls_hash);
@@ -3339,6 +3342,7 @@ tryagain:
                                new_deleg->ls_clp = clp;
                                new_deleg->ls_filerev = filerev;
                                new_deleg->ls_compref = nd->nd_compref;
+                               new_deleg->ls_lastrecall = 0;
                                LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg,
                                    ls_file);
                                LIST_INSERT_HEAD(NFSSTATEHASH(clp,
@@ -5265,7 +5269,8 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, 
NFSPROC_T *p,
         * - check to see if the delegation has expired
         *   - if so, get the v4root lock and then expire it
         */
-       if (!(stp->ls_flags & NFSLCK_DELEGRECALL)) {
+       if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0 || stp->ls_lastrecall <
+           time_uptime) {
                /*
                 * - do a recall callback, since not yet done
                 * For now, never allow truncate to be set. To use
@@ -5280,11 +5285,14 @@ nfsrv_delegconflict(struct nfsstate *stp, int 
*haslockp, NFSPROC_T *p,
                 * will be extended when ops are done on the delegation
                 * stateid, up to the timelimit.)
                 */
-               stp->ls_delegtime = NFSD_MONOSEC + (2 * nfsrv_lease) +
-                   NFSRV_LEASEDELTA;
-               stp->ls_delegtimelimit = NFSD_MONOSEC + (6 * nfsrv_lease) +
-                   NFSRV_LEASEDELTA;
-               stp->ls_flags |= NFSLCK_DELEGRECALL;
+               if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0) {
+                       stp->ls_delegtime = NFSD_MONOSEC + (2 * nfsrv_lease) +
+                           NFSRV_LEASEDELTA;
+                       stp->ls_delegtimelimit = NFSD_MONOSEC + (6 *
+                           nfsrv_lease) + NFSRV_LEASEDELTA;
+                       stp->ls_flags |= NFSLCK_DELEGRECALL;
+               }
+               stp->ls_lastrecall = time_uptime + 1;
 
                /*
                 * Loop NFSRV_CBRETRYCNT times while the CBRecall replies
_______________________________________________
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