summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2002-07-26 00:00:14 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-07-26 00:00:14 -0700
commitff3cc6a09251f437f18029a7bd96f6bd55bccfb2 (patch)
tree48bf0e097f28e00f103858a7cc264522b0381726
parent0be53f272bd1e45378781314423bf238f0493f74 (diff)
[PATCH] increase socket buffer for RPC over UDP
Make RPC over UDP use a socket buffer size that is large enough to fit all the messages. Congestion control is in any case handled by the Van Jacobson algoritm, and we need to work around a bug in ip_build_xmit_slow() w.r.t. fragmentation when there is insufficient buffer memory to fit the entire message.
-rw-r--r--fs/nfs/inode.c3
-rw-r--r--include/linux/sunrpc/clnt.h1
-rw-r--r--include/linux/sunrpc/xprt.h4
-rw-r--r--net/sunrpc/clnt.c14
-rw-r--r--net/sunrpc/sunrpc_syms.c1
-rw-r--r--net/sunrpc/xprt.c21
6 files changed, 43 insertions, 1 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 40ad8333e475..ce7ad8ae64a3 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -425,7 +425,8 @@ int nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int sile
goto failure_kill_reqlist;
}
- /* We're airborne */
+ /* We're airborne Set socket buffersize */
+ rpc_setbufsize(clnt, server->wsize + 100, server->rsize + 100);
/* Check whether to start the lockd process */
if (!(server->flags & NFS_MOUNT_NONLM))
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index d278df00ecb9..92fa9755592e 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -127,6 +127,7 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
void rpc_restart_call(struct rpc_task *);
void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
+void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
static __inline__
int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index e3c7a6b9c5ba..c9b93c6a7a27 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -122,6 +122,9 @@ struct rpc_xprt {
unsigned long cong; /* current congestion */
unsigned long cwnd; /* congestion window */
+ unsigned int rcvsize, /* socket receive buffer size */
+ sndsize; /* socket send buffer size */
+
struct rpc_wait_queue sending; /* requests waiting to send */
struct rpc_wait_queue resend; /* requests waiting to resend */
struct rpc_wait_queue pending; /* requests in flight */
@@ -177,6 +180,7 @@ int xprt_adjust_timeout(struct rpc_timeout *);
void xprt_release(struct rpc_task *);
void xprt_reconnect(struct rpc_task *);
int xprt_clear_backlog(struct rpc_xprt *);
+void xprt_sock_setbufsize(struct rpc_xprt *);
#define XPRT_CONNECT 0
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 4d98ac870e85..001c2253ec8f 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -335,6 +335,20 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
rpcproc_count(task->tk_client, task->tk_msg.rpc_proc)++;
}
+void
+rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize)
+{
+ struct rpc_xprt *xprt = clnt->cl_xprt;
+
+ xprt->sndsize = 0;
+ if (sndsize)
+ xprt->sndsize = sndsize + RPC_SLACK_SPACE;
+ xprt->rcvsize = 0;
+ if (rcvsize)
+ xprt->rcvsize = rcvsize + RPC_SLACK_SPACE;
+ xprt_sock_setbufsize(xprt);
+}
+
/*
* Restart an (async) RPC call. Usually called from within the
* exit handler.
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index d6bdb4630d2d..2b41eb87de5d 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -50,6 +50,7 @@ EXPORT_SYMBOL(rpc_clnt_sigmask);
EXPORT_SYMBOL(rpc_clnt_sigunmask);
EXPORT_SYMBOL(rpc_delay);
EXPORT_SYMBOL(rpc_restart_call);
+EXPORT_SYMBOL(rpc_setbufsize);
/* Client transport */
EXPORT_SYMBOL(xprt_create_proto);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index d805ed6c08d1..3d4ba37b48e1 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -1421,6 +1421,27 @@ xprt_bind_socket(struct rpc_xprt *xprt, struct socket *sock)
}
/*
+ * Set socket buffer length
+ */
+void
+xprt_sock_setbufsize(struct rpc_xprt *xprt)
+{
+ struct sock *sk = xprt->inet;
+
+ if (xprt->stream)
+ return;
+ if (xprt->rcvsize) {
+ sk->userlocks |= SOCK_RCVBUF_LOCK;
+ sk->rcvbuf = xprt->rcvsize * RPC_MAXCONG * 2;
+ }
+ if (xprt->sndsize) {
+ sk->userlocks |= SOCK_SNDBUF_LOCK;
+ sk->sndbuf = xprt->sndsize * RPC_MAXCONG * 2;
+ sk->write_space(sk);
+ }
+}
+
+/*
* Create a client socket given the protocol and peer address.
*/
static struct socket *