aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2013-10-17 14:13:47 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-10-28 15:30:46 -0400
commit60ea68129942dc36cd1a3a9bdaec783369ee5a6d (patch)
treeb1eb0c698e34126f85d95ed3ffe17c334d72f455 /fs/nfs
parent8ef2f8d46aca7ff2e7e2b926bb563212aa63a4af (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.c16
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
5805static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata) 5806static 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
5812static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata) 5814static 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
5818static void nfs4_release_lockowner_release(void *calldata) 5834static void nfs4_release_lockowner_release(void *calldata)