From: NeilBrown <neilb@cse.unsw.edu.au>

If the client was given a delegation, but our callback path to the client has
since failed for some reason, then our only chance to inform the client of this
is to return the cb_path_down error next time the client attempts to renew its
state.

Signed-off-by: Andy Adamson <andros@citi.umich.edu>
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>
---

 25-akpm/fs/nfsd/nfs4state.c       |   20 ++++++++++----------
 25-akpm/include/linux/nfsd/nfsd.h |    1 +
 2 files changed, 11 insertions(+), 10 deletions(-)

diff -puN fs/nfsd/nfs4state.c~nfsd4-provide-no_cb_path-error-on-renew fs/nfsd/nfs4state.c
--- 25/fs/nfsd/nfs4state.c~nfsd4-provide-no_cb_path-error-on-renew	2005-03-07 23:55:37.000000000 -0800
+++ 25-akpm/fs/nfsd/nfs4state.c	2005-03-07 23:55:37.000000000 -0800
@@ -1809,19 +1809,19 @@ nfsd4_renew(clientid_t *clid)
 	status = nfserr_stale_clientid;
 	if (STALE_CLIENTID(clid))
 		goto out;
-	status = nfs_ok;
 	clp = find_confirmed_client(clid);
-	if (clp) {
-		renew_client(clp);
+	status = nfserr_expired;
+	if (clp == NULL) {
+		/* We assume the client took too long to RENEW. */
+		dprintk("nfsd4_renew: clientid not found!\n");
 		goto out;
 	}
-	/*
-	* Couldn't find an nfs4_client for this clientid.  
-	* Presumably this is because the client took too long to 
-	* RENEW, so return NFS4ERR_EXPIRED.
-	*/
-	dprintk("nfsd4_renew: clientid not found!\n");
-	status = nfserr_expired;
+	renew_client(clp);
+	status = nfserr_cb_path_down;
+	if (!list_empty(&clp->cl_del_perclnt)
+			&& !atomic_read(&clp->cl_callback.cb_set))
+		goto out;
+	status = nfs_ok;
 out:
 	nfs4_unlock_state();
 	return status;
diff -puN include/linux/nfsd/nfsd.h~nfsd4-provide-no_cb_path-error-on-renew include/linux/nfsd/nfsd.h
--- 25/include/linux/nfsd/nfsd.h~nfsd4-provide-no_cb_path-error-on-renew	2005-03-07 23:55:37.000000000 -0800
+++ 25-akpm/include/linux/nfsd/nfsd.h	2005-03-07 23:55:37.000000000 -0800
@@ -209,6 +209,7 @@ void		nfsd_lockd_shutdown(void);
 #define	nfserr_no_grace		__constant_htonl(NFSERR_NO_GRACE)
 #define	nfserr_reclaim_bad	__constant_htonl(NFSERR_RECLAIM_BAD)
 #define	nfserr_badname		__constant_htonl(NFSERR_BADNAME)
+#define	nfserr_cb_path_down	__constant_htonl(NFSERR_CB_PATH_DOWN)
 
 /* error codes for internal use */
 /* if a request fails due to kmalloc failure, it gets dropped.
_