diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-01-26 15:42:21 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-01-26 15:42:21 -0500 |
| commit | 2bee72a6aa1e6d0a4f5da56217f0d0bbbdd0d9a3 (patch) | |
| tree | 62a943e0bfb1cff52ac9e54ef5d8a5cea3fbfa35 | |
| parent | b0706ca415b188ed58788420de4d5c9972b2afb2 (diff) | |
NFSv4: Ensure that the NFSv4 locking can recover from stateid errors
In most cases, we just want to mark the lock_stateid sequence id as being
uninitialised.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
| -rw-r--r-- | fs/nfs/nfs4proc.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 198d51d17c13..0b68238ed0c8 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -4088,6 +4088,22 @@ static const struct rpc_call_ops nfs4_recover_lock_ops = { | |||
| 4088 | .rpc_release = nfs4_lock_release, | 4088 | .rpc_release = nfs4_lock_release, |
| 4089 | }; | 4089 | }; |
| 4090 | 4090 | ||
| 4091 | static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error) | ||
| 4092 | { | ||
| 4093 | struct nfs_client *clp = server->nfs_client; | ||
| 4094 | struct nfs4_state *state = lsp->ls_state; | ||
| 4095 | |||
| 4096 | switch (error) { | ||
| 4097 | case -NFS4ERR_ADMIN_REVOKED: | ||
| 4098 | case -NFS4ERR_BAD_STATEID: | ||
| 4099 | case -NFS4ERR_EXPIRED: | ||
| 4100 | if (new_lock_owner != 0 || | ||
| 4101 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) | ||
| 4102 | nfs4_state_mark_reclaim_nograce(clp, state); | ||
| 4103 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; | ||
| 4104 | }; | ||
| 4105 | } | ||
| 4106 | |||
| 4091 | static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type) | 4107 | static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type) |
| 4092 | { | 4108 | { |
| 4093 | struct nfs4_lockdata *data; | 4109 | struct nfs4_lockdata *data; |
| @@ -4126,6 +4142,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f | |||
| 4126 | ret = nfs4_wait_for_completion_rpc_task(task); | 4142 | ret = nfs4_wait_for_completion_rpc_task(task); |
| 4127 | if (ret == 0) { | 4143 | if (ret == 0) { |
| 4128 | ret = data->rpc_status; | 4144 | ret = data->rpc_status; |
| 4145 | if (ret) | ||
| 4146 | nfs4_handle_setlk_error(data->server, data->lsp, | ||
| 4147 | data->arg.new_lock_owner, ret); | ||
| 4129 | } else | 4148 | } else |
| 4130 | data->cancelled = 1; | 4149 | data->cancelled = 1; |
| 4131 | rpc_put_task(task); | 4150 | rpc_put_task(task); |
