From 81051ddce1ab12758ae3367bc2bef2ceba29b6ae Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Thu, 2 Dec 2010 10:41:21 -0500 Subject: [PATCH] recovery: revoke all layouts and device info on client recovery 12.7.4. Recovery from Metadata Server Restart "The client MUST stop using layouts and delete the device ID to device address mappings it previously received from the metadata server." during client state recovery, call pnfs_file_layout_recall() to revoke all layouts and devices held by the client LAYOUTGET, LAYOUTRETURN, and GETDEVICEINFO are all sent under their respective locks, and pnfs_file_layout_recall() requires a lock on each layout and device it operates on, so this would cause a deadlock if one of those operations triggered the recovery. to avoid this, LAYOUTGET, LAYOUTRETURN, and GETDEVICEINFO are all sent with try_recovery=FALSE. this behavior is preferable for recovery, because errors in the pnfs path cause us to fall back to the metadata server Signed-off-by: Casey Bodley --- daemon/nfs41_compound.c | 7 +++++++ daemon/nfs41_ops.c | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/daemon/nfs41_compound.c b/daemon/nfs41_compound.c index ef9b9cb..6ddacf8 100644 --- a/daemon/nfs41_compound.c +++ b/daemon/nfs41_compound.c @@ -27,6 +27,7 @@ #include "nfs41_compound.h" #include "nfs41_xdr.h" #include "nfs41_ops.h" +#include "nfs41_callback.h" #include "name_cache.h" #include "daemon_debug.h" @@ -153,6 +154,7 @@ static int recover_open( AcquireSRWLockExclusive(&open->lock); + open->layout = NULL; stateid.type = STATEID_OPEN; stateid.open = open; @@ -187,6 +189,8 @@ static int recover_client_state( IN nfs41_session *session, IN nfs41_client *client) { + const struct cb_layoutrecall_args recall = { PNFS_LAYOUTTYPE_FILE, + PNFS_IOMODE_ANY, TRUE, { PNFS_RETURN_ALL } }; struct client_state *state = &session->client->state; struct list_entry *entry; nfs41_open_state *open; @@ -202,6 +206,9 @@ static int recover_client_state( } LeaveCriticalSection(&state->lock); + /* revoke all of the client's layouts */ + pnfs_file_layout_recall(client, &recall); + if (status != NFS4ERR_BADSESSION) { /* send reclaim_complete, but don't fail on errors */ status = nfs41_reclaim_complete(session); diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c index 50919cd..9d60001 100644 --- a/daemon/nfs41_ops.c +++ b/daemon/nfs41_ops.c @@ -1668,7 +1668,7 @@ enum nfsstat4 pnfs_rpc_layoutget( layoutget_args.maxcount = session->fore_chan_attrs.ca_maxresponsesize - READ_OVERHEAD; layoutget_res.u.res_ok.layout = layout; - status = compound_encode_send_decode(session, &compound, TRUE); + status = compound_encode_send_decode(session, &compound, FALSE); if (status) goto out; @@ -1783,7 +1783,7 @@ enum nfsstat4 pnfs_rpc_layoutreturn( layoutreturn_args.length = layout->layout.length; layoutreturn_args.stateid = &layout->layout.state; - status = compound_encode_send_decode(session, &compound, TRUE); + status = compound_encode_send_decode(session, &compound, FALSE); if (status) goto out; @@ -1831,7 +1831,7 @@ enum nfsstat4 pnfs_rpc_getdeviceinfo( getdeviceinfo_args.notify_types.count = 0; getdeviceinfo_res.u.res_ok.device = device; - status = compound_encode_send_decode(session, &compound, TRUE); + status = compound_encode_send_decode(session, &compound, FALSE); if (status) goto out;