diff options
| -rw-r--r-- | fs/nfsd/nfs4state.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 84d2dd327b2d..c26dc31fb943 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -397,6 +397,9 @@ static void unhash_generic_stateid(struct nfs4_stateid *stp) | |||
| 397 | 397 | ||
| 398 | static void free_generic_stateid(struct nfs4_stateid *stp) | 398 | static void free_generic_stateid(struct nfs4_stateid *stp) |
| 399 | { | 399 | { |
| 400 | int oflag = nfs4_access_bmap_to_omode(stp); | ||
| 401 | |||
| 402 | nfs4_file_put_access(stp->st_file, oflag); | ||
| 400 | put_nfs4_file(stp->st_file); | 403 | put_nfs4_file(stp->st_file); |
| 401 | kmem_cache_free(stateid_slab, stp); | 404 | kmem_cache_free(stateid_slab, stp); |
| 402 | } | 405 | } |
| @@ -448,11 +451,8 @@ release_stateid_lockowners(struct nfs4_stateid *open_stp) | |||
| 448 | 451 | ||
| 449 | static void release_open_stateid(struct nfs4_stateid *stp) | 452 | static void release_open_stateid(struct nfs4_stateid *stp) |
| 450 | { | 453 | { |
| 451 | int oflag = nfs4_access_bmap_to_omode(stp); | ||
| 452 | |||
| 453 | unhash_generic_stateid(stp); | 454 | unhash_generic_stateid(stp); |
| 454 | release_stateid_lockowners(stp); | 455 | release_stateid_lockowners(stp); |
| 455 | nfs4_file_put_access(stp->st_file, oflag); | ||
| 456 | free_generic_stateid(stp); | 456 | free_generic_stateid(stp); |
| 457 | } | 457 | } |
| 458 | 458 | ||
| @@ -3734,6 +3734,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc | |||
| 3734 | stp->st_stateid.si_stateownerid = sop->so_id; | 3734 | stp->st_stateid.si_stateownerid = sop->so_id; |
| 3735 | stp->st_stateid.si_fileid = fp->fi_id; | 3735 | stp->st_stateid.si_fileid = fp->fi_id; |
| 3736 | stp->st_stateid.si_generation = 0; | 3736 | stp->st_stateid.si_generation = 0; |
| 3737 | stp->st_access_bmap = 0; | ||
| 3737 | stp->st_deny_bmap = open_stp->st_deny_bmap; | 3738 | stp->st_deny_bmap = open_stp->st_deny_bmap; |
| 3738 | stp->st_openstp = open_stp; | 3739 | stp->st_openstp = open_stp; |
| 3739 | 3740 | ||
| @@ -3748,6 +3749,17 @@ check_lock_length(u64 offset, u64 length) | |||
| 3748 | LOFF_OVERFLOW(offset, length))); | 3749 | LOFF_OVERFLOW(offset, length))); |
| 3749 | } | 3750 | } |
| 3750 | 3751 | ||
| 3752 | static void get_lock_access(struct nfs4_stateid *lock_stp, u32 access) | ||
| 3753 | { | ||
| 3754 | struct nfs4_file *fp = lock_stp->st_file; | ||
| 3755 | int oflag = nfs4_access_to_omode(access); | ||
| 3756 | |||
| 3757 | if (test_bit(access, &lock_stp->st_access_bmap)) | ||
| 3758 | return; | ||
| 3759 | nfs4_file_get_access(fp, oflag); | ||
| 3760 | __set_bit(access, &lock_stp->st_access_bmap); | ||
| 3761 | } | ||
| 3762 | |||
| 3751 | /* | 3763 | /* |
| 3752 | * LOCK operation | 3764 | * LOCK operation |
| 3753 | */ | 3765 | */ |
| @@ -3845,18 +3857,16 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 3845 | switch (lock->lk_type) { | 3857 | switch (lock->lk_type) { |
| 3846 | case NFS4_READ_LT: | 3858 | case NFS4_READ_LT: |
| 3847 | case NFS4_READW_LT: | 3859 | case NFS4_READW_LT: |
| 3848 | if (find_readable_file(lock_stp->st_file)) { | 3860 | filp = find_readable_file(lock_stp->st_file); |
| 3849 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ); | 3861 | if (filp) |
| 3850 | filp = find_readable_file(lock_stp->st_file); | 3862 | get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ); |
| 3851 | } | ||
| 3852 | file_lock.fl_type = F_RDLCK; | 3863 | file_lock.fl_type = F_RDLCK; |
| 3853 | break; | 3864 | break; |
| 3854 | case NFS4_WRITE_LT: | 3865 | case NFS4_WRITE_LT: |
| 3855 | case NFS4_WRITEW_LT: | 3866 | case NFS4_WRITEW_LT: |
| 3856 | if (find_writeable_file(lock_stp->st_file)) { | 3867 | filp = find_writeable_file(lock_stp->st_file); |
| 3857 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE); | 3868 | if (filp) |
| 3858 | filp = find_writeable_file(lock_stp->st_file); | 3869 | get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE); |
| 3859 | } | ||
| 3860 | file_lock.fl_type = F_WRLCK; | 3870 | file_lock.fl_type = F_WRLCK; |
| 3861 | break; | 3871 | break; |
| 3862 | default: | 3872 | default: |
