From: NeilBrown 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 Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- fs/nfsd/nfs4state.c | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-) diff -puN fs/nfsd/nfs4state.c~nfsd4-fix-setclientid_confirm-cases fs/nfsd/nfs4state.c --- 25/fs/nfsd/nfs4state.c~nfsd4-fix-setclientid_confirm-cases Thu Jun 2 16:25:21 2005 +++ 25-akpm/fs/nfsd/nfs4state.c Thu Jun 2 16:25:21 2005 @@ -887,10 +887,14 @@ nfsd4_setclientid_confirm(struct svc_rqs 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_rqs 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; } _