diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2012-12-08 00:29:16 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2012-12-08 00:29:16 +0000 |
commit | ded0f38e615d39bdc5ac38cdb3cecf37a66c75fe (patch) | |
tree | b8b979991f852a5c25a95ddbabb63117c46bef2e /sys/rpc/clnt_rc.c | |
parent | b8327e28a33a6bb69cb12171c683fc2756305c0a (diff) | |
download | FreeBSD-src-ded0f38e615d39bdc5ac38cdb3cecf37a66c75fe.zip FreeBSD-src-ded0f38e615d39bdc5ac38cdb3cecf37a66c75fe.tar.gz |
Add support for backchannels to the kernel RPC. Backchannels
are used by NFSv4.1 for callbacks. A backchannel is a connection
established by the client, but used for RPCs done by the server
on the client (callbacks). As a result, this patch mixes some
client side calls in the server side and vice versa. Some
definitions in the .c files were extracted out into a file called
krpc.h, so that they could be included in multiple .c files.
This code has been in projects/nfsv4.1-client for some time.
Although no one has given it a formal review, I believe kib@
has taken a look at it.
Diffstat (limited to 'sys/rpc/clnt_rc.c')
-rw-r--r-- | sys/rpc/clnt_rc.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c index e263278..b910059 100644 --- a/sys/rpc/clnt_rc.c +++ b/sys/rpc/clnt_rc.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <rpc/rpc.h> #include <rpc/rpc_com.h> +#include <rpc/krpc.h> static enum clnt_stat clnt_reconnect_call(CLIENT *, struct rpc_callextra *, rpcproc_t, struct mbuf *, struct mbuf **, struct timeval); @@ -67,27 +68,6 @@ static struct clnt_ops clnt_reconnect_ops = { static int fake_wchan; -struct rc_data { - struct mtx rc_lock; - struct sockaddr_storage rc_addr; /* server address */ - struct netconfig* rc_nconf; /* network type */ - rpcprog_t rc_prog; /* program number */ - rpcvers_t rc_vers; /* version number */ - size_t rc_sendsz; - size_t rc_recvsz; - struct timeval rc_timeout; - struct timeval rc_retry; - int rc_retries; - int rc_privport; - char *rc_waitchan; - int rc_intr; - int rc_connecting; - int rc_closed; - struct ucred *rc_ucred; - CLIENT* rc_client; /* underlying RPC client */ - struct rpc_err rc_err; -}; - CLIENT * clnt_reconnect_create( struct netconfig *nconf, /* network type */ @@ -211,6 +191,8 @@ clnt_reconnect_connect(CLIENT *cl) CLNT_CONTROL(newclient, CLSET_RETRY_TIMEOUT, &rc->rc_retry); CLNT_CONTROL(newclient, CLSET_WAITCHAN, rc->rc_waitchan); CLNT_CONTROL(newclient, CLSET_INTERRUPTIBLE, &rc->rc_intr); + if (rc->rc_backchannel != NULL) + CLNT_CONTROL(newclient, CLSET_BACKCHANNEL, rc->rc_backchannel); stat = RPC_SUCCESS; out: @@ -385,6 +367,7 @@ static bool_t clnt_reconnect_control(CLIENT *cl, u_int request, void *info) { struct rc_data *rc = (struct rc_data *)cl->cl_private; + SVCXPRT *xprt; if (info == NULL) { return (FALSE); @@ -466,6 +449,13 @@ clnt_reconnect_control(CLIENT *cl, u_int request, void *info) *(int *) info = rc->rc_privport; break; + case CLSET_BACKCHANNEL: + xprt = (SVCXPRT *)info; + SVC_ACQUIRE(xprt); + xprt_register(xprt); + rc->rc_backchannel = info; + break; + default: return (FALSE); } @@ -502,9 +492,15 @@ static void clnt_reconnect_destroy(CLIENT *cl) { struct rc_data *rc = (struct rc_data *)cl->cl_private; + SVCXPRT *xprt; if (rc->rc_client) CLNT_DESTROY(rc->rc_client); + if (rc->rc_backchannel) { + xprt = (SVCXPRT *)rc->rc_backchannel; + xprt_unregister(xprt); + SVC_RELEASE(xprt); + } crfree(rc->rc_ucred); mtx_destroy(&rc->rc_lock); mem_free(rc, sizeof(*rc)); |