[pnfs] [PATCH 1/2] nfs41: Add a reference to svc_serv during callback service bring up
Ricardo Labiaga
ricardo.labiaga at netapp.com
Tue Mar 4 19:03:14 EST 2008
From: Ricardo Labiaga <Ricardo.Labiaga at netapp.com>
There is only one NFSv4.1 callback service. The first caller of
nfs4_callback_up() creates the service, subsequent callers increment a
reference count on the service. The service is destroyed when the last
caller invokes nfs_callback_down().
The transport needs to hold a reference to the callback service in order
to invoke it during callback processing. Currently this reference is only
obtained when the service is first created. This is incorrect, since
subsequent registrations for other transports will leave the xprt->serv
pointer uninitialized, leading to an oops when a callback arrives on
the "unreferenced" transport.
This patch fixes the problem by ensuring that a reference to the service
is saved in xprt->serv, either because the service is created by this
invocation to nfs4_callback_up() or by a prior invocation.
Signed-off-by: Ricardo Labiaga <Ricardo.Labiaga at netapp.com>
---
fs/nfs/callback.c | 22 ++++++++++++++++------
1 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index e6a55a6..4afd42c 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -186,12 +186,6 @@ int nfs4_callback_up(struct svc_serv *serv)
*/
int nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
{
- /*
- * Save the svc_serv in the transport so that it can
- * be referenced when the session backchannel is initialized
- */
- xprt->serv = serv;
-
INIT_LIST_HEAD(&serv->sv_cb_list);
spin_lock_init(&serv->sv_cb_lock);
init_waitqueue_head(&serv->sv_cb_waitq);
@@ -236,6 +230,22 @@ int nfs_callback_up(int minorversion, void *args)
nfs_callback_info.serv = serv;
wait_for_completion(&nfs_callback_info.started);
out:
+ if (ret == 0) {
+ switch (minorversion) {
+ case 0:
+ break;
+#if defined(CONFIG_NFS_V4_1)
+ case 1:
+ /*
+ * Save the svc_serv in the transport so that it can
+ * be referenced when the session backchannel is
+ * initialized and when callbacks arrive.
+ */
+ xprt->serv = nfs_callback_info.serv;
+ break;
+#endif /* CONFIG_NFS_V4_1 */
+ }
+ }
mutex_unlock(&nfs_callback_mutex);
unlock_kernel();
return ret;
--
1.5.3.3
More information about the pNFS
mailing list