From: Anna Schumaker <schumaker.anna@gmail.com>
To: andros@netapp.com, trond.myklebust@primarydata.com
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH 2/4] NFSv4 Check errors on stateid changed functions in I/O path
Date: Tue, 04 Mar 2014 13:08:08 -0500 [thread overview]
Message-ID: <53161688.6030204@gmail.com> (raw)
In-Reply-To: <1393954269-3974-3-git-send-email-andros@netapp.com>
On 03/04/2014 12:31 PM, andros@netapp.com wrote:
> From: Andy Adamson <andros@netapp.com>
>
> Retry I/O from the call prepare state (with the new stateid) if the stateid
> has changed on an stateid expired error
>
> Fail the I/O if the statied represents a lost lock.
>
> Otherwise, let the error handler decide what to do.
>
> Without this change, I/O with a stateid expired error such as
> NFS4ERR_BAD_STATEID can be retried without recovery and loop forever.
>
> Signed-off-by: Andy Adamson <andros@netapp.com>
> ---
> fs/nfs/nfs4proc.c | 77 +++++++++++++++++++++++++++++++++++++++++++------------
> 1 file changed, 60 insertions(+), 17 deletions(-)
>
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 2f1997d..de8e7f5 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -4107,29 +4107,49 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
> return 0;
> }
>
> -static bool nfs4_read_stateid_changed(struct rpc_task *task,
> +static int nfs4_read_stateid_changed(struct rpc_task *task,
> struct nfs_readargs *args)
> {
> + int ret;
>
> - if (!nfs4_error_stateid_expired(task->tk_status) ||
> - nfs4_stateid_is_current(&args->stateid,
> + ret = nfs4_stateid_is_current(&args->stateid,
> args->context,
> args->lock_context,
> - FMODE_READ))
> - return false;
> - rpc_restart_call_prepare(task);
> - return true;
> + FMODE_READ);
> + switch (ret) {
> + case 0: /* stateid changed */
> + if (nfs4_error_stateid_expired(task->tk_status)) {
> + /* stateid expired error, retry with changed stateid */
> + rpc_restart_call_prepare(task);
> + return -EAGAIN;
> + }
> + return 0; /* let error handler proceed */
> +
> + case -EIO: /* -EIO means lock stateid was lost: fail the I/O */
> + task->tk_status = -EIO;
> + return -EIO;
> +
> + case -EWOULDBLOCK: /* stateid change in progress */
> + default:/* stateid has not changed, let error handler proceed.*/
> + return 0;
> +
> + }
> }
This bit of code exists down below, too. Is there any reason it can't be an error handling function?
Anna
>
> static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
> {
> + int ret;
>
> dprintk("--> %s\n", __func__);
>
> if (!nfs4_sequence_done(task, &data->res.seq_res))
> return -EAGAIN;
> - if (nfs4_read_stateid_changed(task, &data->args))
> - return -EAGAIN;
> + ret = nfs4_read_stateid_changed(task, &data->args);
> + switch (ret) {
> + case -EAGAIN:
> + case -EIO:
> + return ret;
> + }
> return data->read_done_cb ? data->read_done_cb(task, data) :
> nfs4_read_done_cb(task, data);
> }
> @@ -4176,23 +4196,46 @@ static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data
> static bool nfs4_write_stateid_changed(struct rpc_task *task,
> struct nfs_writeargs *args)
> {
> + int ret;
>
> - if (!nfs4_error_stateid_expired(task->tk_status) ||
> - nfs4_stateid_is_current(&args->stateid,
> + ret = nfs4_stateid_is_current(&args->stateid,
> args->context,
> args->lock_context,
> - FMODE_WRITE))
> - return false;
> - rpc_restart_call_prepare(task);
> - return true;
> + FMODE_WRITE);
> +
> + switch (ret) {
> + case 0: /* stateid changed */
> + if (nfs4_error_stateid_expired(task->tk_status)) {
> + /* stateid expired error, retry with changed stateid */
> + rpc_restart_call_prepare(task);
> + return -EAGAIN;
> + }
> + return 0; /* let error handler proceed */
> +
> + case -EIO: /* -EIO means lock stateid was lost: fail the I/O */
> + task->tk_status = -EIO;
> + return -EIO;
> +
> + case -EWOULDBLOCK: /* stateid change in progress */
> + default:/* stateid has not changed, let error handler proceed.*/
> + return 0;
> +
> + }
> }
>
> static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
> {
> + int ret;
> +
> if (!nfs4_sequence_done(task, &data->res.seq_res))
> return -EAGAIN;
> - if (nfs4_write_stateid_changed(task, &data->args))
> - return -EAGAIN;
> +
> + ret = nfs4_write_stateid_changed(task, &data->args);
> + switch (ret) {
> + case -EAGAIN:
> + case -EIO:
> + return ret;
> + }
> return data->write_done_cb ? data->write_done_cb(task, data) :
> nfs4_write_done_cb(task, data);
> }
next prev parent reply other threads:[~2014-03-04 18:08 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-04 17:31 [PATCH 0/4] NFSv4 fix nfs4_stateid_is_current processing andros
2014-03-04 17:31 ` [PATCH 1/4] NFSv4 propagate nfs4_stateid_is_current errors andros
2014-03-04 17:31 ` [PATCH 2/4] NFSv4 Check errors on stateid changed functions in I/O path andros
2014-03-04 18:08 ` Anna Schumaker [this message]
2014-03-05 8:52 ` Andy Adamson
2014-03-04 17:31 ` [PATCH 3/4] NFSv4 _nfs4_do_setattr use zero stateid on lost lock andros
2014-03-04 18:42 ` Trond Myklebust
2014-03-05 8:51 ` Andy Adamson
2014-03-05 13:04 ` Trond Myklebust
2014-03-04 17:31 ` [PATCH 4/4] NFSv4.1 Fail data server I/O if stateid represents a " andros
2014-03-04 17:33 ` Trond Myklebust
2014-03-04 18:09 ` [PATCH 0/4] NFSv4 fix nfs4_stateid_is_current processing Trond Myklebust
2014-03-05 10:58 ` Andy Adamson
2014-03-05 13:13 ` Trond Myklebust
2014-03-04 19:05 ` [PATCH v2 0/3] " Trond Myklebust
2014-03-04 19:05 ` [PATCH v2 1/3] NFSv4: Fix the return value of nfs4_select_rw_stateid Trond Myklebust
2014-03-04 19:05 ` [PATCH v2 2/3] NFSv4.1 Fail data server I/O if stateid represents a lost lock Trond Myklebust
2014-03-04 19:05 ` [PATCH v2 3/3] NFSv4: Fail the truncate() if the lock/open stateid is invalid Trond Myklebust
2014-03-05 11:40 ` Andy Adamson
2014-03-05 13:29 ` Trond Myklebust
2014-03-05 10:59 ` [PATCH v2 0/3] NFSv4 fix nfs4_stateid_is_current processing Andy Adamson
2014-03-05 14:07 ` [PATCH v3 0/4] " Trond Myklebust
2014-03-05 14:07 ` [PATCH v3 1/4] NFSv4: nfs4_stateid_is_current should return 'true' for an invalid stateid Trond Myklebust
2014-03-05 14:07 ` [PATCH v3 2/4] NFSv4: Fix the return value of nfs4_select_rw_stateid Trond Myklebust
2014-03-05 14:07 ` [PATCH v3 3/4] NFSv4.1 Fail data server I/O if stateid represents a lost lock Trond Myklebust
2014-03-05 14:07 ` [PATCH v3 4/4] NFSv4: Fail the truncate() if the lock/open stateid is invalid Trond Myklebust
2014-03-05 18:30 ` [PATCH v4 0/4] NFSv4 fix nfs4_stateid_is_current processing Trond Myklebust
2014-03-05 18:30 ` [PATCH v4 1/4] NFSv4: nfs4_stateid_is_current should return 'true' for an invalid stateid Trond Myklebust
2014-03-05 18:30 ` [PATCH v4 2/4] NFSv4: Fix the return value of nfs4_select_rw_stateid Trond Myklebust
2014-03-05 18:30 ` [PATCH v4 3/4] NFSv4.1 Fail data server I/O if stateid represents a lost lock Trond Myklebust
2014-03-05 18:30 ` [PATCH v4 4/4] NFSv4: Fail the truncate() if the lock/open stateid is invalid Trond Myklebust
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=53161688.6030204@gmail.com \
--to=schumaker.anna@gmail.com \
--cc=andros@netapp.com \
--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 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.