diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2013-10-17 14:13:47 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-10-28 15:30:46 -0400 |
commit | 60ea68129942dc36cd1a3a9bdaec783369ee5a6d (patch) | |
tree | b1eb0c698e34126f85d95ed3ffe17c334d72f455 /fs/nfs | |
parent | 8ef2f8d46aca7ff2e7e2b926bb563212aa63a4af (diff) |
NFS: Migration support for RELEASE_LOCKOWNER
Currently the Linux NFS client ignores the operation status code for
the RELEASE_LOCKOWNER operation. Like NFSv3's UMNT operation,
RELEASE_LOCKOWNER is a courtesy to help servers manage their
resources, and the outcome is not consequential for the client.
During a migration, a server may report NFS4ERR_LEASE_MOVED, in
which case the client really should retry, since typically
LEASE_MOVED has nothing to do with the current operation, but does
prevent it from going forward.
Also, it's important for a client to respond as soon as possible to
a moved lease condition, since the client's lease could expire on
the destination without further action by the client.
NFS4ERR_DELAY is not included in the list of valid status codes for
RELEASE_LOCKOWNER in RFC 3530bis. However, rfc3530-migration-update
does permit migration-capable servers to return DELAY to clients,
but only in the context of an ongoing migration. In this case the
server has frozen lock state in preparation for migration, and a
client retry would help the destination server purge unneeded state
once migration recovery is complete.
Interestly, NFS4ERR_MOVED is not valid for RELEASE_LOCKOWNER, even
though lock owners can be migrated with Transparent State Migration.
Note that RFC 3530bis section 9.5 includes RELEASE_LOCKOWNER in the
list of operations that renew a client's lease on the server if they
succeed. Now that our client pays attention to the operation's
status code, we can note that renewal appropriately.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2564e1c89f56..9f2ccf7471ee 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -5800,6 +5800,7 @@ struct nfs_release_lockowner_data { | |||
5800 | struct nfs_release_lockowner_args args; | 5800 | struct nfs_release_lockowner_args args; |
5801 | struct nfs4_sequence_args seq_args; | 5801 | struct nfs4_sequence_args seq_args; |
5802 | struct nfs4_sequence_res seq_res; | 5802 | struct nfs4_sequence_res seq_res; |
5803 | unsigned long timestamp; | ||
5803 | }; | 5804 | }; |
5804 | 5805 | ||
5805 | static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata) | 5806 | static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata) |
@@ -5807,12 +5808,27 @@ static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata | |||
5807 | struct nfs_release_lockowner_data *data = calldata; | 5808 | struct nfs_release_lockowner_data *data = calldata; |
5808 | nfs40_setup_sequence(data->server, | 5809 | nfs40_setup_sequence(data->server, |
5809 | &data->seq_args, &data->seq_res, task); | 5810 | &data->seq_args, &data->seq_res, task); |
5811 | data->timestamp = jiffies; | ||
5810 | } | 5812 | } |
5811 | 5813 | ||
5812 | static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata) | 5814 | static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata) |
5813 | { | 5815 | { |
5814 | struct nfs_release_lockowner_data *data = calldata; | 5816 | struct nfs_release_lockowner_data *data = calldata; |
5817 | struct nfs_server *server = data->server; | ||
5818 | |||
5815 | nfs40_sequence_done(task, &data->seq_res); | 5819 | nfs40_sequence_done(task, &data->seq_res); |
5820 | |||
5821 | switch (task->tk_status) { | ||
5822 | case 0: | ||
5823 | renew_lease(server, data->timestamp); | ||
5824 | break; | ||
5825 | case -NFS4ERR_STALE_CLIENTID: | ||
5826 | case -NFS4ERR_EXPIRED: | ||
5827 | case -NFS4ERR_LEASE_MOVED: | ||
5828 | case -NFS4ERR_DELAY: | ||
5829 | if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) | ||
5830 | rpc_restart_call_prepare(task); | ||
5831 | } | ||
5816 | } | 5832 | } |
5817 | 5833 | ||
5818 | static void nfs4_release_lockowner_release(void *calldata) | 5834 | static void nfs4_release_lockowner_release(void *calldata) |