diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4state.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index af360705e551..678f3be88ac0 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/nfsd/xdr4.h> | 50 | #include <linux/nfsd/xdr4.h> |
51 | #include <linux/namei.h> | 51 | #include <linux/namei.h> |
52 | #include <linux/mutex.h> | 52 | #include <linux/mutex.h> |
53 | #include <linux/lockd/bind.h> | ||
53 | 54 | ||
54 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 55 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
55 | 56 | ||
@@ -2657,6 +2658,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2657 | struct file_lock conflock; | 2658 | struct file_lock conflock; |
2658 | __be32 status = 0; | 2659 | __be32 status = 0; |
2659 | unsigned int strhashval; | 2660 | unsigned int strhashval; |
2661 | unsigned int cmd; | ||
2660 | int err; | 2662 | int err; |
2661 | 2663 | ||
2662 | dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", | 2664 | dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", |
@@ -2739,10 +2741,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2739 | case NFS4_READ_LT: | 2741 | case NFS4_READ_LT: |
2740 | case NFS4_READW_LT: | 2742 | case NFS4_READW_LT: |
2741 | file_lock.fl_type = F_RDLCK; | 2743 | file_lock.fl_type = F_RDLCK; |
2744 | cmd = F_SETLK; | ||
2742 | break; | 2745 | break; |
2743 | case NFS4_WRITE_LT: | 2746 | case NFS4_WRITE_LT: |
2744 | case NFS4_WRITEW_LT: | 2747 | case NFS4_WRITEW_LT: |
2745 | file_lock.fl_type = F_WRLCK; | 2748 | file_lock.fl_type = F_WRLCK; |
2749 | cmd = F_SETLK; | ||
2746 | break; | 2750 | break; |
2747 | default: | 2751 | default: |
2748 | status = nfserr_inval; | 2752 | status = nfserr_inval; |
@@ -2769,9 +2773,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2769 | 2773 | ||
2770 | /* XXX?: Just to divert the locks_release_private at the start of | 2774 | /* XXX?: Just to divert the locks_release_private at the start of |
2771 | * locks_copy_lock: */ | 2775 | * locks_copy_lock: */ |
2772 | conflock.fl_ops = NULL; | 2776 | locks_init_lock(&conflock); |
2773 | conflock.fl_lmops = NULL; | 2777 | err = vfs_lock_file(filp, cmd, &file_lock, &conflock); |
2774 | err = posix_lock_file_conf(filp, &file_lock, &conflock); | ||
2775 | switch (-err) { | 2778 | switch (-err) { |
2776 | case 0: /* success! */ | 2779 | case 0: /* success! */ |
2777 | update_stateid(&lock_stp->st_stateid); | 2780 | update_stateid(&lock_stp->st_stateid); |
@@ -2788,7 +2791,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2788 | status = nfserr_deadlock; | 2791 | status = nfserr_deadlock; |
2789 | break; | 2792 | break; |
2790 | default: | 2793 | default: |
2791 | dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",err); | 2794 | dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err); |
2792 | status = nfserr_resource; | 2795 | status = nfserr_resource; |
2793 | break; | 2796 | break; |
2794 | } | 2797 | } |
@@ -2813,7 +2816,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2813 | struct inode *inode; | 2816 | struct inode *inode; |
2814 | struct file file; | 2817 | struct file file; |
2815 | struct file_lock file_lock; | 2818 | struct file_lock file_lock; |
2816 | struct file_lock conflock; | 2819 | int error; |
2817 | __be32 status; | 2820 | __be32 status; |
2818 | 2821 | ||
2819 | if (nfs4_in_grace()) | 2822 | if (nfs4_in_grace()) |
@@ -2869,18 +2872,23 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2869 | 2872 | ||
2870 | nfs4_transform_lock_offset(&file_lock); | 2873 | nfs4_transform_lock_offset(&file_lock); |
2871 | 2874 | ||
2872 | /* posix_test_lock uses the struct file _only_ to resolve the inode. | 2875 | /* vfs_test_lock uses the struct file _only_ to resolve the inode. |
2873 | * since LOCKT doesn't require an OPEN, and therefore a struct | 2876 | * since LOCKT doesn't require an OPEN, and therefore a struct |
2874 | * file may not exist, pass posix_test_lock a struct file with | 2877 | * file may not exist, pass vfs_test_lock a struct file with |
2875 | * only the dentry:inode set. | 2878 | * only the dentry:inode set. |
2876 | */ | 2879 | */ |
2877 | memset(&file, 0, sizeof (struct file)); | 2880 | memset(&file, 0, sizeof (struct file)); |
2878 | file.f_path.dentry = cstate->current_fh.fh_dentry; | 2881 | file.f_path.dentry = cstate->current_fh.fh_dentry; |
2879 | 2882 | ||
2880 | status = nfs_ok; | 2883 | status = nfs_ok; |
2881 | if (posix_test_lock(&file, &file_lock, &conflock)) { | 2884 | error = vfs_test_lock(&file, &file_lock); |
2885 | if (error) { | ||
2886 | status = nfserrno(error); | ||
2887 | goto out; | ||
2888 | } | ||
2889 | if (file_lock.fl_type != F_UNLCK) { | ||
2882 | status = nfserr_denied; | 2890 | status = nfserr_denied; |
2883 | nfs4_set_lock_denied(&conflock, &lockt->lt_denied); | 2891 | nfs4_set_lock_denied(&file_lock, &lockt->lt_denied); |
2884 | } | 2892 | } |
2885 | out: | 2893 | out: |
2886 | nfs4_unlock_state(); | 2894 | nfs4_unlock_state(); |
@@ -2933,9 +2941,9 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2933 | /* | 2941 | /* |
2934 | * Try to unlock the file in the VFS. | 2942 | * Try to unlock the file in the VFS. |
2935 | */ | 2943 | */ |
2936 | err = posix_lock_file(filp, &file_lock); | 2944 | err = vfs_lock_file(filp, F_SETLK, &file_lock, NULL); |
2937 | if (err) { | 2945 | if (err) { |
2938 | dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n"); | 2946 | dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n"); |
2939 | goto out_nfserr; | 2947 | goto out_nfserr; |
2940 | } | 2948 | } |
2941 | /* | 2949 | /* |