From bde785c2bea1d8e0d99bf9bffe979540a10c1705 Mon Sep 17 00:00:00 2001
From: Neil Brown <neilb@cse.unsw.edu.au>
Date: Tue, 7 Sep 2004 17:51:40 -0700
Subject: [PATCH] [PATCH] knfsd: calls to break_lease in nfsd should be
 O_NONBLOCKing

If we would block, we return "err-jukebox" for nfsv3, or just drop the request
for v2.

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>
---
 fs/nfsd/nfsproc.c | 1 +
 fs/nfsd/nfssvc.c  | 2 ++
 fs/nfsd/vfs.c     | 8 ++++----
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index d34a59d2848e..13ff22ad23b0 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -586,6 +586,7 @@ nfserrno (int errno)
 		{ nfserr_dquot, -EDQUOT },
 #endif
 		{ nfserr_stale, -ESTALE },
+		{ nfserr_jukebox, -EWOULDBLOCK },
 		{ nfserr_jukebox, -ETIMEDOUT },
 		{ nfserr_dropit, -EAGAIN },
 		{ nfserr_dropit, -ENOMEM },
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index b783620ff9dd..8a06919c7af3 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -328,6 +328,8 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp)
 
 	/* Now call the procedure handler, and encode NFS status. */
 	nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
+	if (nfserr == nfserr_jukebox && rqstp->rq_vers == 2)
+		nfserr = nfserr_dropit;
 	if (nfserr == nfserr_dropit) {
 		dprintk("nfsd: Dropping request due to malloc failure!\n");
 		nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index be03b2734ef5..1db1af42ea33 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -303,8 +303,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 		 * If we are changing the size of the file, then
 		 * we need to break all leases.
 		 */
-		err = break_lease(inode, FMODE_WRITE);
-		if (err)
+		err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
+		if (err) /* ENOMEM or EWOULDBLOCK */
 			goto out_nfserr;
 
 		err = get_write_access(inode);
@@ -669,8 +669,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 	 * Check to see if there are any leases on this file.
 	 * This may block while leases are broken.
 	 */
-	err = break_lease(inode, (access & MAY_WRITE) ? FMODE_WRITE : 0);
-	if (err)
+	err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0));
+	if (err) /* NOMEM or WOULDBLOCK */
 		goto out_nfserr;
 
 	if (access & MAY_WRITE) {
-- 
2.30.9