summaryrefslogtreecommitdiffstats
path: root/sys/rpc/clnt_rc.c
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2012-12-08 00:29:16 +0000
committerrmacklem <rmacklem@FreeBSD.org>2012-12-08 00:29:16 +0000
commitded0f38e615d39bdc5ac38cdb3cecf37a66c75fe (patch)
treeb8b979991f852a5c25a95ddbabb63117c46bef2e /sys/rpc/clnt_rc.c
parentb8327e28a33a6bb69cb12171c683fc2756305c0a (diff)
downloadFreeBSD-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.c38
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));
OpenPOWER on IntegriCloud