From: Chuck Lever <chuck.lever@oracle.com>
To: trond.myklybust@fys.uio.no
Cc: nfs@lists.sourceforge.net
Subject: [PATCH 06/14] SUNRPC: introduce rpcbind: replacement for in-kernel portmapper
Date: Thu, 18 Jan 2007 18:30:12 -0500 [thread overview]
Message-ID: <20070118233012.23310.70826.stgit@localhost.localdomain> (raw)
In-Reply-To: <20070118232356.23310.6705.stgit@localhost.localdomain>
Introduce a replacement for the in-kernel portmapper client that supports
all 3 versions of the rpcbind protocol. This code is not used yet.
Original code by Groupe Bull updated for the latest kernel, with multiple
bug fixes.
Note that rpcb_clnt.c does not yet support registering via versions 3 and
4 of the rpcbind protocol.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/sunrpc/clnt.h | 3
include/linux/sunrpc/debug.h | 1
include/linux/sunrpc/xprt.h | 1
net/sunrpc/Makefile | 2
net/sunrpc/rpcb_clnt.c | 539 ++++++++++++++++++++++++++++++++++++++++++
net/sunrpc/xprt.c | 1
6 files changed, 546 insertions(+), 1 deletions(-)
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index a1be89d..502e5ea 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -121,6 +121,8 @@ int rpc_destroy_client(struct rpc_clnt
void rpc_release_client(struct rpc_clnt *);
void rpc_getport(struct rpc_task *);
int rpc_register(u32, u32, int, unsigned short, int *);
+int rpcb_register(u32, u32, int, unsigned short, int *);
+void rpcb_getport(struct rpc_task *);
void rpc_call_setup(struct rpc_task *, struct rpc_message *, int);
@@ -143,6 +145,7 @@ char * rpc_peeraddr2str(struct rpc_clnt
* Helper function for NFSroot support
*/
int rpc_getport_external(struct sockaddr_in *, __u32, __u32, int);
+int rpcb_getport_external(struct sockaddr_in *, __u32, __u32, int);
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 60fce3c..7b11c74 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -18,6 +18,7 @@ #define RPCDBG_DEBUG 0x0004
#define RPCDBG_NFS 0x0008
#define RPCDBG_AUTH 0x0010
#define RPCDBG_PMAP 0x0020
+#define RPCDBG_BIND 0x0020
#define RPCDBG_SCHED 0x0040
#define RPCDBG_TRANS 0x0080
#define RPCDBG_SVCSOCK 0x0100
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 51c3660..6c035cb 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -150,6 +150,7 @@ struct rpc_xprt {
unsigned long state; /* transport state */
unsigned char shutdown : 1, /* being shut down */
resvport : 1; /* use a reserved port */
+ unsigned int bind_index; /* bind function index */
/*
* Connection of transports
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index cdcab9c..3417a1e 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
auth.o auth_null.o auth_unix.o \
svc.o svcsock.o svcauth.o svcauth_unix.o \
- pmap_clnt.o timer.o xdr.o \
+ pmap_clnt.o rpcb_clnt.o timer.o xdr.o \
sunrpc_syms.o cache.o rpc_pipe.o
sunrpc-$(CONFIG_PROC_FS) += stats.o
sunrpc-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
new file mode 100644
index 0000000..8f3e133
--- /dev/null
+++ b/net/sunrpc/rpcb_clnt.c
@@ -0,0 +1,539 @@
+/*
+ * linux/net/sunrpc/rpcb_clnt.c
+ *
+ * In-kernel rpcbind client supporting versions 2, 3, and 4 of the rpcbind
+ * protocol (RFC 1833).
+ *
+ * Added by Gilles Quillard, Bull Open Source, 2005 <gilles.quillard@bull.net>
+ *
+ * Based on net/sunrpc/pmap_clnt.c,
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/sched.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_BIND
+#endif
+
+#define RPC_BIND_PROGRAM (100000U)
+#define RPC_BIND_PORT (111U)
+
+#define RPCB_SET (1)
+#define RPCB_UNSET (2)
+#define RPCB_GETPORT (3)
+#define RPCB_GETADDR (3)
+#define RPCB_GETVERSADDR (9)
+
+/* US-ASCII netid strings -- must work even on s/390 */
+#define RPCB_NETID_UDP "\165\144\160" /* "udp" */
+#define RPCB_NETID_TCP "\164\143\160" /* "tcp" */
+
+static void rpcb_getport_done(struct rpc_task *, void *);
+extern struct rpc_program rpcb_program;
+
+struct rpcbind_args {
+ struct rpc_xprt * r_xprt;
+
+ u32 r_prog;
+ u32 r_vers;
+ u32 r_prot;
+ unsigned short r_port;
+ char * r_netid;
+ char r_addr[128];
+ char * r_owner;
+};
+
+static struct rpc_procinfo rpcb_procedures2[];
+static struct rpc_procinfo rpcb_procedures3[];
+
+static struct rpcb_info {
+ int rpc_vers;
+ struct rpc_procinfo * rpc_proc;
+} rpcb_next_version[];
+
+static void rpcb_getport_prepare(struct rpc_task *task, void *calldata)
+{
+ struct rpcbind_args *map = calldata;
+ struct rpc_xprt *xprt = map->r_xprt;
+ struct rpc_message msg = {
+ .rpc_proc = rpcb_next_version[xprt->bind_index].rpc_proc,
+ .rpc_argp = map,
+ .rpc_resp = &map->r_port,
+ };
+
+ rpc_call_setup(task, &msg, 0);
+}
+
+static inline struct rpcbind_args *rpcb_map_alloc(void)
+{
+ return kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
+}
+
+static inline void rpcb_map_free(struct rpcbind_args *map)
+{
+ kfree(map);
+}
+
+static void rpcb_map_release(void *data)
+{
+ rpcb_map_free(data);
+}
+
+static const struct rpc_call_ops rpcb_getport_ops = {
+ .rpc_call_prepare = rpcb_getport_prepare,
+ .rpc_call_done = rpcb_getport_done,
+ .rpc_release = rpcb_map_release,
+};
+
+static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
+{
+ xprt_clear_binding(xprt);
+ rpc_wake_up_status(&xprt->binding, status);
+}
+
+static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, int proto, int version, int privileged)
+{
+ struct rpc_create_args args = {
+ .protocol = proto,
+ .address = srvaddr,
+ .addrsize = sizeof(struct sockaddr_in),
+ .servername = hostname,
+ .program = &rpcb_program,
+ .version = version,
+ .authflavor = RPC_AUTH_NULL,
+ .flags = (RPC_CLNT_CREATE_ONESHOT |
+ RPC_CLNT_CREATE_NOPING),
+ };
+
+ ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPC_BIND_PORT);
+ if (!privileged)
+ args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
+ return rpc_create(&args);
+}
+
+/**
+ * rpcb_register - set or unset a port registration with the local portmapper
+ * @prog: RPC program number to bind
+ * @vers: RPC version number to bind
+ * @prot: transport protocol to use to make this request
+ * @port: port value to register
+ * @okay: result code
+ *
+ * port == 0 means unregister, port != 0 means register.
+ *
+ * This routine supports only rpcbind version 2.
+ */
+int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
+{
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
+ };
+ struct rpcbind_args map = {
+ .r_prog = prog,
+ .r_vers = vers,
+ .r_prot = prot,
+ .r_port = port,
+ };
+ struct rpc_message msg = {
+ .rpc_proc = &rpcb_procedures2[port ? RPCB_SET : RPCB_UNSET],
+ .rpc_argp = &map,
+ .rpc_resp = okay,
+ };
+ struct rpc_clnt *rpcb_clnt;
+ int error = 0;
+
+ dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
+ "rpcbind\n", (port ? "" : "un"),
+ prog, vers, prot, port);
+
+ rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin,
+ IPPROTO_UDP, 2, 1);
+ if (IS_ERR(rpcb_clnt))
+ return PTR_ERR(rpcb_clnt);
+
+ error = rpc_call_sync(rpcb_clnt, &msg, 0);
+
+ if (error < 0)
+ printk(KERN_WARNING "RPC: failed to contact local rpcbind "
+ "server (errno %d).\n", -error);
+ dprintk("RPC: registration status %d/%d\n", error, *okay);
+
+ return error;
+}
+
+#ifdef CONFIG_ROOT_NFS
+/**
+ * rpcb_getport_external - obtain the port for a given RPC service on a given host
+ * @sin: address of remote peer
+ * @prog: RPC program number to bind
+ * @vers: RPC version number to bind
+ * @prot: transport protocol to use to make this request
+ *
+ * Called from outside the RPC client in a synchronous task context.
+ *
+ * For now, this supports only version 2 queries, but is used only by
+ * mount_clnt for NFS_ROOT.
+ */
+int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
+{
+ struct rpcbind_args map = {
+ .r_prog = prog,
+ .r_vers = vers,
+ .r_prot = prot,
+ .r_port = 0,
+ };
+ struct rpc_message msg = {
+ .rpc_proc = &rpcb_procedures2[RPCB_GETPORT],
+ .rpc_argp = &map,
+ .rpc_resp = &map.r_port,
+ };
+ struct rpc_clnt *rpcb_clnt;
+ char hostname[40];
+ int status;
+
+ dprintk("RPC: rpcb_getport_external(%u.%u.%u.%u, %u, %u, %d)\n",
+ NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
+
+ sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
+ rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0);
+ if (IS_ERR(rpcb_clnt))
+ return PTR_ERR(rpcb_clnt);
+
+ status = rpc_call_sync(rpcb_clnt, &msg, 0);
+
+ if (status >= 0) {
+ if (map.r_port != 0)
+ return map.r_port;
+ status = -EACCES;
+ }
+ return status;
+}
+#endif
+
+/**
+ * rpcb_getport - obtain the port for a given RPC service on a given host
+ * @task: task that is waiting for portmapper request
+ *
+ * This one can be called for an ongoing RPC request, and can be used in
+ * an async (rpciod) context.
+ */
+void rpcb_getport(struct rpc_task *task)
+{
+ struct rpc_clnt *clnt = task->tk_client;
+ int bind_version;
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_clnt *rpcb_clnt;
+ static struct rpcbind_args *map;
+ struct rpc_task *child;
+ struct sockaddr addr;
+ int status;
+
+ dprintk("RPC: %5u rpcb_getport(%s, %u, %u, %d)\n",
+ task->tk_pid, clnt->cl_server,
+ clnt->cl_prog, clnt->cl_vers, xprt->prot);
+
+ /* Autobind on cloned rpc clients is discouraged */
+ BUG_ON(clnt->cl_parent != clnt);
+
+ if (xprt_test_and_set_binding(xprt)) {
+ status = -EACCES; /* tell caller to check again */
+ dprintk("RPC: %5u rpcb_getport waiting for another binder\n",
+ task->tk_pid);
+ goto bailout_nowake;
+ }
+
+ /* Put self on queue before sending rpcbind request, in case
+ * rpcb_getport_done completes before we return from rpc_run_task */
+ rpc_sleep_on(&xprt->binding, task, NULL, NULL);
+
+ /* Someone else may have bound if we slept */
+ if (xprt_bound(xprt)) {
+ status = 0;
+ dprintk("RPC: %5u rpcb_getport already bound\n", task->tk_pid);
+ goto bailout_nofree;
+ }
+
+ if (rpcb_next_version[xprt->bind_index].rpc_proc == NULL) {
+ xprt->bind_index = 0;
+ status = -EACCES; /* tell caller to check again */
+ dprintk("RPC: %5u rpcb_getport no more getport versions "
+ "available\n", task->tk_pid);
+ goto bailout_nofree;
+ }
+ bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
+
+ dprintk("RPC: %5u rpcb_getport trying rpcbind version %u\n",
+ task->tk_pid, bind_version);
+
+ map = rpcb_map_alloc();
+ if (!map) {
+ status = -ENOMEM;
+ dprintk("RPC: %5u rpcb_getport no memory available\n",
+ task->tk_pid);
+ goto bailout_nofree;
+ }
+ map->r_prog = clnt->cl_prog;
+ map->r_vers = clnt->cl_vers;
+ map->r_prot = xprt->prot;
+ map->r_port = 0;
+ map->r_xprt = xprt_get(xprt);
+ map->r_netid = (xprt->prot == IPPROTO_TCP) ? RPCB_NETID_TCP :
+ RPCB_NETID_UDP;
+ memcpy(&map->r_addr, rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR),
+ sizeof(map->r_addr));
+ map->r_owner = "rpcb"; /* ignored for GETADDR */
+
+ rpc_peeraddr(clnt, (void *)&addr, sizeof(addr));
+ rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0);
+ if (IS_ERR(rpcb_clnt)) {
+ status = PTR_ERR(rpcb_clnt);
+ dprintk("RPC: %5u rpcb_getport rpcb_create failed, error %ld\n",
+ task->tk_pid, PTR_ERR(rpcb_clnt));
+ goto bailout;
+ }
+
+ child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map);
+ if (IS_ERR(child)) {
+ status = -EIO;
+ dprintk("RPC: %5u rpcb_getport rpc_run_task failed\n",
+ task->tk_pid);
+ goto bailout;
+ }
+ rpc_put_task(child);
+
+ task->tk_xprt->stat.bind_count++;
+ return;
+
+bailout:
+ rpcb_map_free(map);
+ xprt_put(xprt);
+bailout_nofree:
+ rpcb_wake_rpcbind_waiters(xprt, status);
+bailout_nowake:
+ task->tk_status = status;
+}
+
+/*
+ * Rpcbind child task calls this callback via tk_exit.
+ */
+static void rpcb_getport_done(struct rpc_task *child, void *data)
+{
+ struct rpcbind_args *map = data;
+ struct rpc_xprt *xprt = map->r_xprt;
+ int status = child->tk_status;
+
+ if (status != -EPROTONOSUPPORT)
+ xprt->bind_index = 0;
+ else
+ xprt->bind_index++;
+
+ if (status < 0) {
+ /* rpcbind server not available on remote host? */
+ xprt->ops->set_port(xprt, 0);
+ } else if (map->r_port == 0) {
+ /* Requested RPC service wasn't registered on remote host */
+ xprt->ops->set_port(xprt, 0);
+ status = -EACCES;
+ } else {
+ /* Succeeded */
+ xprt->ops->set_port(xprt, map->r_port);
+ xprt_set_bound(xprt);
+ status = 0;
+ }
+
+ dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
+ child->tk_pid, status, map->r_port);
+
+ rpcb_wake_rpcbind_waiters(xprt, status);
+ xprt_put(xprt);
+}
+
+/*
+ * rpcbind version 2 XDR encode/decode routines
+ */
+static int xdr_encode_mapping(struct rpc_rqst *req, __be32 *p, struct rpcbind_args *rpcb)
+{
+ dprintk("RPC: xdr_encode_mapping(%u, %u, %d, %u)\n",
+ rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
+ *p++ = htonl(rpcb->r_prog);
+ *p++ = htonl(rpcb->r_vers);
+ *p++ = htonl(rpcb->r_prot);
+ *p++ = htonl(rpcb->r_port);
+
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+ return 0;
+}
+
+static int xdr_decode_getport(struct rpc_rqst *req, __be32 *p, unsigned short *portp)
+{
+ *portp = (unsigned short) ntohl(*p++);
+ return 0;
+}
+
+static int xdr_decode_set(struct rpc_rqst *req, __be32 *p, unsigned int *boolp)
+{
+ *boolp = (unsigned int) ntohl(*p++);
+ return 0;
+}
+
+/*
+ * rpcbind version 3 XDR encode/decode routines
+ */
+static int xdr_encode_getaddr(struct rpc_rqst *req, __be32 *p, struct rpcbind_args *rpcb)
+{
+ dprintk("RPC: xdr_encode_getaddr(%u, %u, %s)\n",
+ rpcb->r_prog, rpcb->r_vers, rpcb->r_addr);
+ *p++ = htonl(rpcb->r_prog);
+ *p++ = htonl(rpcb->r_vers);
+
+ p = xdr_encode_string(p, rpcb->r_netid);
+ p = xdr_encode_string(p, rpcb->r_addr);
+ p = xdr_encode_string(p, rpcb->r_owner);
+
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+
+ return 0;
+}
+
+static int xdr_decode_getaddr(struct rpc_rqst *req, __be32 *p, unsigned short *portp)
+{
+ char *addr;
+ int addr_len, c, i, f, first, val;
+
+ *portp = 0;
+ addr_len = (unsigned int) ntohl(*p++);
+ addr = (char *)p;
+ val = 0;
+ first = 1;
+ f = 1;
+ for (i = addr_len - 1; i > 0; i--) {
+ c = addr[i];
+ if (c >= '0' && c <= '9') {
+ val += (c - '0') * f;
+ f *= 10;
+ } else if (c == '.') {
+ if (first) {
+ *portp = val;
+ val = first = 0;
+ f = 1;
+ } else {
+ *portp |= (val << 8);
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+static struct rpc_procinfo rpcb_procedures2[] = {
+ [RPCB_SET] = {
+ .p_proc = RPCB_SET,
+ .p_encode = (kxdrproc_t) xdr_encode_mapping,
+ .p_decode = (kxdrproc_t) xdr_decode_set,
+ .p_bufsiz = 4,
+ .p_count = 1,
+ },
+ [RPCB_UNSET] = {
+ .p_proc = RPCB_UNSET,
+ .p_encode = (kxdrproc_t) xdr_encode_mapping,
+ .p_decode = (kxdrproc_t) xdr_decode_set,
+ .p_bufsiz = 4,
+ .p_count = 1,
+ },
+ [RPCB_GETADDR] = {
+ .p_proc = RPCB_GETPORT,
+ .p_encode = (kxdrproc_t) xdr_encode_mapping,
+ .p_decode = (kxdrproc_t) xdr_decode_getport,
+ .p_bufsiz = 4,
+ .p_count = 1,
+ },
+};
+
+static struct rpc_procinfo rpcb_procedures3[] = {
+ [RPCB_SET] = {
+ .p_proc = RPCB_SET,
+ .p_encode = (kxdrproc_t) xdr_encode_mapping,
+ .p_decode = (kxdrproc_t) xdr_decode_set,
+ .p_bufsiz = 4,
+ .p_count = 1,
+ },
+ [RPCB_UNSET] = {
+ .p_proc = RPCB_UNSET,
+ .p_encode = (kxdrproc_t) xdr_encode_mapping,
+ .p_decode = (kxdrproc_t) xdr_decode_set,
+ .p_bufsiz = 4,
+ .p_count = 1,
+ },
+ [RPCB_GETADDR] = {
+ .p_proc = RPCB_GETADDR,
+ .p_encode = (kxdrproc_t) xdr_encode_getaddr,
+ .p_decode = (kxdrproc_t) xdr_decode_getaddr,
+ .p_bufsiz = 36,
+ .p_count = 1,
+ },
+};
+
+static struct rpc_procinfo rpcb_procedures4[] = {
+ [RPCB_GETVERSADDR] = {
+ .p_proc = RPCB_GETVERSADDR,
+ .p_encode = (kxdrproc_t) xdr_encode_getaddr,
+ .p_decode = (kxdrproc_t) xdr_decode_getaddr,
+ .p_bufsiz = 36,
+ .p_count = 1,
+ },
+};
+
+static struct rpcb_info rpcb_next_version[] = {
+#if defined(CONFIG_RPCBIND_VERSION4)
+ { 4, &rpcb_procedures4[RPCB_GETVERSADDR] },
+#endif
+#if defined(CONFIG_RPCBIND_VERSION3)
+ { 3, &rpcb_procedures3[RPCB_GETADDR] },
+#endif
+ { 2, &rpcb_procedures2[RPCB_GETPORT] },
+ { 0, NULL },
+};
+
+static struct rpc_version rpcb_version2 = {
+ .number = 2,
+ .nrprocs = 4,
+ .procs = rpcb_procedures2
+};
+
+static struct rpc_version rpcb_version3 = {
+ .number = 3,
+ .nrprocs = 4,
+ .procs = rpcb_procedures3
+};
+
+static struct rpc_version rpcb_version4 = {
+ .number = 4,
+ .nrprocs = 10,
+ .procs = rpcb_procedures4
+};
+
+static struct rpc_version *rpcb_version[] = {
+ NULL,
+ NULL,
+ &rpcb_version2,
+ &rpcb_version3,
+ &rpcb_version4
+};
+
+static struct rpc_stat rpcb_stats;
+
+struct rpc_program rpcb_program = {
+ .name = "rpcbind",
+ .number = RPC_BIND_PROGRAM,
+ .nrvers = ARRAY_SIZE(rpcb_version),
+ .version = rpcb_version,
+ .stats = &rpcb_stats,
+};
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 9f787ac..86181ac 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -928,6 +928,7 @@ struct rpc_xprt *xprt_create_transport(i
xprt->timer.data = (unsigned long) xprt;
xprt->last_used = jiffies;
xprt->cwnd = RPC_INITCWND;
+ xprt->bind_index = 0;
rpc_init_wait_queue(&xprt->binding, "xprt_binding");
rpc_init_wait_queue(&xprt->pending, "xprt_pending");
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
next prev parent reply other threads:[~2007-01-18 23:30 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-18 23:23 [PATCH 00/14] NFS/RPC client patches for 2.6.21 Chuck Lever
2007-01-18 23:29 ` [PATCH 01/14] NFS: fix print format for tk_pid Chuck Lever
2007-01-19 0:03 ` Christoph Hellwig
2007-01-19 0:10 ` Chuck Lever
2007-01-18 23:29 ` [PATCH 02/14] SUNRPC: fix print format for tk_pid in auth_gss support Chuck Lever
2007-01-18 23:29 ` [PATCH 03/14] SUNRPC: fix print format for tk_pid Chuck Lever
2007-01-18 23:29 ` [PATCH 04/14] SUNRPC: Eliminate side effects from rpc_malloc Chuck Lever
2007-01-18 23:30 ` [PATCH 05/14] SUNRPC: Make rpc_free API more generic Chuck Lever
2007-01-18 23:30 ` Chuck Lever [this message]
2007-01-19 0:09 ` [PATCH 06/14] SUNRPC: introduce rpcbind: replacement for in-kernel portmapper Christoph Hellwig
2007-01-19 21:54 ` Chuck Lever
2007-01-18 23:30 ` [PATCH 07/14] SUNRPC: switch socket-based RPC transports to use rpcbind Chuck Lever
2007-01-18 23:30 ` [PATCH 08/14] SUNRPC: switch the RPC server to use the new rpcbind registration API Chuck Lever
2007-01-18 23:30 ` [PATCH 09/14] NFS: switch NFSROOT to use new rpcbind client Chuck Lever
2007-01-18 23:30 ` [PATCH 10/14] SUNRPC: Enable support for rpcbind versions 3 and 4 via CONFIG options Chuck Lever
2007-01-19 0:11 ` Christoph Hellwig
2007-01-19 22:04 ` Chuck Lever
2007-01-19 22:10 ` Trond Myklebust
2007-01-18 23:30 ` [PATCH 11/14] SUNRPC: remove old portmapper Chuck Lever
2007-01-18 23:30 ` [PATCH 12/14] SUNRPC: RPC buffer size estimates are too large Chuck Lever
2007-01-18 23:49 ` J. Bruce Fields
2007-01-18 23:54 ` Chuck Lever
2007-01-19 0:00 ` J. Bruce Fields
2007-01-19 0:08 ` Chuck Lever
2007-01-19 22:36 ` Trond Myklebust
2007-01-19 22:46 ` Chuck Lever
2007-01-19 23:12 ` Trond Myklebust
2007-01-23 16:04 ` Chuck Lever
2007-01-18 23:30 ` [PATCH 13/14] NLM: Shrink the maximum request size of NLM4 requests Chuck Lever
2007-01-19 0:13 ` Christoph Hellwig
2007-01-19 22:27 ` Chuck Lever
2007-01-20 9:26 ` Christoph Hellwig
2007-01-18 23:31 ` [PATCH 14/14] SUNRPC: Debugging aid Chuck Lever
2007-01-19 22:28 ` Trond Myklebust
2007-01-19 22:38 ` Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070118233012.23310.70826.stgit@localhost.localdomain \
--to=chuck.lever@oracle.com \
--cc=nfs@lists.sourceforge.net \
--cc=trond.myklybust@fys.uio.no \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox