From: NeilBrown <neilb@cse.unsw.edu.au>
Date: Fri, 24 Jun 2005 05:04:08 +0000 (-0700)
Subject: [PATCH] knfsd: nfsd4: fix setclientid_confirm cases
X-Git-Tag: v2.6.13-rc1~68^2~292
X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=1a69c179a28a9bb9f4d086927b192d5cffe88e50;p=linux-2.6-omap-h63xx.git

[PATCH] knfsd: nfsd4: fix setclientid_confirm cases

Setclientid_confirm code confused states 1 and 3 (numbering from the
IMPLEMENTATION section of rfc3530, section 14.2.33).  Fix this.

State 1 allows the client to change the callback channel on the fly.  We don't
implement this currently, so just turn off the callback channel in this case.

From: Fred Isaman
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 67a038dc0d0..997343c2304 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -887,10 +887,14 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
 		if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred)) 
 			status = nfserr_clid_inuse;
 		else {
-			expire_client(conf);
-			clp = unconf;
-			move_to_confirmed(unconf);
+			/* XXX: We just turn off callbacks until we can handle
+			  * change request correctly. */
+			clp = conf;
+			clp->cl_callback.cb_parsed = 0;
+			gen_confirm(clp);
+			expire_client(unconf);
 			status = nfs_ok;
+
 		}
 		goto out;
 	} 
@@ -920,9 +924,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
 		if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
 			status = nfserr_clid_inuse;
 		} else {
-			status = nfs_ok;
+			unsigned int hash =
+				clientstr_hashval(unconf->cl_recdir);
+			conf = find_confirmed_client_by_str(unconf->cl_recdir,
+									hash);
+			if (conf) {
+				expire_client(conf);
+			}
 			clp = unconf;
 			move_to_confirmed(unconf);
+			status = nfs_ok;
 		}
 		goto out;
 	}