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

Commit 4d6bbb62 authored by Ricardo Labiaga's avatar Ricardo Labiaga Committed by Benny Halevy
Browse files

nfs41: Backchannel bc_svc_process()



Implement the NFSv4.1 backchannel service.  Invokes the common callback
processing logic svc_process_common() to authenticate the call and
dispatch the appropriate NFSv4.1 XDR decoder and operation procedure.
It then invokes bc_send() to send the reply over the same connection.
bc_send() is implemented in a separate patch.

At this time there is no slot validation or reply cache handling.

[nfs41: Preallocate rpc_rqst receive buffer for handling callbacks]
Signed-off-by: default avatarRicardo Labiaga <Ricardo.Labiaga@netapp.com>
Signed-off-by: default avatarBenny Halevy <bhalevy@panasas.com>
[Move bc_svc_process() declaration to correct patch]
Signed-off-by: default avatarRicardo Labiaga <Ricardo.Labiaga@netapp.com>
Signed-off-by: default avatarBenny Halevy <bhalevy@panasas.com>
parent 1cad7ea6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -419,6 +419,8 @@ int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
int		   svc_pool_stats_open(struct svc_serv *serv, struct file *file);
void		   svc_destroy(struct svc_serv *);
int		   svc_process(struct svc_rqst *);
int		   bc_svc_process(struct svc_serv *, struct rpc_rqst *,
			struct svc_rqst *);
int		   svc_register(const struct svc_serv *, const int,
				const unsigned short, const unsigned short);

+49 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/svcsock.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/bc_xprt.h>

#define RPCDBG_FACILITY	RPCDBG_SVCDSP

@@ -1239,6 +1240,54 @@ svc_process(struct svc_rqst *rqstp)
	return svc_send(rqstp);
}

#if defined(CONFIG_NFS_V4_1)
/*
 * Process a backchannel RPC request that arrived over an existing
 * outbound connection
 */
int
bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
	       struct svc_rqst *rqstp)
{
	struct kvec	*argv = &rqstp->rq_arg.head[0];
	struct kvec	*resv = &rqstp->rq_res.head[0];
	int 		error;

	/* Build the svc_rqst used by the common processing routine */
	rqstp->rq_xid = req->rq_xid;
	rqstp->rq_prot = req->rq_xprt->prot;
	rqstp->rq_server = serv;

	rqstp->rq_addrlen = sizeof(req->rq_xprt->addr);
	memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen);
	memcpy(&rqstp->rq_arg, &req->rq_rcv_buf, sizeof(rqstp->rq_arg));
	memcpy(&rqstp->rq_res, &req->rq_snd_buf, sizeof(rqstp->rq_res));

	/* reset result send buffer "put" position */
	resv->iov_len = 0;

	if (rqstp->rq_prot != IPPROTO_TCP) {
		printk(KERN_ERR "No support for Non-TCP transports!\n");
		BUG();
	}

	/*
	 * Skip the next two words because they've already been
	 * processed in the trasport
	 */
	svc_getu32(argv);	/* XID */
	svc_getnl(argv);	/* CALLDIR */

	error = svc_process_common(rqstp, argv, resv);
	if (error <= 0)
		return error;

	memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf));
	return bc_send(req);
}
EXPORT_SYMBOL(bc_svc_process);
#endif /* CONFIG_NFS_V4_1 */

/*
 * Return (transport-specific) limit on the rpc payload.
 */