[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250129-nfsd-6-14-v3-1-506e71e39e6b@kernel.org>
Date: Wed, 29 Jan 2025 18:20:41 -0500
From: Jeff Layton <jlayton@...nel.org>
To: Chuck Lever <chuck.lever@...cle.com>, Neil Brown <neilb@...e.de>,
Olga Kornievskaia <okorniev@...hat.com>, Dai Ngo <Dai.Ngo@...cle.com>,
Tom Talpey <tom@...pey.com>, "J. Bruce Fields" <bfields@...ldses.org>
Cc: linux-nfs@...r.kernel.org, linux-kernel@...r.kernel.org,
Jeff Layton <jlayton@...nel.org>
Subject: [PATCH v3 1/6] nfsd: add routines to get/put session references
for callbacks
The existing session reference counting is too heavyweight for
callbacks. There is an atomic refcount in nfsd4_session (se_ref), but
the existing functions take a client reference alongside it, and require
the nn->client_lock. This is unnecessary for callbacks as they are
already owned by the client.
Add new nfsd4_cb_get_session() and nfsd4_cb_put_session() calls that
take and put a session reference on behalf of a callback.
Signed-off-by: Jeff Layton <jlayton@...nel.org>
---
fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++++++++++++--
fs/nfsd/state.h | 2 ++
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index cc819b8e8acdf5dcfe44c5bae45c6233f7b695e9..db68fd579ff0454153537817ee3cca71303654b4 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -234,6 +234,37 @@ static void put_client_renew(struct nfs4_client *clp)
spin_unlock(&nn->client_lock);
}
+/**
+ * nfsd4_cb_get_session - get a session reference for a callback
+ * @ses: session of which to get a reference
+ *
+ * Callbacks are different than client-driven RPCs. The caller doesn't
+ * need a reference to the nfs4_client, and doesn't want to renew the
+ * lease when putting the reference. Returns true if a session was
+ * acquired, or false otherwise (which indicates that the session is
+ * dead).
+ */
+bool nfsd4_cb_get_session(struct nfsd4_session *ses)
+{
+ if (is_session_dead(ses))
+ return false;
+ return atomic_inc_not_zero(&ses->se_ref);
+}
+
+/**
+ * nfsd4_cb_put_session - put a session reference for a callback
+ * @ses: session of which to put a reference
+ *
+ * Callbacks are different than client-driven RPCs. The caller doesn't
+ * need a reference to the nfs4_client, and doesn't want to renew the
+ * lease when putting the reference.
+ */
+void nfsd4_cb_put_session(struct nfsd4_session *ses)
+{
+ if (ses && atomic_dec_and_test(&ses->se_ref) && is_session_dead(ses))
+ free_session(ses);
+}
+
static __be32 nfsd4_get_session_locked(struct nfsd4_session *ses)
{
__be32 status;
@@ -254,8 +285,7 @@ static void nfsd4_put_session_locked(struct nfsd4_session *ses)
lockdep_assert_held(&nn->client_lock);
- if (atomic_dec_and_test(&ses->se_ref) && is_session_dead(ses))
- free_session(ses);
+ nfsd4_cb_put_session(ses);
put_client_renew_locked(clp);
}
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 74d2d7b42676d907bec9159b927aeed223d668c3..79d985d2a656e1a5b22a6a9c88f309515725e847 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -753,6 +753,8 @@ struct nfsd4_compound_state;
struct nfsd_net;
struct nfsd4_copy;
+bool nfsd4_cb_get_session(struct nfsd4_session *ses);
+void nfsd4_cb_put_session(struct nfsd4_session *ses);
extern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate, struct svc_fh *fhp,
stateid_t *stateid, int flags, struct nfsd_file **filp,
--
2.48.1
Powered by blists - more mailing lists