From 7c8f58b9923fa1a165e363253ae0369cda2f8ee1 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Thu, 18 Nov 2010 11:23:49 -0500 Subject: [PATCH] recovery: avoid recursive state recovery avoid the recursive case where state recovery operations (OPEN for reclaim and RECLAIM_COMPLETE) return BADSESSION, which kicks off another round of recovery added a 'bool_t try_recovery' argument to compound_encode_send_decode() in place of its unused 'bufsize_in' and 'bufsize_out'. when try_recovery=FALSE, return BADSESSION/STALE_CLIENTID errors instead of attempting recovery. nfs41_open_reclaim(), nfs41_reclaim_complete(), and nfs41_destroy_session() now pass try_recovery=FALSE during state recovery, we can now check the return values of nfs41_open_reclaim() and nfs41_reclaim_complete() for BADSESSION, and use a goto to restart session recovery Signed-off-by: Casey Bodley --- daemon/lookup.c | 2 +- daemon/name_cache.c | 2 +- daemon/nfs41_compound.c | 29 ++++++++++----------- daemon/nfs41_compound.h | 3 +-- daemon/nfs41_ops.c | 56 +++++++++++++++++++++-------------------- 5 files changed, 45 insertions(+), 47 deletions(-) diff --git a/daemon/lookup.c b/daemon/lookup.c index 1bcbb55..a650754 100644 --- a/daemon/lookup.c +++ b/daemon/lookup.c @@ -160,7 +160,7 @@ static int lookup_rpc( } buffer_size = MAX_RPC_RES_SIZE(component_count); - status = compound_encode_send_decode(session, &compound, 0, buffer_size); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; diff --git a/daemon/name_cache.c b/daemon/name_cache.c index dd9412d..085337e 100644 --- a/daemon/name_cache.c +++ b/daemon/name_cache.c @@ -1099,7 +1099,7 @@ static int rpc_array_putfh( putfh_args[i].in_recovery = 1; } - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; status = sequence_res.sr_status; diff --git a/daemon/nfs41_compound.c b/daemon/nfs41_compound.c index 0f09540..2463bce 100644 --- a/daemon/nfs41_compound.c +++ b/daemon/nfs41_compound.c @@ -126,8 +126,7 @@ static void recovery_finish( int compound_encode_send_decode( nfs41_session *session, nfs41_compound *compound, - uint32_t bufsize_in, - uint32_t bufsize_out) + bool_t try_recovery) { int status, retry_count = 0, delayby = 0; nfs41_sequence_args *args = @@ -182,17 +181,14 @@ retry: if (compound->res.status != NFS4_OK) dprintf(1, "\n################ %s ################\n\n", nfs_error_string(compound->res.status)); - if (compound->res.status != NFS4_OK && - compound->args.argarray[0].op == OP_DESTROY_SESSION) { - dprintf(1, "OP_DESTROY_SESSION ignoring errors\n"); - compound->res.status = NFS4_OK; - } switch (compound->res.status) { case NFS4_OK: break; case NFS4ERR_STALE_CLIENTID: + if (!try_recovery) + goto out; if (!recovery_start_or_wait(session->client)) goto do_retry; //try to create a new client @@ -207,9 +203,12 @@ retry: //fallthru and reestablish the session case NFS4ERR_BADSESSION: if (compound->res.status == NFS4ERR_BADSESSION) { + if (!try_recovery) + goto out; if (!recovery_start_or_wait(session->client)) goto do_retry; } +restart_recovery: //try to create a new session status = nfs41_session_renew(session); if (status == NFS4ERR_STALE_CLIENTID) { @@ -221,15 +220,8 @@ retry: recovery_finish(session->client); goto out; } - status = nfs41_session_renew(session); - if (status) { - eprintf("after reestablishing clientid: nfs41_session_renew() " - "failed with %d\n", status); - status = ERROR_BAD_NET_RESP; - recovery_finish(session->client); - goto out; - } - } else if (status && status != NFS4ERR_STALE_CLIENTID) { + goto restart_recovery; + } else if (status) { eprintf("nfs41_session_renew: failed with %d\n", status); recovery_finish(session->client); goto out; @@ -252,6 +244,9 @@ retry: AcquireSRWLockExclusive(&open->lock); memcpy(&open->stateid, &stateid, sizeof(stateid4)); ReleaseSRWLockExclusive(&open->lock); + } else if (status == NFS4ERR_BADSESSION) { + LeaveCriticalSection(&state->lock); + goto restart_recovery; } } LeaveCriticalSection(&state->lock); @@ -261,6 +256,8 @@ retry: if (status && status == NFS4ERR_NOTSUPP) eprintf("nfs41_reclaim_complete() failed with %s\n", nfs_error_string(status)); + if (status == NFS4ERR_BADSESSION) + goto restart_recovery; } recovery_finish(session->client); goto do_retry; diff --git a/daemon/nfs41_compound.h b/daemon/nfs41_compound.h index 6460a59..d87c79c 100644 --- a/daemon/nfs41_compound.h +++ b/daemon/nfs41_compound.h @@ -77,7 +77,6 @@ void compound_add_op( int compound_encode_send_decode( nfs41_session *session, nfs41_compound *compound, - uint32_t bufsize_in, - uint32_t bufsize_out); + bool_t try_recovery); #endif /* __NFS41_DAEMON_COMPOUND_H__ */ diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c index 8baa1f0..9a522e3 100644 --- a/daemon/nfs41_ops.c +++ b/daemon/nfs41_ops.c @@ -246,7 +246,8 @@ int nfs41_destroy_session( compound_add_op(&compound, OP_DESTROY_SESSION, &ds_args, &ds_res); ds_args.dsa_sessionid = session->session_id; - status = compound_encode_send_decode(session, &compound, 0, 0); + /* don't attempt to recover from BADSESSION/STALE_CLIENTID */ + status = compound_encode_send_decode(session, &compound, FALSE); if (status) goto out; @@ -278,7 +279,8 @@ enum nfsstat4 nfs41_reclaim_complete( compound_add_op(&compound, OP_RECLAIM_COMPLETE, NULL, &reclaim_res); - status = compound_encode_send_decode(session, &compound, 0, 0); + /* don't attempt to recover from BADSESSION */ + status = compound_encode_send_decode(session, &compound, FALSE); if (status) goto out; @@ -365,7 +367,7 @@ int nfs41_open( pgetattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; pgetattr_res.info = &dir_info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -468,7 +470,8 @@ int nfs41_open_reclaim( pgetattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; pgetattr_res.info = &dir_info; - status = compound_encode_send_decode(session, &compound, 0, 0); + /* don't attempt to recover from BADSESSION errors */ + status = compound_encode_send_decode(session, &compound, FALSE); if (status) goto out; @@ -559,7 +562,7 @@ int nfs41_create( pgetattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; pgetattr_res.info = &dir_info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -629,7 +632,7 @@ int nfs41_close( getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; getattr_res.info = &info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -702,7 +705,7 @@ int nfs41_write( getattr_res.info = &info; } - status = compound_encode_send_decode(session, &compound, data_len, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -769,7 +772,7 @@ int nfs41_read( read_res.resok4.data_len = count; read_res.resok4.data = data_out; - status = compound_encode_send_decode(session, &compound, 0, count); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -838,7 +841,7 @@ int nfs41_commit( getattr_res.info = &info; } - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -906,7 +909,7 @@ int nfs41_lock( lock_res.u.resok4.lock_stateid = &stateid->stateid; lock_res.u.denied.owner.owner_len = NFS4_OPAQUE_LIMIT; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -952,7 +955,7 @@ int nfs41_unlock( locku_args.lock_stateid = stateid; locku_res.lock_stateid = &stateid->stateid; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1002,8 +1005,7 @@ int nfs41_readdir( readdir_res.reply.entries = entries; ZeroMemory(entries, readdir_args.dircount); - status = compound_encode_send_decode(session, &compound, - 0, readdir_args.maxcount); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1065,7 +1067,7 @@ int nfs41_getattr( getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; getattr_res.info = info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1124,7 +1126,7 @@ int nfs41_remove( getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; getattr_res.info = &info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1206,7 +1208,7 @@ int nfs41_rename( src_getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; src_getattr_res.info = &src_info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1284,7 +1286,7 @@ int nfs41_setattr( setattr_args.stateid = stateid; setattr_args.info = info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1375,7 +1377,7 @@ int nfs41_link( compound_add_op(&compound, OP_GETFH, NULL, &getfh_res); getfh_res.fh = &link_out->fh; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1439,7 +1441,7 @@ int nfs41_readlink( readlink_res.link_len = max_len - 1; readlink_res.link = link_out; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1484,7 +1486,7 @@ int nfs41_access( compound_add_op(&compound, OP_ACCESS, &access_args, &access_res); access_args.access = requested; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1516,7 +1518,7 @@ int nfs41_send_sequence( if (status) goto out; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1556,7 +1558,7 @@ int nfs41_delegreturn( compound_add_op(&compound, OP_DELEGRETURN, &dr_args, &dr_res); dr_args.stateid = stateid; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1606,7 +1608,7 @@ enum nfsstat4 nfs41_fs_locations( getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; getattr_res.info = &info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1657,7 +1659,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, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1720,7 +1722,7 @@ enum nfsstat4 pnfs_rpc_layoutcommit( getattr_res.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT; getattr_res.info = &info; - status = compound_encode_send_decode(session, &compound, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1772,7 +1774,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, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out; @@ -1820,7 +1822,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, 0, 0); + status = compound_encode_send_decode(session, &compound, TRUE); if (status) goto out;