aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e6a9322a321f..21482b2518f6 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2918,6 +2918,10 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
2918 struct nfs4_lock_state *lsp; 2918 struct nfs4_lock_state *lsp;
2919 int status; 2919 int status;
2920 2920
2921 /* Is this a delegated lock? */
2922 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
2923 return do_vfs_lock(request->fl_file, request);
2924
2921 status = nfs4_set_lock_state(state, request); 2925 status = nfs4_set_lock_state(state, request);
2922 if (status != 0) 2926 if (status != 0)
2923 return status; 2927 return status;
@@ -3032,6 +3036,9 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
3032 struct nfs4_exception exception = { }; 3036 struct nfs4_exception exception = { };
3033 int err; 3037 int err;
3034 3038
3039 /* Cache the lock if possible... */
3040 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3041 return 0;
3035 do { 3042 do {
3036 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 3043 err = _nfs4_do_setlk(state, F_SETLK, request, 1);
3037 if (err != -NFS4ERR_DELAY) 3044 if (err != -NFS4ERR_DELAY)
@@ -3047,6 +3054,9 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
3047 struct nfs4_exception exception = { }; 3054 struct nfs4_exception exception = { };
3048 int err; 3055 int err;
3049 3056
3057 err = nfs4_set_lock_state(state, request);
3058 if (err != 0)
3059 return err;
3050 do { 3060 do {
3051 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 3061 err = _nfs4_do_setlk(state, F_SETLK, request, 0);
3052 if (err != -NFS4ERR_DELAY) 3062 if (err != -NFS4ERR_DELAY)
@@ -3062,15 +3072,25 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
3062 int status; 3072 int status;
3063 3073
3064 down_read(&clp->cl_sem); 3074 down_read(&clp->cl_sem);
3065 status = nfs4_set_lock_state(state, request); 3075 /* Is this a delegated open? */
3066 if (status == 0) 3076 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3067 status = _nfs4_do_setlk(state, cmd, request, 0); 3077 /* Yes: cache locks! */
3068 if (status == 0) { 3078 status = do_vfs_lock(request->fl_file, request);
3069 /* Note: we always want to sleep here! */ 3079 /* ...but avoid races with delegation recall... */
3070 request->fl_flags |= FL_SLEEP; 3080 if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
3071 if (do_vfs_lock(request->fl_file, request) < 0) 3081 goto out;
3072 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
3073 } 3082 }
3083 status = nfs4_set_lock_state(state, request);
3084 if (status != 0)
3085 goto out;
3086 status = _nfs4_do_setlk(state, cmd, request, 0);
3087 if (status != 0)
3088 goto out;
3089 /* Note: we always want to sleep here! */
3090 request->fl_flags |= FL_SLEEP;
3091 if (do_vfs_lock(request->fl_file, request) < 0)
3092 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
3093out:
3074 up_read(&clp->cl_sem); 3094 up_read(&clp->cl_sem);
3075 return status; 3095 return status;
3076} 3096}