diff options
author | Andy Adamson <andros@netapp.com> | 2011-01-06 03:04:31 +0100 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-01-06 20:46:24 +0100 |
commit | 2c2618c6f29c41a0a966f14f05c8bf45fcabb750 (patch) | |
tree | c247cfda9f847028e1d43cab1e69d2cd8a2146a4 | |
parent | NFS implement v4.0 callback_ident (diff) | |
download | linux-2c2618c6f29c41a0a966f14f05c8bf45fcabb750.tar.xz linux-2c2618c6f29c41a0a966f14f05c8bf45fcabb750.zip |
NFS associate sessionid with callback connection
The sessions based callback service is started prior to the CREATE_SESSION call
so that it can handle CB_NULL requests which can be sent before the
CREATE_SESSION call returns and the session ID is known.
Set the callback sessionid after a sucessful CREATE_SESSION.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/callback.c | 31 | ||||
-rw-r--r-- | fs/nfs/callback.h | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 6 | ||||
-rw-r--r-- | include/linux/sunrpc/svc_xprt.h | 1 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 4 |
5 files changed, 42 insertions, 1 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 0e9fae831dfa..c0b05497972b 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_bh(&serv->sv_cb_lock); + serv->bc_xprt->xpt_bc_sid = bc_sid; + spin_unlock_bh(&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 @@ -241,6 +268,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 85a7cfd1b8dd..58d61a8ce8b9 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 f575a3126737..485e95e8fd62 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -192,6 +192,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 aea0d438e3c7..357da5e0daa3 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -78,6 +78,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/svcsock.c b/net/sunrpc/svcsock.c index e6b66d81115e..db3013e4aa04 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1605,7 +1605,9 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv, */ static void svc_bc_sock_free(struct svc_xprt *xprt) { - if (xprt) + if (xprt) { + kfree(xprt->xpt_bc_sid); kfree(container_of(xprt, struct svc_sock, sk_xprt)); + } } #endif /* CONFIG_NFS_V4_1 */ |