summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-op-sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-op-sm.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c67
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) {