linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@redhat.com>
To: linux-nfs@vger.kernel.org
Cc: "J. Bruce Fields" <bfields@citi.umich.edu>
Subject: [PATCH 04/11] nfsd4: make backchannel sequence number per-session
Date: Thu, 21 Oct 2010 12:20:11 -0400	[thread overview]
Message-ID: <1287678018-9266-5-git-send-email-bfields@redhat.com> (raw)
In-Reply-To: <1287678018-9266-1-git-send-email-bfields@redhat.com>

From: J. Bruce Fields <bfields@citi.umich.edu>

Currently we don't deal well with a client that has multiple sessions
associated with it (even simultaneously, or serially over the lifetime
of the client).

In particular, we don't attempt to keep the backchannel running after
the original session diseappears.

We will fix that soon.

Once we do that, we need the slot sequence number to be per-session;
otherwise, for example, we cannot correctly handle a case like this:

	- All session 1 connections are lost.
	- The client creates session 2.  We use it for the backchannel
	  (since it's the only working choice).
	- The client gives us a new connection to use with session 1.
	- The client destroys session 2.

At this point our only choice is to go back to using session 1.  When we
do so we must use the sequence number that is next for session 1.  We
therefore need to maintain multiple sequence number streams.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/nfsd/nfs4callback.c |    8 ++++----
 fs/nfsd/nfs4state.c    |   22 ++++++++++++----------
 fs/nfsd/state.h        |    2 +-
 3 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 78ac779..5df9dda 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -260,7 +260,7 @@ encode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb,
 
 	WRITE32(OP_CB_SEQUENCE);
 	WRITEMEM(ses->se_sessionid.data, NFS4_MAX_SESSIONID_LEN);
-	WRITE32(cb->cb_clp->cl_cb_seq_nr);
+	WRITE32(ses->se_cb_seq_nr);
 	WRITE32(0);		/* slotid, always 0 */
 	WRITE32(0);		/* highest slotid always 0 */
 	WRITE32(0);		/* cachethis always 0 */
@@ -369,7 +369,7 @@ decode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb,
 		goto out;
 	}
 	READ32(dummy);
-	if (dummy != cb->cb_clp->cl_cb_seq_nr) {
+	if (dummy != ses->se_cb_seq_nr) {
 		dprintk("%s Invalid sequence number\n", __func__);
 		goto out;
 	}
@@ -643,11 +643,11 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
 
 	if (clp->cl_cb_conn.cb_minorversion) {
 		/* No need for lock, access serialized in nfsd4_cb_prepare */
-		++clp->cl_cb_seq_nr;
+		++clp->cl_cb_session->se_cb_seq_nr;
 		clear_bit(0, &clp->cl_cb_slot_busy);
 		rpc_wake_up_next(&clp->cl_cb_waitq);
 		dprintk("%s: freed slot, new seqid=%d\n", __func__,
-			clp->cl_cb_seq_nr);
+			clp->cl_cb_session->se_cb_seq_nr);
 
 		/* We're done looking into the sequence information */
 		task->tk_msg.rpc_resp = NULL;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c942511..6367c44 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -725,8 +725,7 @@ void free_session(struct kref *kref)
 	kfree(ses);
 }
 
-
-static __be32 alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses)
+static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses)
 {
 	struct nfsd4_session *new;
 	struct nfsd4_channel_attrs *fchan = &cses->fore_channel;
@@ -747,7 +746,7 @@ static __be32 alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp
 	new = alloc_session(slotsize, numslots);
 	if (!new) {
 		nfsd4_put_drc_mem(slotsize, fchan->maxreqs);
-		return nfserr_jukebox;
+		return NULL;
 	}
 	init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize);
 
@@ -756,6 +755,7 @@ static __be32 alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp
 
 	INIT_LIST_HEAD(&new->se_conns);
 
+	new->se_cb_seq_nr = 1;
 	new->se_flags = cses->flags;
 	kref_init(&new->se_ref);
 	idx = hash_sessionid(&new->se_sessionid);
@@ -765,9 +765,10 @@ static __be32 alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp
 	spin_unlock(&client_lock);
 
 	status = nfsd4_new_conn(rqstp, new);
