aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-11-04 15:39:36 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-11-04 15:39:36 -0500
commit6bfc93ef98f00b38f1913a7fdeae46ae8dbd7c52 (patch)
tree2eb5f2fa26376b3d6ae5eebd65e93d4eec9555bd /fs
parent888e694c167975709f17526dbbed2d98f84e8f85 (diff)
NFSv4: Teach NFSv4 to cache locks when we hold a delegation
Now that we have a method of dealing with delegation recalls, actually enable the caching of posix and BSD locks. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-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}