diff mbox

nfsd: don't break lease on CLAIM_DELEGATE_CUR

Message ID 20110725202509.GA27002@fieldses.org (mailing list archive)
State New, archived
Headers show

Commit Message

J. Bruce Fields July 25, 2011, 8:25 p.m. UTC
The real bug here is in the lease code, but my previous attempt at the
needs some revision and testing, it's an annoying bug, and Casey's patch
(below) is simple and easy to backport to stable, so I'm planning on
applying this and then queueing up the proper fix later, absent any
objections.

--b.

commit 0c12eaffdf09466f36a9ffe970dda8f4aeb6efc0
Author: Casey Bodley <cbodley@citi.umich.edu>
Date:   Sat Jul 23 14:58:10 2011 -0400

    nfsd: don't break lease on CLAIM_DELEGATE_CUR
    
    CLAIM_DELEGATE_CUR is used in response to a broken lease; allowing it
    to break the lease and return EAGAIN leaves the client unable to make
    progress in returning the delegation
    
    nfs4_get_vfs_file() now takes struct nfsd4_open for access to the
    claim type, and calls nfsd_open() with NFSD_MAY_NOT_BREAK_LEASE when
    claim type is CLAIM_DELEGATE_CUR
    
    Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
    Cc: stable@kernel.org
    Signed-off-by: J. Bruce Fields <bfields@redhat.com>

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 47da5257..3787ec1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2585,12 +2585,18 @@  static inline int nfs4_access_to_access(u32 nfs4_access)
 	return flags;
 }
 
-static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
-*fp, struct svc_fh *cur_fh, u32 nfs4_access)
+static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
+		struct svc_fh *cur_fh, struct nfsd4_open *open)
 {
 	__be32 status;
-	int oflag = nfs4_access_to_omode(nfs4_access);
-	int access = nfs4_access_to_access(nfs4_access);
+	int oflag = nfs4_access_to_omode(open->op_share_access);
+	int access = nfs4_access_to_access(open->op_share_access);
+
+	/* CLAIM_DELEGATE_CUR is used in response to a broken lease;
+	 * allowing it to break the lease and return EAGAIN leaves the
+	 * client unable to make progress in returning the delegation */
+	if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
+		access |= NFSD_MAY_NOT_BREAK_LEASE;
 
 	if (!fp->fi_fds[oflag]) {
 		status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
@@ -2615,7 +2621,7 @@  nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
 	if (stp == NULL)
 		return nfserr_resource;
 
-	status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access);
+	status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
 	if (status) {
 		kmem_cache_free(stateid_slab, stp);
 		return status;
@@ -2648,7 +2654,7 @@  nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
 
 	new_access = !test_bit(op_share_access, &stp->st_access_bmap);
 	if (new_access) {
-		status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access);
+		status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
 		if (status)
 			return status;
 	}