+	/* whoops: benny points out, status is ignored! (err, or bogus) */
 	if (status) {
 		free_session(&new->se_ref);
-		return nfserr_jukebox;
+		return NULL;
 	}
 	if (!clp->cl_cb_session && (cses->flags & SESSION4_BACK_CHAN)) {
 		struct sockaddr *sa = svc_addr(rqstp);
@@ -779,10 +780,9 @@ static __be32 alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp
 		clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
 		clp->cl_cb_conn.cb_minorversion = 1;
 		clp->cl_cb_conn.cb_prog = cses->callback_prog;
-		clp->cl_cb_seq_nr = 1;
 		nfsd4_probe_callback(clp, &clp->cl_cb_conn);
 	}
-	return nfs_ok;
+	return new;
 }
 
 /* caller must hold client_lock */
@@ -1485,6 +1485,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
 {
 	struct sockaddr *sa = svc_addr(rqstp);
 	struct nfs4_client *conf, *unconf;
+	struct nfsd4_session *new;
 	struct nfsd4_clid_slot *cs_slot = NULL;
 	int status = 0;
 
@@ -1538,11 +1539,12 @@ nfsd4_create_session(struct svc_rqst *rqstp,
 	cr_ses->flags &= ~SESSION4_PERSIST;
 	cr_ses->flags &= ~SESSION4_RDMA;
 
-	status = alloc_init_session(rqstp, conf, cr_ses);
-	if (status)
+	status = nfserr_jukebox;
+	new = alloc_init_session(rqstp, conf, cr_ses);
+	if (!new)
 		goto out;
-
-	memcpy(cr_ses->sessionid.data, conf->cl_cb_session->se_sessionid.data,
+	status = nfs_ok;
+	memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
 	       NFS4_MAX_SESSIONID_LEN);
 	cr_ses->seqid = cs_slot->sl_seqid;
 
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index cdce26a..7f5b267 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -172,6 +172,7 @@ struct nfsd4_session {
 	struct nfsd4_channel_attrs se_fchannel;
 	struct nfsd4_channel_attrs se_bchannel;
 	struct list_head	se_conns;
+	u32			se_cb_seq_nr;
 	struct nfsd4_slot	*se_slots[];	/* forward channel slots */
 };
 
@@ -249,7 +250,6 @@ struct nfs4_client {
 	/* for nfs41 callbacks */
 	/* We currently support a single back channel with a single slot */
 	unsigned long		cl_cb_slot_busy;
-	u32			cl_cb_seq_nr;
 	struct rpc_wait_queue	cl_cb_waitq;	/* backchannel callers may */
 						/* wait here for slots */
 };
-- 
1.7.1


  parent reply	other threads:[~2010-10-21 16:20 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-21 16:20 sessions patches J. Bruce Fields
2010-10-21 16:20 ` [PATCH 01/11] nfsd4: don't cache seq_misordered replies J. Bruce Fields
2010-10-21 16:20 ` [PATCH 02/11] nfsd4: move callback setup into session init code J. Bruce Fields
2010-10-27 17:26   ` Benny Halevy
2010-10-27 17:45     ` Benny Halevy
2010-10-27 17:59       ` J. Bruce Fields
2010-10-27 18:03         ` Benny Halevy
2010-10-21 16:20 ` [PATCH 03/11] nfsd4: use client pointer to backchannel session J. Bruce Fields
2010-10-21 16:20 ` J. Bruce Fields [this message]
2010-10-21 16:20 ` [PATCH 05/11] nfsd4: confirm only on succesful create_session J. Bruce Fields
2010-10-21 16:20 ` [PATCH 06/11] nfsd4: track backchannel connections J. Bruce Fields
2010-10-21 16:20 ` [PATCH 07/11] nfsd4: callback program number is per-session J. Bruce Fields
2010-10-21 16:20 ` [PATCH 08/11] nfsd4: separate callback change and callback probe J. Bruce Fields
2010-10-21 16:20 ` [PATCH 09/11] nfsd4: delay session removal till free_client J. Bruce Fields
2010-10-21 16:20 ` [PATCH 10/11] nfsd4: move minorversion to client J. Bruce Fields
2010-10-21 16:20 ` [PATCH 11/11] nfsd4: only require krb5 principal for NFSv4.0 callbacks J. Bruce Fields
2010-10-25  1:06 ` sessions patches 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=1287678018-9266-5-git-send-email-bfields@redhat.com \
    --to=bfields@redhat.com \
    --cc=bfields@citi.umich.edu \
    --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 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).