summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-syncop.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-syncop.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c250
1 files changed, 127 insertions, 123 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
index a00438e6d96..c5066b015a3 100644
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
@@ -1067,89 +1067,36 @@ out:
int
-gd_build_peers_list (struct cds_list_head *peers,
- struct cds_list_head *xact_peers, glusterd_op_t op)
+gd_lock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, dict_t *op_ctx,
+ char **op_errstr, uuid_t txn_id,
+ glusterd_op_info_t *txn_opinfo)
{
- glusterd_peerinfo_t *peerinfo = NULL;
- int npeers = 0;
+ int ret = -1;
+ int peer_cnt = 0;
+ uuid_t peer_uuid = {0};
+ xlator_t *this = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ struct syncargs args = {0};
- GF_ASSERT (peers);
- GF_ASSERT (xact_peers);
+ this = THIS;
+ synctask_barrier_init((&args));
+ peer_cnt = 0;
rcu_read_lock ();
- cds_list_for_each_entry_rcu (peerinfo, peers, uuid_list) {
- if (!peerinfo->connected)
+ cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) {
+ /* Only send requests to peers who were available before the
+ * transaction started
+ */
+ if (peerinfo->generation > txn_opinfo->txn_generation)
continue;
- if (op != GD_OP_SYNC_VOLUME &&
- peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
- continue;
-
- cds_list_add_tail (&peerinfo->op_peers_list, xact_peers);
- npeers++;
- }
- rcu_read_unlock ();
-
- return npeers;
-}
-int
-gd_build_local_xaction_peers_list (struct cds_list_head *peers,
- struct cds_list_head *xact_peers,
- glusterd_op_t op)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_local_peers_t *local_peers = NULL;
- int npeers = 0;
-
- GF_ASSERT (peers);
- GF_ASSERT (xact_peers);
-
- rcu_read_lock ();
- cds_list_for_each_entry_rcu (peerinfo, peers, uuid_list) {
if (!peerinfo->connected)
continue;
if (op != GD_OP_SYNC_VOLUME &&
peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
continue;
- local_peers = GF_CALLOC (1, sizeof (*local_peers),
- gf_gld_mt_local_peers_t);
- if (!local_peers) {
- npeers = -1;
- goto unlock;
- }
- CDS_INIT_LIST_HEAD (&local_peers->op_peers_list);
- local_peers->peerinfo = peerinfo;
- cds_list_add_tail (&local_peers->op_peers_list, xact_peers);
- npeers++;
- }
-unlock:
- rcu_read_unlock ();
-
- return npeers;
-}
-int
-gd_lock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, dict_t *op_ctx,
- char **op_errstr, int npeers, uuid_t txn_id,
- struct cds_list_head *peers)
-{
- int ret = -1;
- int peer_cnt = 0;
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- struct syncargs args = {0};
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- this = THIS;
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
if (conf->op_version < GD_OP_VERSION_3_6_0) {
/* Reset lock status */
peerinfo->locked = _gf_false;
@@ -1160,6 +1107,13 @@ gd_lock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, dict_t *op_ctx,
MY_UUID, peer_uuid, txn_id);
peer_cnt++;
}
+ rcu_read_unlock ();
+
+ if (0 == peer_cnt) {
+ ret = 0;
+ goto out;
+ }
+
gd_synctask_barrier_wait((&args), peer_cnt);
if (args.op_ret) {
@@ -1187,15 +1141,15 @@ out:
}
int
-gd_stage_op_phase (struct cds_list_head *peers, glusterd_op_t op,
- dict_t *op_ctx, dict_t *req_dict, char **op_errstr,
- int npeers)
+gd_stage_op_phase (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
+ char **op_errstr, glusterd_op_info_t *txn_opinfo)
{
int ret = -1;
int peer_cnt = 0;
dict_t *rsp_dict = NULL;
char *hostname = NULL;
xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
uuid_t tmp_uuid = {0};
char *errstr = NULL;
@@ -1204,6 +1158,8 @@ gd_stage_op_phase (struct cds_list_head *peers, glusterd_op_t op,
this = THIS;
GF_ASSERT (this);
+ conf = this->private;
+ GF_ASSERT (conf);
rsp_dict = dict_new ();
if (!rsp_dict)
@@ -1252,21 +1208,36 @@ stage_done:
goto out;
}
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
gd_syncargs_init (&args, aggr_dict);
synctask_barrier_init((&args));
peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
+ rcu_read_lock ();
+ cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) {
+ /* Only send requests to peers who were available before the
+ * transaction started
+ */
+ if (peerinfo->generation > txn_opinfo->txn_generation)
+ continue;
+
+ if (!peerinfo->connected)
+ continue;
+ if (op != GD_OP_SYNC_VOLUME &&
+ peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ continue;
+
ret = gd_syncop_mgmt_stage_op (peerinfo, &args,
MY_UUID, tmp_uuid,
op, req_dict, op_ctx);
peer_cnt++;
}
+ rcu_read_unlock ();
+
+ if (0 == peer_cnt) {
+ ret = 0;
+ goto out;
+ }
+
gf_log (this->name, GF_LOG_DEBUG, "Sent stage op req for 'Volume %s' "
"to %d peers", gd_op_list[op], peer_cnt);
@@ -1295,9 +1266,8 @@ out:
}
int
-gd_commit_op_phase (struct cds_list_head *peers, glusterd_op_t op,
- dict_t *op_ctx, dict_t *req_dict, char **op_errstr,
- int npeers)
+gd_commit_op_phase (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
+ char **op_errstr, glusterd_op_info_t *txn_opinfo)
{
dict_t *rsp_dict = NULL;
int peer_cnt = -1;
@@ -1305,12 +1275,17 @@ gd_commit_op_phase (struct cds_list_head *peers, glusterd_op_t op,
char *hostname = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
uuid_t tmp_uuid = {0};
char *errstr = NULL;
struct syncargs args = {0};
int type = GF_QUOTA_OPTION_TYPE_NONE;
this = THIS;
+ GF_ASSERT (this);
+ conf = this->private;
+ GF_ASSERT (conf);
+
rsp_dict = dict_new ();
if (!rsp_dict) {
ret = -1;
@@ -1359,21 +1334,36 @@ commit_done:
goto out;
}
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
gd_syncargs_init (&args, op_ctx);
synctask_barrier_init((&args));
peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
+ rcu_read_lock ();
+ cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) {
+ /* Only send requests to peers who were available before the
+ * transaction started
+ */
+ if (peerinfo->generation > txn_opinfo->txn_generation)
+ continue;
+
+ if (!peerinfo->connected)
+ continue;
+ if (op != GD_OP_SYNC_VOLUME &&
+ peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ continue;
+
ret = gd_syncop_mgmt_commit_op (peerinfo, &args,
MY_UUID, tmp_uuid,
op, req_dict, op_ctx);
peer_cnt++;
}
+ rcu_read_unlock ();
+
+ if (0 == peer_cnt) {
+ ret = 0;
+ goto out;
+ }
+
gd_synctask_barrier_wait((&args), peer_cnt);
ret = args.op_ret;
if (args.errstr)
@@ -1399,8 +1389,8 @@ out:
int
gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret,
rpcsvc_request_t *req, dict_t *op_ctx, char *op_errstr,
- int npeers, char *volname, gf_boolean_t is_acquired,
- uuid_t txn_id, struct cds_list_head *peers)
+ char *volname, gf_boolean_t is_acquired, uuid_t txn_id,
+ glusterd_op_info_t *txn_opinfo)
{
glusterd_peerinfo_t *peerinfo = NULL;
uuid_t tmp_uuid = {0};
@@ -1412,11 +1402,6 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret,
this = THIS;
GF_ASSERT (this);
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
/* If the lock has not been held during this
* transaction, do not send unlock requests */
if (!is_acquired) {
@@ -1428,7 +1413,21 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret,
peer_cnt = 0;
if (conf->op_version < GD_OP_VERSION_3_6_0) {
- list_for_each_local_xaction_peers (peerinfo, peers) {
+ rcu_read_lock ();
+ cds_list_for_each_entry_rcu (peerinfo, &conf->peers,
+ uuid_list) {
+ /* Only send requests to peers who were available before
+ * the transaction started
+ */
+ if (peerinfo->generation > txn_opinfo->txn_generation)
+ continue;
+
+ if (!peerinfo->connected)
+ continue;
+ if (op != GD_OP_SYNC_VOLUME &&
+ peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ continue;
+
/* Only unlock peers that were locked */
if (peerinfo->locked) {
gd_syncop_mgmt_unlock (peerinfo, &args,
@@ -1436,16 +1435,39 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret,
peer_cnt++;
}
}
+ rcu_read_unlock ();
} else {
if (volname) {
- list_for_each_local_xaction_peers (peerinfo, peers) {
+ rcu_read_lock ();
+ cds_list_for_each_entry_rcu (peerinfo, &conf->peers,
+ uuid_list) {
+ /* Only send requests to peers who were
+ * available before the transaction started
+ */
+ if (peerinfo->generation >
+ txn_opinfo->txn_generation)
+ continue;
+
+ if (!peerinfo->connected)
+ continue;
+ if (op != GD_OP_SYNC_VOLUME &&
+ peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ continue;
+
gd_syncop_mgmt_v3_unlock (op_ctx, peerinfo,
&args, MY_UUID,
tmp_uuid, txn_id);
peer_cnt++;
}
+ rcu_read_unlock ();
}
}
+
+ if (0 == peer_cnt) {
+ ret = 0;
+ goto out;
+ }
+
gd_synctask_barrier_wait((&args), peer_cnt);
ret = args.op_ret;
@@ -1585,7 +1607,6 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
{
int ret = -1;
int op_ret = -1;
- int npeers = 0;
dict_t *req_dict = NULL;
glusterd_conf_t *conf = NULL;
glusterd_op_t op = 0;
@@ -1596,7 +1617,6 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
xlator_t *this = NULL;
gf_boolean_t is_acquired = _gf_false;
uuid_t *txn_id = NULL;
- struct cds_list_head xaction_peers = {0,};
glusterd_op_info_t txn_opinfo = {{0},};
this = THIS;
@@ -1604,8 +1624,6 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
conf = this->private;
GF_ASSERT (conf);
- CDS_INIT_LIST_HEAD (&xaction_peers);
-
ret = dict_get_int32 (op_ctx, GD_SYNC_OPCODE_KEY, &tmp_op);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to get volume "
@@ -1686,20 +1704,11 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
local_locking_done:
- /* Maintain xaction_peers on per transaction basis */
- npeers = gd_build_local_xaction_peers_list (&conf->peers,
- &xaction_peers, op);
- if (npeers == -1) {
- gf_log (this->name, GF_LOG_ERROR, "building local peers list "
- "failed");
- goto out;
- }
-
/* If no volname is given as a part of the command, locks will
* not be held */
if (volname || (conf->op_version < GD_OP_VERSION_3_6_0)) {
- ret = gd_lock_op_phase (conf, op, op_ctx, &op_errstr,
- npeers, *txn_id, &xaction_peers);
+ ret = gd_lock_op_phase (conf, op, op_ctx, &op_errstr, *txn_id,
+ &txn_opinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Locking Peers Failed.");
@@ -1716,8 +1725,7 @@ local_locking_done:
goto out;
}
- ret = gd_stage_op_phase (&xaction_peers, op, op_ctx, req_dict,
- &op_errstr, npeers);
+ ret = gd_stage_op_phase (op, op_ctx, req_dict, &op_errstr, &txn_opinfo);
if (ret)
goto out;
@@ -1725,8 +1733,8 @@ local_locking_done:
if (ret)
goto out;
- ret = gd_commit_op_phase (&xaction_peers, op, op_ctx, req_dict,
- &op_errstr, npeers);
+ ret = gd_commit_op_phase (op, op_ctx, req_dict, &op_errstr,
+ &txn_opinfo);
if (ret)
goto out;
@@ -1734,11 +1742,9 @@ local_locking_done:
out:
op_ret = ret;
if (txn_id) {
- (void) gd_unlock_op_phase (conf, op, &op_ret, req,
- op_ctx, op_errstr,
- npeers, volname,
- is_acquired, *txn_id,
- &xaction_peers);
+ (void) gd_unlock_op_phase (conf, op, &op_ret, req, op_ctx,
+ op_errstr, volname, is_acquired,
+ *txn_id, &txn_opinfo);
/* Clearing the transaction opinfo */
ret = glusterd_clear_txn_opinfo (txn_id);
@@ -1751,8 +1757,6 @@ out:
glusterd_op_send_cli_response (op, op_ret, 0, req, op_ctx, op_errstr);
- gd_cleanup_local_xaction_peers_list (&xaction_peers);
-
if (volname)
GF_FREE (volname);