]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFSv4: Track the number of referring calls in struct cb_process_state
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 15 Nov 2023 18:55:27 +0000 (13:55 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Thu, 4 Jan 2024 15:47:56 +0000 (10:47 -0500)
When the server gives us a set of referring calls, to tell us that the
NFSv4.1 callback needs to be ordered with respect to those calls, then
we may want to make that information available to the operations. In
certain cases, it may allow them to optimise their behaviour due to the
extra knowledge.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/callback.h
fs/nfs/callback_proc.c

index ccd4f245cae240b812c3a7e6d44e2de32de819c5..cc1b6620a0c22f399255c29724fafdb23b7395ad 100644 (file)
@@ -40,11 +40,12 @@ enum nfs4_callback_opnum {
 
 struct nfs4_slot;
 struct cb_process_state {
-       __be32                  drc_status;
        struct nfs_client       *clp;
        struct nfs4_slot        *slot;
-       u32                     minorversion;
        struct net              *net;
+       u32                     minorversion;
+       __be32                  drc_status;
+       unsigned int            referring_calls;
 };
 
 struct cb_compound_hdr_arg {
index 96a4923080ae2880fd3f13cd8a2261f197f24d3b..5d7fe37d226c8824979b228dde4abe628b60e5d3 100644 (file)
@@ -450,6 +450,7 @@ static int referring_call_exists(struct nfs_client *clp,
        __acquires(lock)
 {
        int status = 0;
+       int found = 0;
        int i, j;
        struct nfs4_session *session;
        struct nfs4_slot_table *tbl;
@@ -478,11 +479,12 @@ static int referring_call_exists(struct nfs_client *clp,
                        spin_lock(lock);
                        if (status)
                                goto out;
+                       found++;
                }
        }
 
 out:
-       return status;
+       return status < 0 ? status : found;
 }
 
 __be32 nfs4_callback_sequence(void *argp, void *resp,
@@ -493,6 +495,7 @@ __be32 nfs4_callback_sequence(void *argp, void *resp,
        struct nfs4_slot_table *tbl;
        struct nfs4_slot *slot;
        struct nfs_client *clp;
+       int ret;
        int i;
        __be32 status = htonl(NFS4ERR_BADSESSION);
 
@@ -552,11 +555,13 @@ __be32 nfs4_callback_sequence(void *argp, void *resp,
         * related callback was received before the response to the original
         * call.
         */
-       if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists,
-                               &tbl->slot_tbl_lock) < 0) {
+       ret = referring_call_exists(clp, args->csa_nrclists, args->csa_rclists,
+                                   &tbl->slot_tbl_lock);
+       if (ret < 0) {
                status = htonl(NFS4ERR_DELAY);
                goto out_unlock;
        }
+       cps->referring_calls = ret;
 
        /*
         * RFC5661 20.9.3