All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven <steven@void.org>
To: nfs@lists.sourceforge.net
Subject: Minor problem in nfsv3 write
Date: Mon, 19 Sep 2005 18:10:46 -0700	[thread overview]
Message-ID: <20050920011046.23A07F4@dead.void.org> (raw)


There is a minor bug in the way writes are handled in nfs3.  If the
client requests a write for more than 32k of data the server will only
write 32k but report that it wrote the whole amount.

This happens when nfs3svc_decode_writeargs caps the amount that can be
written to NFSSVC_MAXBLKSIZE (which is 32k), by limiting the amount that
it copies into the args object (fs/nfsd/nfs3xdr.c:375).  The amount that
is reported to the client is copied from the request packet, which is
the amount the client requested (fs/nfsd/nfs3proc.c:209) not the amount
which was written.

I think the right thing to do is adjust the amount in the request object
to the amount that will be written in the decoder. 

Following is an modified version of nfs3svc_decode_writeargs and diffs
against a 2.6.13 kernel which does this.

--Steven

int
nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_writeargs *args)
{
        unsigned int len, v, hdr;

        if (!(p = decode_fh(p, &args->fh))
         || !(p = xdr_decode_hyper(p, &args->offset)))
                return 0;

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

        hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
        if (rqstp->rq_arg.len < len + hdr)
                return 0;

        args->vec[0].iov_base = (void*)p;
        args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;

        if (len > NFSSVC_MAXBLKSIZE) {
                len = NFSSVC_MAXBLKSIZE;
                /* adjust count to match the amount that will be written */
                args->count = len;
        }
        v=  0;
        while (len > args->vec[v].iov_len) {
                len -= args->vec[v].iov_len;
                v++;
                args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
                args->vec[v].iov_len = PAGE_SIZE;
        }
        args->vec[v].iov_len = len;
        args->vlen = v+1;

        /* args->count may be less than args->len since it is capped */
        return args->count <= args->len && args->vec[0].iov_len > 0;
}

*** fs/nfsd/nfs3xdr.c.orig	Fri Sep 16 18:02:12 2005
--- fs/nfsd/nfs3xdr.c	Mon Sep 19 17:35:22 2005
***************
*** 372,379 ****
  	args->vec[0].iov_base = (void*)p;
  	args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
  
! 	if (len > NFSSVC_MAXBLKSIZE)
  		len = NFSSVC_MAXBLKSIZE;
  	v=  0;
  	while (len > args->vec[v].iov_len) {
  		len -= args->vec[v].iov_len;
--- 372,382 ----
  	args->vec[0].iov_base = (void*)p;
  	args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
  
! 	if (len > NFSSVC_MAXBLKSIZE) {
  		len = NFSSVC_MAXBLKSIZE;
+ 		/* adjust count to match the amount that will be written */
+ 		args->count = len;
+ 	}
  	v=  0;
  	while (len > args->vec[v].iov_len) {
  		len -= args->vec[v].iov_len;
***************
*** 384,390 ****
  	args->vec[v].iov_len = len;
  	args->vlen = v+1;
  
! 	return args->count == args->len && args->vec[0].iov_len > 0;
  }
  
  int
--- 387,394 ----
  	args->vec[v].iov_len = len;
  	args->vlen = v+1;
  
! 	/* args->count may be less than args->len since it is capped */
! 	return args->count <= args->len && args->vec[0].iov_len > 0;
  }
  
  int


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. 
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

             reply	other threads:[~2005-09-20  1:11 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-20  1:10 Steven [this message]
2005-09-20  1:25 ` Minor problem in nfsv3 write J. Bruce Fields
2005-09-20 12:25   ` Peter Staubach
2005-09-20 18:30     ` Steven
2005-09-20 19:26       ` J. Bruce Fields
2005-09-20 22:19         ` [PATCH] " Steven
2005-09-20 23:46           ` J. Bruce Fields
  -- strict thread matches above, loose matches on Subject: below --
2005-09-20  6:29 Sumeet Gupta

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=20050920011046.23A07F4@dead.void.org \
    --to=steven@void.org \
    --cc=nfs@lists.sourceforge.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.