Commit 7adae489 authored by Greg Banks's avatar Greg Banks Committed by Linus Torvalds
Browse files

[PATCH] knfsd: Prepare knfsd for support of rsize/wsize of up to 1MB, over TCP



The limit over UDP remains at 32K.  Also, make some of the apparently
arbitrary sizing constants clearer.

The biggest change here involves replacing NFSSVC_MAXBLKSIZE by a function of
the rqstp.  This allows it to be different for different protocols (udp/tcp)
and also allows it to depend on the servers declared sv_bufsiz.

Note that we don't actually increase sv_bufsz for nfs yet.  That comes next.

Signed-off-by: default avatarGreg Banks <gnb@melbourne.sgi.com>
Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3cc03b16
Loading
Loading
Loading
Loading
+8 −6
Original line number Original line Diff line number Diff line
@@ -160,6 +160,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
				        struct nfsd3_readres  *resp)
				        struct nfsd3_readres  *resp)
{
{
	int	nfserr;
	int	nfserr;
	u32	max_blocksize = svc_max_payload(rqstp);


	dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
	dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
				SVCFH_fmt(&argp->fh),
				SVCFH_fmt(&argp->fh),
@@ -172,8 +173,8 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
	 */
	 */


	resp->count = argp->count;
	resp->count = argp->count;
	if (NFSSVC_MAXBLKSIZE < resp->count)
	if (max_blocksize < resp->count)
		resp->count = NFSSVC_MAXBLKSIZE;
		resp->count = max_blocksize;


	svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
	svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);


@@ -538,15 +539,16 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
					   struct nfsd3_fsinfores *resp)
					   struct nfsd3_fsinfores *resp)
{
{
	int	nfserr;
	int	nfserr;
	u32	max_blocksize = svc_max_payload(rqstp);


	dprintk("nfsd: FSINFO(3)   %s\n",
	dprintk("nfsd: FSINFO(3)   %s\n",
				SVCFH_fmt(&argp->fh));
				SVCFH_fmt(&argp->fh));


	resp->f_rtmax  = NFSSVC_MAXBLKSIZE;
	resp->f_rtmax  = max_blocksize;
	resp->f_rtpref = NFSSVC_MAXBLKSIZE;
	resp->f_rtpref = max_blocksize;
	resp->f_rtmult = PAGE_SIZE;
	resp->f_rtmult = PAGE_SIZE;
	resp->f_wtmax  = NFSSVC_MAXBLKSIZE;
	resp->f_wtmax  = max_blocksize;
	resp->f_wtpref = NFSSVC_MAXBLKSIZE;
	resp->f_wtpref = max_blocksize;
	resp->f_wtmult = PAGE_SIZE;
	resp->f_wtmult = PAGE_SIZE;
	resp->f_dtpref = PAGE_SIZE;
	resp->f_dtpref = PAGE_SIZE;
	resp->f_maxfilesize = ~(u32) 0;
	resp->f_maxfilesize = ~(u32) 0;
+8 −5
Original line number Original line Diff line number Diff line
@@ -330,6 +330,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
{
{
	unsigned int len;
	unsigned int len;
	int v,pn;
	int v,pn;
	u32 max_blocksize = svc_max_payload(rqstp);


	if (!(p = decode_fh(p, &args->fh))
	if (!(p = decode_fh(p, &args->fh))
	 || !(p = xdr_decode_hyper(p, &args->offset)))
	 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -337,8 +338,8 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,


	len = args->count = ntohl(*p++);
	len = args->count = ntohl(*p++);


	if (len > NFSSVC_MAXBLKSIZE)
	if (len > max_blocksize)
		len = NFSSVC_MAXBLKSIZE;
		len = max_blocksize;


	/* set up the kvec */
	/* set up the kvec */
	v=0;
	v=0;
@@ -358,6 +359,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
					struct nfsd3_writeargs *args)
					struct nfsd3_writeargs *args)
{
{
	unsigned int len, v, hdr;
	unsigned int len, v, hdr;
	u32 max_blocksize = svc_max_payload(rqstp);


	if (!(p = decode_fh(p, &args->fh))
	if (!(p = decode_fh(p, &args->fh))
	 || !(p = xdr_decode_hyper(p, &args->offset)))
	 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -375,8 +377,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
	rqstp->rq_vec[0].iov_base = (void*)p;
	rqstp->rq_vec[0].iov_base = (void*)p;
	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;


	if (len > NFSSVC_MAXBLKSIZE)
	if (len > max_blocksize)
		len = NFSSVC_MAXBLKSIZE;
		len = max_blocksize;
	v=  0;
	v=  0;
	while (len > rqstp->rq_vec[v].iov_len) {
	while (len > rqstp->rq_vec[v].iov_len) {
		len -= rqstp->rq_vec[v].iov_len;
		len -= rqstp->rq_vec[v].iov_len;
@@ -564,6 +566,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
					struct nfsd3_readdirargs *args)
					struct nfsd3_readdirargs *args)
{
{
	int len, pn;
	int len, pn;
	u32 max_blocksize = svc_max_payload(rqstp);


	if (!(p = decode_fh(p, &args->fh)))
	if (!(p = decode_fh(p, &args->fh)))
		return 0;
		return 0;
@@ -572,7 +575,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
	args->dircount = ntohl(*p++);
	args->dircount = ntohl(*p++);
	args->count    = ntohl(*p++);
	args->count    = ntohl(*p++);


	len = (args->count > NFSSVC_MAXBLKSIZE) ? NFSSVC_MAXBLKSIZE :
	len = (args->count > max_blocksize) ? max_blocksize :
						  args->count;
						  args->count;
	args->count = len;
	args->count = len;


+3 −3
Original line number Original line Diff line number Diff line
@@ -1536,12 +1536,12 @@ out_acl:
	if (bmval0 & FATTR4_WORD0_MAXREAD) {
	if (bmval0 & FATTR4_WORD0_MAXREAD) {
		if ((buflen -= 8) < 0)
		if ((buflen -= 8) < 0)
			goto out_resource;
			goto out_resource;
		WRITE64((u64) NFSSVC_MAXBLKSIZE);
		WRITE64((u64) svc_max_payload(rqstp));
	}
	}
	if (bmval0 & FATTR4_WORD0_MAXWRITE) {
	if (bmval0 & FATTR4_WORD0_MAXWRITE) {
		if ((buflen -= 8) < 0)
		if ((buflen -= 8) < 0)
			goto out_resource;
			goto out_resource;
		WRITE64((u64) NFSSVC_MAXBLKSIZE);
		WRITE64((u64) svc_max_payload(rqstp));
	}
	}
	if (bmval1 & FATTR4_WORD1_MODE) {
	if (bmval1 & FATTR4_WORD1_MODE) {
		if ((buflen -= 4) < 0)
		if ((buflen -= 4) < 0)
@@ -2055,7 +2055,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr,


	RESERVE_SPACE(8); /* eof flag and byte count */
	RESERVE_SPACE(8); /* eof flag and byte count */


	maxcount = NFSSVC_MAXBLKSIZE;
	maxcount = svc_max_payload(resp->rqstp);
	if (maxcount > read->rd_length)
	if (maxcount > read->rd_length)
		maxcount = read->rd_length;
		maxcount = read->rd_length;


+3 −3
Original line number Original line Diff line number Diff line
@@ -146,13 +146,13 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
	 * status, 17 words for fattr, and 1 word for the byte count.
	 * status, 17 words for fattr, and 1 word for the byte count.
	 */
	 */


	if (NFSSVC_MAXBLKSIZE < argp->count) {
	if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
		printk(KERN_NOTICE
		printk(KERN_NOTICE
			"oversized read request from %u.%u.%u.%u:%d (%d bytes)\n",
			"oversized read request from %u.%u.%u.%u:%d (%d bytes)\n",
				NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
				NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
				ntohs(rqstp->rq_addr.sin_port),
				ntohs(rqstp->rq_addr.sin_port),
				argp->count);
				argp->count);
		argp->count = NFSSVC_MAXBLKSIZE;
		argp->count = NFSSVC_MAXBLKSIZE_V2;
	}
	}
	svc_reserve(rqstp, (19<<2) + argp->count + 4);
	svc_reserve(rqstp, (19<<2) + argp->count + 4);


@@ -553,7 +553,7 @@ static struct svc_procedure nfsd_procedures2[18] = {
  PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
  PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
  PROC(lookup,	 diropargs,	diropres,	fhandle,	RC_NOCACHE, ST+FH+AT),
  PROC(lookup,	 diropargs,	diropres,	fhandle,	RC_NOCACHE, ST+FH+AT),
  PROC(readlink, readlinkargs,	readlinkres,	none,		RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
  PROC(readlink, readlinkargs,	readlinkres,	none,		RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
  PROC(read,	 readargs,	readres,	fhandle,	RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4),
  PROC(read,	 readargs,	readres,	fhandle,	RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4),
  PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
  PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
  PROC(write,	 writeargs,	attrstat,	fhandle,	RC_REPLBUFF, ST+AT),
  PROC(write,	 writeargs,	attrstat,	fhandle,	RC_REPLBUFF, ST+AT),
  PROC(create,	 createargs,	diropres,	fhandle,	RC_REPLBUFF, ST+FH+AT),
  PROC(create,	 createargs,	diropres,	fhandle,	RC_REPLBUFF, ST+FH+AT),
+5 −5
Original line number Original line Diff line number Diff line
@@ -254,8 +254,8 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
	len = args->count     = ntohl(*p++);
	len = args->count     = ntohl(*p++);
	p++; /* totalcount - unused */
	p++; /* totalcount - unused */


	if (len > NFSSVC_MAXBLKSIZE)
	if (len > NFSSVC_MAXBLKSIZE_V2)
		len = NFSSVC_MAXBLKSIZE;
		len = NFSSVC_MAXBLKSIZE_V2;


	/* set up somewhere to store response.
	/* set up somewhere to store response.
	 * We take pages, put them on reslist and include in iovec
	 * We take pages, put them on reslist and include in iovec
@@ -288,8 +288,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
	rqstp->rq_vec[0].iov_base = (void*)p;
	rqstp->rq_vec[0].iov_base = (void*)p;
	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
				(((void*)p) - rqstp->rq_arg.head[0].iov_base);
				(((void*)p) - rqstp->rq_arg.head[0].iov_base);
	if (len > NFSSVC_MAXBLKSIZE)
	if (len > NFSSVC_MAXBLKSIZE_V2)
		len = NFSSVC_MAXBLKSIZE;
		len = NFSSVC_MAXBLKSIZE_V2;
	v = 0;
	v = 0;
	while (len > rqstp->rq_vec[v].iov_len) {
	while (len > rqstp->rq_vec[v].iov_len) {
		len -= rqstp->rq_vec[v].iov_len;
		len -= rqstp->rq_vec[v].iov_len;
@@ -458,7 +458,7 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
{
{
	struct kstatfs	*stat = &resp->stats;
	struct kstatfs	*stat = &resp->stats;


	*p++ = htonl(NFSSVC_MAXBLKSIZE);	/* max transfer size */
	*p++ = htonl(NFSSVC_MAXBLKSIZE_V2);	/* max transfer size */
	*p++ = htonl(stat->f_bsize);
	*p++ = htonl(stat->f_bsize);
	*p++ = htonl(stat->f_blocks);
	*p++ = htonl(stat->f_blocks);
	*p++ = htonl(stat->f_bfree);
	*p++ = htonl(stat->f_bfree);
Loading