From: Trond Myklebust <Trond.Myklebust@netapp.com>
To: Ricardo Labiaga <Ricardo.Labiaga@netapp.com>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH 2/2] nfs41: Don't clear DRAINING flag on NFS4ERR_STALE_CLIENTID
Date: Sun, 06 Dec 2009 13:02:40 -0500 [thread overview]
Message-ID: <1260122560.11862.11.camel@localhost> (raw)
In-Reply-To: <1260098184-19209-3-git-send-email-Ricardo.Labiaga@netapp.com>
On Sun, 2009-12-06 at 03:16 -0800, Ricardo Labiaga wrote:
> If CREATE_SESSION fails with NFS4ERR_STALE_CLIENTID, don't clear the
> NFS4CLNT_SESSION_DRAINING flag and don't wake RPCs waiting for the
> session to be reestablished. We don't have a session yet, so there
> is no reason to wake other RPCs.
>
> This avoids sending spurious compounds with bogus sequenceID during
> session and state recovery.
How about the following instead? It ensures that we drain the session
before renewing the lease too.
Cheers
Trond
---------------------------------------------------------------------------------------
nfs41: Don't clear DRAINING flag on NFS4ERR_STALE_CLIENTID
From: Ricardo Labiaga <Ricardo.Labiaga@netapp.com>
If CREATE_SESSION fails with NFS4ERR_STALE_CLIENTID, don't clear the
NFS4CLNT_SESSION_DRAINING flag and don't wake RPCs waiting for the
session to be reestablished. We don't have a session yet, so there
is no reason to wake other RPCs.
This avoids sending spurious compounds with bogus sequenceID during
session and state recovery.
Signed-off-by: Ricardo Labiaga <Ricardo.Labiaga@netapp.com>
[Trond.Myklebust@netapp.com: cleaned up patch by adding the
nfs41_begin/end_drain_session() helpers]
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
fs/nfs/nfs4proc.c | 2 ++
fs/nfs/nfs4state.c | 59 ++++++++++++++++++++++++++++++++++++----------------
2 files changed, 43 insertions(+), 18 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4be0369..fbae2c9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4586,10 +4586,12 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
init_completion(&session->complete);
tbl = &session->fc_slot_table;
+ tbl->highest_used_slotid = -1;
spin_lock_init(&tbl->slot_tbl_lock);
rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
tbl = &session->bc_slot_table;
+ tbl->highest_used_slotid = -1;
spin_lock_init(&tbl->slot_tbl_lock);
rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 9cfe686..1b629cc 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -135,16 +135,43 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
return status;
}
+static void nfs41_end_drain_session(struct nfs_client *clp,
+ struct nfs4_session *ses)
+{
+ if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state))
+ rpc_wake_up(&ses->fc_slot_table.slot_tbl_waitq);
+}
+
+static int nfs41_begin_drain_session(struct nfs_client *clp,
+ struct nfs4_session *ses)
+{
+ struct nfs4_slot_table *tbl = &ses->fc_slot_table;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ set_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state);
+ if (tbl->highest_used_slotid != -1) {
+ INIT_COMPLETION(ses->complete);
+ spin_unlock(&tbl->slot_tbl_lock);
+ return wait_for_completion_interruptible(&ses->complete);
+ }
+ spin_unlock(&tbl->slot_tbl_lock);
+ return 0;
+}
+
int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
{
int status;
+ status = nfs41_begin_drain_session(clp, clp->cl_session);
+ if (status != 0)
+ goto out;
status = nfs4_proc_exchange_id(clp, cred);
if (status != 0)
goto out;
status = nfs4_proc_create_session(clp);
if (status != 0)
goto out;
+ nfs41_end_drain_session(clp, clp->cl_session);
nfs41_setup_state_renewal(clp);
nfs_mark_client_ready(clp, NFS_CS_READY);
out:
@@ -1239,20 +1266,11 @@ static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err)
static int nfs4_reset_session(struct nfs_client *clp)
{
struct nfs4_session *ses = clp->cl_session;
- struct nfs4_slot_table *tbl = &ses->fc_slot_table;
int status;
- spin_lock(&tbl->slot_tbl_lock);
- set_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state);
- if (tbl->highest_used_slotid != -1) {
- INIT_COMPLETION(ses->complete);
- spin_unlock(&tbl->slot_tbl_lock);
- status = wait_for_completion_interruptible(&ses->complete);
- if (status) /* -ERESTARTSYS */
- goto out;
- } else {
- spin_unlock(&tbl->slot_tbl_lock);
- }
+ status = nfs41_begin_drain_session(clp, ses);
+ if (status != 0)
+ return status;
status = nfs4_proc_destroy_session(clp->cl_session);
if (status && status != -NFS4ERR_BADSESSION &&
@@ -1265,13 +1283,18 @@ static int nfs4_reset_session(struct nfs_client *clp)
status = nfs4_proc_create_session(clp);
if (status)
nfs4_session_recovery_handle_error(clp, status);
- /* fall through*/
+
out:
- /* Wake up the next rpc task even on error */
- clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state);
- rpc_wake_up(&clp->cl_session->fc_slot_table.slot_tbl_waitq);
- if (status == 0)
- nfs41_setup_state_renewal(clp);
+ /*
+ * Let the state manager reestablish state
+ * without waking other tasks yet.
+ */
+ if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
+ /* Wake up the next rpc task */
+ nfs41_end_drain_session(clp, ses);
+ if (status == 0)
+ nfs41_setup_state_renewal(clp);
+ }
return status;
}
next prev parent reply other threads:[~2009-12-06 18:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-06 11:16 [PATCH 0/2] Bugfixes for zero stateID RPCs Ricardo Labiaga
2009-12-06 11:16 ` [PATCH 1/2] nfs41: nfs41_setup_state_renewal Ricardo Labiaga
2009-12-06 11:16 ` [PATCH 2/2] nfs41: Don't clear DRAINING flag on NFS4ERR_STALE_CLIENTID Ricardo Labiaga
2009-12-06 17:05 ` Trond Myklebust
2009-12-06 18:02 ` Trond Myklebust [this message]
2009-12-07 8:13 ` Labiaga, Ricardo
2009-12-06 18:02 ` [PATCH 1/2] nfs41: nfs41_setup_state_renewal Trond Myklebust
2009-12-07 8:12 ` Labiaga, Ricardo
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=1260122560.11862.11.camel@localhost \
--to=trond.myklebust@netapp.com \
--cc=Ricardo.Labiaga@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/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.