diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-11-04 15:39:36 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-11-04 15:39:36 -0500 |
| commit | 6bfc93ef98f00b38f1913a7fdeae46ae8dbd7c52 (patch) | |
| tree | 2eb5f2fa26376b3d6ae5eebd65e93d4eec9555bd | |
| parent | 888e694c167975709f17526dbbed2d98f84e8f85 (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>
| -rw-r--r-- | fs/nfs/nfs4proc.c | 36 |
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__); | ||
| 3093 | out: | ||
| 3074 | up_read(&clp->cl_sem); | 3094 | up_read(&clp->cl_sem); |
| 3075 | return status; | 3095 | return status; |
| 3076 | } | 3096 | } |
