From: "Antti Tönkyrä" <daedalus@pingtimeout.net>
To: Trond Myklebust <trond.myklebust@primarydata.com>,
Dr Fields James Bruce <bfields@fieldses.org>
Cc: Linux NFS Mailing List <linux-nfs@vger.kernel.org>
Subject: Re: Patch for mapping EILSEQ into NFSERR_INVAL
Date: Thu, 05 Dec 2013 10:39:17 +0200 [thread overview]
Message-ID: <52A03BB5.3010803@pingtimeout.net> (raw)
In-Reply-To: <1386197350.31895.2.camel@leira.trondhjem.org>
On 2013-12-05 00:49, Trond Myklebust wrote:
> On Wed, 2013-12-04 at 16:38 -0500, Dr Fields James Bruce wrote:
>> On Wed, Dec 04, 2013 at 04:22:48PM -0500, Trond Myklebust wrote:
>>> On Dec 4, 2013, at 16:03, Dr Fields James Bruce <bfields@fieldses.org> wrote:
>>>
>>>> On Wed, Dec 04, 2013 at 10:44:45PM +0200, Antti Tönkyrä wrote:
>>>>
>>>>>>> http://daedalus.pingtimeout.net/dbg/eilseq_ioerr.pcap
>>>> And I see something I'd overlooked before: the client is sending the
>>>> later opens with the same open owner and sequence id. But NFS4ERR_IO is
>>>> a seqid-mutating error. So now I think this probably *is* a client
>>>> bug....
>>> Umm… Yes and no. The client should be able to recover when it discovers that the seqid is out of sync.
>>>
>>> That said, I see that we do
>>>
>>> status = decode_op_hdr(xdr, OP_OPEN);
>>> if (status != -EIO)
>>> nfs_increment_open_seqid(status, res->seqid);
>>>
>>> and since NFS4ERR_IO == EIO, that means we skip the seqid update when you send us NFS4ERR_IO.
>> Oh, OK. Maybe decode_op_hdr could use -NFS4ERR_BADXDR for the two
>> decoding errors it catches and eliminate the need for this special -EIO
>> case?
> That is sort of hackish. How about something like the following patch.
>
>> I think NFS4ERR_IO is a legal error for these operations. (Even if the
>> server should have returned something else in this case.)
> It is legal for OPEN. It does not seem to be legal for OPEN_CONFIRM,
> LOCK, LOCKU, CLOSE or OPEN_DOWNGRADE according to RFC3530bis.
>
> Cheers
> Trond
>
> 8<--------------------------------------------------------
> From 968a89bfaf176d70352bb1c0003bf496fdc180aa Mon Sep 17 00:00:00 2001
> From: Trond Myklebust <Trond.Myklebust@netapp.com>
> Date: Wed, 4 Dec 2013 17:39:23 -0500
> Subject: [PATCH] NFSv4: OPEN must handle the NFS4ERR_IO return code correctly
>
> decode_op_hdr() cannot distinguish between an XDR decoding error and
> the perfectly valid errorcode NFS4ERR_IO. This is normally not a
> problem, but for the particular case of OPEN, we need to be able
> to increment the NFSv4 open sequence id when the server returns
> a valid response.
>
> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
> ---
> fs/nfs/nfs4xdr.c | 47 +++++++++++++++++++++++++++++++----------------
> 1 file changed, 31 insertions(+), 16 deletions(-)
>
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 5be2868c02f1..8c21d69a9dc1 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -3097,7 +3097,8 @@ out_overflow:
> return -EIO;
> }
>
> -static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
> +static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected,
> + int *nfs_retval)
> {
> __be32 *p;
> uint32_t opnum;
> @@ -3107,19 +3108,32 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
> if (unlikely(!p))
> goto out_overflow;
> opnum = be32_to_cpup(p++);
> - if (opnum != expected) {
> - dprintk("nfs: Server returned operation"
> - " %d but we issued a request for %d\n",
> - opnum, expected);
> - return -EIO;
> - }
> + if (unlikely(opnum != expected))
> + goto out_bad_operation;
> nfserr = be32_to_cpup(p);
> - if (nfserr != NFS_OK)
> - return nfs4_stat_to_errno(nfserr);
> - return 0;
> + if (nfserr == NFS_OK)
> + *nfs_retval = 0;
> + else
> + *nfs_retval = nfs4_stat_to_errno(nfserr);
> + return true;
> +out_bad_operation:
> + dprintk("nfs: Server returned operation"
> + " %d but we issued a request for %d\n",
> + opnum, expected);
> + *nfs_retval = -EREMOTEIO;
> + return false;
> out_overflow:
> print_overflow_msg(__func__, xdr);
> - return -EIO;
> + *nfs_retval = -EIO;
> + return false;
> +}
> +
> +static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
> +{
> + int retval;
> +
> + __decode_op_hdr(xdr, expected, &retval);
> + return retval;
> }
>
> /* Dummy routine */
> @@ -5001,11 +5015,12 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
> uint32_t savewords, bmlen, i;
> int status;
>
> - status = decode_op_hdr(xdr, OP_OPEN);
> - if (status != -EIO)
> - nfs_increment_open_seqid(status, res->seqid);
> - if (!status)
> - status = decode_stateid(xdr, &res->stateid);
> + if (!__decode_op_hdr(xdr, OP_OPEN, &status))
> + return status;
> + nfs_increment_open_seqid(status, res->seqid);
> + if (status)
> + return status;
> + status = decode_stateid(xdr, &res->stateid);
> if (unlikely(status))
> return status;
>
I compiled 3.13-rc1 with that patch included.
Touching the file now returns I/O error just like before but the share
doesn't die anymore so the patch works.
- Antti
next prev parent reply other threads:[~2013-12-05 8:39 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-02 20:21 Patch for mapping EILSEQ into NFSERR_INVAL Antti Tönkyrä
2013-12-02 20:45 ` Trond Myklebust
2013-12-02 20:52 ` Antti Tönkyrä
2013-12-03 20:48 ` Dr Fields James Bruce
2013-12-03 21:22 ` Dr Fields James Bruce
2013-12-04 6:55 ` Antti Tönkyrä
2013-12-04 15:41 ` Dr Fields James Bruce
2013-12-04 20:44 ` Antti Tönkyrä
2013-12-04 21:03 ` Dr Fields James Bruce
2013-12-04 21:08 ` Antti Tönkyrä
2013-12-04 21:22 ` Trond Myklebust
2013-12-04 21:38 ` Dr Fields James Bruce
2013-12-04 22:49 ` Trond Myklebust
2013-12-05 8:39 ` Antti Tönkyrä [this message]
2013-12-04 12:33 ` Antti Tönkyrä
2013-12-04 12:40 ` Antti Tönkyrä
2013-12-04 8:31 ` Christoph Hellwig
2013-12-04 11:15 ` Antti Tönkyrä
2013-12-04 11:19 ` Christoph Hellwig
2013-12-04 11:34 ` Antti Tönkyrä
2013-12-05 19:45 ` J. Bruce Fields
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=52A03BB5.3010803@pingtimeout.net \
--to=daedalus@pingtimeout.net \
--cc=bfields@fieldses.org \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@primarydata.com \
/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;
as well as URLs for NNTP newsgroup(s).