diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-op-sm.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index d7694258301..5bfdb0bb43e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -119,13 +119,16 @@ glusterd_txn_opinfo_dict_fini () void glusterd_txn_opinfo_init (glusterd_op_info_t *opinfo, - glusterd_op_sm_state_info_t *state, - glusterd_op_t *op, - dict_t *op_ctx, - rpcsvc_request_t *req) + glusterd_op_sm_state_info_t *state, glusterd_op_t *op, + dict_t *op_ctx, rpcsvc_request_t *req) { + glusterd_conf_t *conf = NULL; + GF_ASSERT (opinfo); + conf = THIS->private; + GF_ASSERT (conf); + if (state) opinfo->state = *state; @@ -140,6 +143,9 @@ glusterd_txn_opinfo_init (glusterd_op_info_t *opinfo, if (req) opinfo->req = req; + opinfo->txn_generation = conf->generation; + cmm_smp_rmb (); + return; } @@ -314,9 +320,6 @@ glusterd_clear_txn_opinfo (uuid_t *txn_id) dict_del(priv->glusterd_txn_opinfo, uuid_utoa (*txn_id)); - if (txn_op_info.local_xaction_peers) - GF_FREE (txn_op_info.local_xaction_peers); - gf_log ("", GF_LOG_DEBUG, "Successfully cleared opinfo for transaction ID : %s", uuid_utoa (*txn_id)); @@ -2919,9 +2922,13 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) priv = this->private; GF_ASSERT (priv); - list_for_each_local_xaction_peers (peerinfo, - opinfo.local_xaction_peers) { - GF_ASSERT (peerinfo); + rcu_read_lock (); + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started + */ + if (peerinfo->generation > opinfo.txn_generation) + continue; if (!peerinfo->connected || !peerinfo->mgmt) continue; @@ -2936,6 +2943,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) if (proc->fn) { ret = proc->fn (NULL, this, peerinfo); if (ret) { + rcu_read_unlock (); gf_log (this->name, GF_LOG_WARNING, "Failed to send lock request " "for operation 'Volume %s' to " @@ -2958,6 +2966,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) ret = dict_set_static_ptr (dict, "peerinfo", peerinfo); if (ret) { + rcu_read_unlock (); gf_log (this->name, GF_LOG_ERROR, "failed to set peerinfo"); dict_unref (dict); @@ -2966,6 +2975,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) ret = proc->fn (NULL, this, dict); if (ret) { + rcu_read_unlock (); gf_log (this->name, GF_LOG_WARNING, "Failed to send mgmt_v3 lock " "request for operation " @@ -2981,6 +2991,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) } } } + rcu_read_unlock (); opinfo.pending_count = pending_count; if (!opinfo.pending_count) @@ -3009,9 +3020,13 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx) priv = this->private; GF_ASSERT (priv); - list_for_each_local_xaction_peers (peerinfo, - opinfo.local_xaction_peers) { - GF_ASSERT (peerinfo); + rcu_read_lock (); + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started + */ + if (peerinfo->generation > opinfo.txn_generation) + continue; if (!peerinfo->connected || !peerinfo->mgmt || !peerinfo->locked) @@ -3083,6 +3098,7 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx) } } } + rcu_read_unlock (); opinfo.pending_count = pending_count; if (!opinfo.pending_count) @@ -3562,9 +3578,13 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) if (op == GD_OP_REPLACE_BRICK) glusterd_rb_use_rsp_dict (NULL, rsp_dict); - list_for_each_local_xaction_peers (peerinfo, - opinfo.local_xaction_peers) { - GF_ASSERT (peerinfo); + rcu_read_lock (); + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started + */ + if (peerinfo->generation > opinfo.txn_generation) + continue; if (!peerinfo->connected || !peerinfo->mgmt) continue; @@ -3577,6 +3597,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) if (proc->fn) { ret = dict_set_static_ptr (dict, "peerinfo", peerinfo); if (ret) { + rcu_read_unlock (); gf_log (this->name, GF_LOG_ERROR, "failed to " "set peerinfo"); goto out; @@ -3593,6 +3614,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) pending_count++; } } + rcu_read_unlock (); opinfo.pending_count = pending_count; out: @@ -4212,9 +4234,13 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx) goto out; } - list_for_each_local_xaction_peers (peerinfo, - opinfo.local_xaction_peers) { - GF_ASSERT (peerinfo); + rcu_read_lock (); + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started + */ + if (peerinfo->generation > opinfo.txn_generation) + continue; if (!peerinfo->connected || !peerinfo->mgmt) continue; @@ -4227,6 +4253,7 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx) if (proc->fn) { ret = dict_set_static_ptr (dict, "peerinfo", peerinfo); if (ret) { + rcu_read_unlock (); gf_log (this->name, GF_LOG_ERROR, "failed to set peerinfo"); goto out; @@ -4242,6 +4269,7 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx) pending_count++; } } + rcu_read_unlock (); opinfo.pending_count = pending_count; gf_log (this->name, GF_LOG_DEBUG, "Sent commit op req for 'Volume %s' " @@ -4528,7 +4556,6 @@ glusterd_op_txn_complete (uuid_t *txn_id) glusterd_op_clear_op (); glusterd_op_reset_ctx (); glusterd_op_clear_errstr (); - gd_cleanup_local_xaction_peers_list (opinfo.local_xaction_peers); /* Based on the op-version, we release the cluster or mgmt_v3 lock */ if (priv->op_version < GD_OP_VERSION_3_6_0) { |