Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c2618c6 authored by Andy Adamson's avatar Andy Adamson Committed by Trond Myklebust
Browse files

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: default avatarAndy Adamson <andros@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent f4eecd5d
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -136,6 +136,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
 */
@@ -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 */

/*
+1 −0
Original line number Diff line number Diff line
@@ -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,
+6 −0
Original line number Diff line number Diff line
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -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;
};
+3 −1
Original line number Diff line number Diff line
@@ -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 */