Commit afdc754f authored by Trond Myklebust's avatar Trond Myklebust

NFS,RPC: RPC client now advertises maximum payload size

 The RPC client now reports the maximum payload size supported by the chosen
 transport method.  This is something a little less than 64KB for RPC over
 UDP, and about 2GB - 1 for RPC over TCP.  The effective rsize and wsize
 values are not allowed to exceed the reported maximum RPC payload size.
Signed-off-by: default avatarChuck Lever <cel@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 388a910d
......@@ -249,6 +249,7 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
.fattr = &fattr,
};
int no_root_error = 0;
unsigned long max_rpc_payload;
/* We probably want something more informative here */
snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
......@@ -285,6 +286,12 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
if (fsinfo.wtmax >= 512 && server->wsize > fsinfo.wtmax)
server->wsize = nfs_block_size(fsinfo.wtmax, NULL);
max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
if (server->rsize > max_rpc_payload)
server->rsize = max_rpc_payload;
if (server->wsize > max_rpc_payload)
server->wsize = max_rpc_payload;
server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (server->rpages > NFS_READ_MAXIOV) {
server->rpages = NFS_READ_MAXIOV;
......
......@@ -128,6 +128,7 @@ 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);
size_t rpc_max_payload(struct rpc_clnt *);
static __inline__
int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
......
......@@ -140,6 +140,9 @@ struct rpc_xprt {
unsigned int rcvsize, /* socket receive buffer size */
sndsize; /* socket send buffer size */
size_t max_payload; /* largest RPC payload size,
in bytes */
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 */
......
......@@ -23,6 +23,7 @@
#include <asm/system.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
......@@ -451,6 +452,20 @@ rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize
xprt_sock_setbufsize(xprt);
}
/*
* Return size of largest payload RPC client can support, in bytes
*
* For stream transports, this is one RPC record fragment (see RFC
* 1831), as we don't support multi-record requests yet. For datagram
* transports, this is the size of an IP packet minus the IP, UDP, and
* RPC header sizes.
*/
size_t rpc_max_payload(struct rpc_clnt *clnt)
{
return clnt->cl_xprt->max_payload;
}
EXPORT_SYMBOL(rpc_max_payload);
/*
* Restart an (async) RPC call. Usually called from within the
* exit handler.
......
......@@ -1460,8 +1460,11 @@ xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
if (xprt->stream) {
xprt->cwnd = RPC_MAXCWND(xprt);
xprt->nocong = 1;
} else
xprt->max_payload = (1U << 31) - 1;
} else {
xprt->cwnd = RPC_INITCWND;
xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
}
spin_lock_init(&xprt->sock_lock);
spin_lock_init(&xprt->xprt_lock);
init_waitqueue_head(&xprt->cong_wait);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment