The branch main has been updated by rmacklem:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4517fbfd4251180147082f94253c4347fa44f570

commit 4517fbfd4251180147082f94253c4347fa44f570
Author:     Rick Macklem <rmack...@freebsd.org>
AuthorDate: 2025-02-14 20:56:52 +0000
Commit:     Rick Macklem <rmack...@freebsd.org>
CommitDate: 2025-02-14 20:56:52 +0000

    nfscl: Add support for CB_RECALL_SLOT
    
    The callback CB_RECALL_SLOT is required for NFSv4.1/4.2.
    Fortunately, there does not appear to be any extant
    NFSv4.1/4.2 servers that use it.  Since commit b97a478896e9
    fixed handling of session slot shrinking, this patch
    adds support for CB_RECALL_SLOT, which shrinks the
    number of session slots as well.
    
    MFC after:      2 weeks
---
 sys/fs/nfs/nfs_commonkrpc.c    |  4 ++--
 sys/fs/nfs/nfs_var.h           |  1 +
 sys/fs/nfsclient/nfs_clstate.c | 18 ++++++++++++++++++
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index e35172ee2b34..0ae3b94bef89 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -123,7 +123,6 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, 
CTLFLAG_RW, &nfs_skip_wcc_da
 SYSCTL_INT(_vfs_nfs, OID_AUTO, dsretries, CTLFLAG_RW, &nfs_dsretries, 0,
     "Number of retries for a DS RPC before failure");
 
-static void    nfs_resetslots(struct nfsclsession *);
 static void    nfs_down(struct nfsmount *, struct thread *, const char *,
     int, int);
 static void    nfs_up(struct nfsmount *, struct thread *, const char *,
@@ -1474,12 +1473,13 @@ nfsmout:
 /*
  * Reset slots above nfsess_foreslots that are not busy.
  */
-static void
+void
 nfs_resetslots(struct nfsclsession *sep)
 {
        int i;
        uint64_t bitval;
 
+       mtx_assert(&sep->nfsess_mtx, MA_OWNED);
        bitval = (1 << sep->nfsess_foreslots);
        for (i = sep->nfsess_foreslots; i < NFSV4_SLOTS; i++) {
                if ((sep->nfsess_slots & bitval) == 0 &&
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 00d5b914f4af..b48d853b285e 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -780,6 +780,7 @@ int newnfs_request(struct nfsrv_descript *, struct nfsmount 
*,
     struct nfsclient *, struct nfssockreq *, vnode_t, NFSPROC_T *,
     struct ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *,
     struct nfsclsession *);
+void nfs_resetslots(struct nfsclsession *);
 int newnfs_connect(struct nfsmount *, struct nfssockreq *,
     struct ucred *, NFSPROC_T *, int, bool, struct __rpc_client **);
 void newnfs_disconnect(struct nfsmount *, struct nfssockreq *);
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 8a82fe77690e..f5621fd0a758 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -3934,6 +3934,24 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                                *tl = txdr_unsigned(NFSV4_CBSLOTS - 1);
                        }
                        break;
+               case NFSV4OP_CBRECALLSLOT:
+                       NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+                       highslot = fxdr_unsigned(uint32_t, *tl);
+                       NFSLOCKCLSTATE();
+                       clp = nfscl_getclntsess(sessionid);
+                       if (clp == NULL)
+                               error = NFSERR_SERVERFAULT;
+                       if (error == 0) {
+                               tsep = nfsmnt_mdssession(clp->nfsc_nmp);
+                               mtx_lock(&tsep->nfsess_mtx);
+                               if ((highslot + 1) < tsep->nfsess_foreslots) {
+                                       tsep->nfsess_foreslots = (highslot + 1);
+                                       nfs_resetslots(tsep);
+                               }
+                               mtx_unlock(&tsep->nfsess_mtx);
+                       }
+                       NFSUNLOCKCLSTATE();
+                       break;
                default:
                        if (i == 0 && minorvers != NFSV4_MINORVERSION)
                                error = NFSERR_OPNOTINSESS;

Reply via email to