From patchwork Tue Nov 30 20:31:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Adamson X-Patchwork-Id: 369061 X-Patchwork-Delegate: Trond.Myklebust@netapp.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oAUMTd9k024662 for ; Tue, 30 Nov 2010 22:29:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753925Ab0K3W3O (ORCPT ); Tue, 30 Nov 2010 17:29:14 -0500 Received: from mx2.netapp.com ([216.240.18.37]:26569 "EHLO mx2.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754899Ab0K3W3H (ORCPT ); Tue, 30 Nov 2010 17:29:07 -0500 X-IronPort-AV: E=Sophos;i="4.59,282,1288594800"; d="scan'208";a="489187666" Received: from smtp1.corp.netapp.com ([10.57.156.124]) by mx2-out.netapp.com with ESMTP; 30 Nov 2010 14:29:07 -0800 Received: from localhost.localdomain (verdan01-lxp.hq.netapp.com [10.58.48.142] (may be forged)) by smtp1.corp.netapp.com (8.13.1/8.13.1/NTAP-1.6) with ESMTP id oAUMT3Zn011288; Tue, 30 Nov 2010 14:29:06 -0800 (PST) From: andros@netapp.com To: trond.myklebust@netapp.com Cc: linux-nfs@vger.kernel.org, Andy Adamson Subject: [PATCH 3/5] NFS associate sessionid with callback connection Date: Tue, 30 Nov 2010 15:31:09 -0500 Message-Id: <1291149071-2026-4-git-send-email-andros@netapp.com> X-Mailer: git-send-email 1.6.6 In-Reply-To: <1291149071-2026-3-git-send-email-andros@netapp.com> References: <1291149071-2026-1-git-send-email-andros@netapp.com> <1291149071-2026-2-git-send-email-andros@netapp.com> <1291149071-2026-3-git-send-email-andros@netapp.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 30 Nov 2010 22:29:47 +0000 (UTC) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 023a9eb..558d858 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -137,6 +137,33 @@ out_err: #if defined(CONFIG_NFS_V4_1) /* + * * CB_SEQUENCE operations will fail until the callback sessionid is set. + * */ +int nfs4_set_callback_sessionid(struct nfs_client *clp) +{ + struct svc_serv *serv = clp->cl_rpcclient->cl_xprt->bc_serv; + struct nfs4_sessionid *bc_sid; + + if (!serv->bc_xprt) + return -EINVAL; + + /* on success freed in xprt_free */ + bc_sid = kmalloc(sizeof(struct nfs4_sessionid), GFP_KERNEL); + if (!bc_sid) + return -ENOMEM; + memcpy(bc_sid->data, &clp->cl_session->sess_id.data, + NFS4_MAX_SESSIONID_LEN); + spin_lock(&serv->sv_cb_lock); + serv->bc_xprt->xpt_bc_sid = bc_sid; + spin_unlock(&serv->sv_cb_lock); + dprintk("%s set xpt_bc_sid=%u:%u:%u:%u for bc_xprt %p\n", __func__, + ((u32 *)bc_sid->data)[0], ((u32 *)bc_sid->data)[1], + ((u32 *)bc_sid->data)[2], ((u32 *)bc_sid->data)[3], + serv->bc_xprt); + return 0; +} + +/* * The callback service for NFSv4.1 callbacks */ static int @@ -236,6 +263,10 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, struct nfs_callback_data *cb_info) { } +int nfs4_set_callback_sessionid(struct nfs_client *clp) +{ + return 0; +} #endif /* CONFIG_NFS_V4_1 */ /* diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index 85a7cfd..58d61a8 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -137,6 +137,7 @@ extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); extern void nfs_callback_down(int minorversion); extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid); +extern int nfs4_set_callback_sessionid(struct nfs_client *clp); #endif /* CONFIG_NFS_V4 */ /* * nfs41: Callbacks are expected to not cause substantial latency, diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index fe61422..11290de 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -193,6 +193,12 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) status = nfs4_proc_create_session(clp); if (status != 0) goto out; + status = nfs4_set_callback_sessionid(clp); + if (status != 0) { + printk(KERN_WARNING "Sessionid not set. No callback service\n"); + nfs_callback_down(1); + status = 0; + } nfs41_setup_state_renewal(clp); nfs_mark_client_ready(clp, NFS_CS_READY); out: diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index 600c669..aa15126 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -79,6 +79,7 @@ struct svc_xprt { size_t xpt_remotelen; /* length of address */ struct rpc_wait_queue xpt_bc_pending; /* backchannel wait queue */ struct list_head xpt_users; /* callbacks on free */ + void *xpt_bc_sid; /* back channel session ID */ struct net *xpt_net; }; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 4c8f18a..18783cb 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -985,6 +985,8 @@ void xprt_free(struct rpc_xprt *xprt) { put_net(xprt->xprt_net); kfree(xprt->slot); + if (xprt->bc_xprt) + kfree(xprt->bc_xprt->xpt_bc_sid); kfree(xprt); } EXPORT_SYMBOL_GPL(xprt_free);