From: Ricardo Labiaga <Ricardo.Labiaga@xxxxxxxxxx> 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@xxxxxxxxxx> Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> --- fs/nfs/callback.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index be8ac50..036d66a 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -223,8 +223,13 @@ int nfs_callback_up(u32 minorversion, void *args) #endif /* CONFIG_NFS_V4_1 */ mutex_lock(&nfs_callback_mutex); - if (nfs_callback_info.users++ || nfs_callback_info.task != NULL) + if (nfs_callback_info.users++ || nfs_callback_info.task != NULL) { +#if defined(CONFIG_NFS_V4_1) + if (minorversion) + xprt->bc_serv = nfs_callback_info.serv; +#endif /* CONFIG_NFS_V4_1 */ goto out; + } serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, nfs_callback_family, NULL); if (!serv) { -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html