diff options
author | Casey Bodley <cbodley@citi.umich.edu> | 2011-07-23 14:58:10 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-07-23 14:58:17 -0400 |
commit | 0c12eaffdf09466f36a9ffe970dda8f4aeb6efc0 (patch) | |
tree | f799f3f33325fbe6411341375a43b0d9dba7e920 | |
parent | 8fb47a4fbf858a164e973b8ea8ef5e83e61f2e50 (diff) |
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>
-rw-r--r-- | fs/nfsd/nfs4state.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 47da52576e66..3787ec117400 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) | |||
2585 | return flags; | 2585 | return flags; |
2586 | } | 2586 | } |
2587 | 2587 | ||
2588 | static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file | 2588 | static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, |
2589 | *fp, struct svc_fh *cur_fh, u32 nfs4_access) | 2589 | struct svc_fh *cur_fh, struct nfsd4_open *open) |
2590 | { | 2590 | { |
2591 | __be32 status; | 2591 | __be32 status; |
2592 | int oflag = nfs4_access_to_omode(nfs4_access); | 2592 | int oflag = nfs4_access_to_omode(open->op_share_access); |
2593 | int access = nfs4_access_to_access(nfs4_access); | 2593 | int access = nfs4_access_to_access(open->op_share_access); |
2594 | |||
2595 | /* CLAIM_DELEGATE_CUR is used in response to a broken lease; | ||
2596 | * allowing it to break the lease and return EAGAIN leaves the | ||
2597 | * client unable to make progress in returning the delegation */ | ||
2598 | if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) | ||
2599 | access |= NFSD_MAY_NOT_BREAK_LEASE; | ||
2594 | 2600 | ||
2595 | if (!fp->fi_fds[oflag]) { | 2601 | if (!fp->fi_fds[oflag]) { |
2596 | status = nfsd_open(rqstp, cur_fh, S_IFREG, access, | 2602 | status = nfsd_open(rqstp, cur_fh, S_IFREG, access, |
@@ -2615,7 +2621,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, | |||
2615 | if (stp == NULL) | 2621 | if (stp == NULL) |
2616 | return nfserr_resource; | 2622 | return nfserr_resource; |
2617 | 2623 | ||
2618 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access); | 2624 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); |
2619 | if (status) { | 2625 | if (status) { |
2620 | kmem_cache_free(stateid_slab, stp); | 2626 | kmem_cache_free(stateid_slab, stp); |
2621 | return status; | 2627 | return status; |
@@ -2648,7 +2654,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c | |||
2648 | 2654 | ||
2649 | new_access = !test_bit(op_share_access, &stp->st_access_bmap); | 2655 | new_access = !test_bit(op_share_access, &stp->st_access_bmap); |
2650 | if (new_access) { | 2656 | if (new_access) { |
2651 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access); | 2657 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); |
2652 | if (status) | 2658 | if (status) |
2653 | return status; | 2659 | return status; |
2654 | } | 2660 | } |