diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-syncop.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-syncop.c | 250 |
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); |