static int gateway_forward_request(struct request *req, bool all_node) { int i, err_ret = SD_RES_SUCCESS, ret, local = -1; unsigned wlen; uint64_t oid = req->rq.obj.oid; int nr_to_send; struct write_info wi; struct sd_op_template *op; struct sd_req hdr; struct sd_node *target_nodes[SD_MAX_COPIES]; dprintf("%"PRIx64"\n", oid); gateway_init_fwd_hdr(&hdr, &req->rq); op = get_sd_op(hdr.opcode); write_info_init(&wi); wlen = hdr.data_length; nr_to_send = init_target_nodes(req, all_node, oid, target_nodes); for (i = 0; i < nr_to_send; i++) { struct sockfd *sfd; struct node_id *nid; if (node_is_local(target_nodes[i])) { local = i; continue; } nid = &target_nodes[i]->nid; sfd = sheep_get_sockfd(nid); if (!sfd) { err_ret = SD_RES_NETWORK_ERROR; break; } ret = send_req(sfd->fd, &hdr, req->data, &wlen); if (ret) { sheep_del_sockfd(nid, sfd); err_ret = SD_RES_NETWORK_ERROR; dprintf("fail %d\n", ret); break; } write_info_advance(&wi, nid, sfd); } if (local != -1 && err_ret == SD_RES_SUCCESS) { assert(op); ret = sheep_do_op_work(op, req); if (ret != SD_RES_SUCCESS) { eprintf("fail to write local %"PRIx32"\n", ret); err_ret = ret; } } dprintf("nr_sent %d, err %x\n", wi.nr_sent, err_ret); if (wi.nr_sent > 0) { ret = wait_forward_request(&wi, req); if (ret != SD_RES_SUCCESS) err_ret = ret; } return err_ret; }
static int gateway_forward_request(struct request *req) { int i, err_ret = SD_RES_SUCCESS, ret, local = -1; unsigned wlen; uint64_t oid = req->rq.obj.oid; int nr_to_send; struct write_info wi; const struct sd_op_template *op; struct sd_req hdr; const struct sd_node *target_nodes[SD_MAX_NODES]; sd_debug("%"PRIx64, oid); gateway_init_fwd_hdr(&hdr, &req->rq); op = get_sd_op(hdr.opcode); wlen = hdr.data_length; nr_to_send = init_target_nodes(req, oid, target_nodes); write_info_init(&wi, nr_to_send); if (nr_to_send == 0) { sd_debug("there is no living nodes"); return SD_RES_HALT; } for (i = 0; i < nr_to_send; i++) { struct sockfd *sfd; const struct node_id *nid; if (node_is_local(target_nodes[i])) { local = i; continue; } nid = &target_nodes[i]->nid; sfd = sockfd_cache_get(nid); if (!sfd) { err_ret = SD_RES_NETWORK_ERROR; break; } ret = send_req(sfd->fd, &hdr, req->data, wlen, sheep_need_retry, req->rq.epoch, MAX_RETRY_COUNT); if (ret) { sockfd_cache_del_node(nid); err_ret = SD_RES_NETWORK_ERROR; sd_debug("fail %d", ret); break; } write_info_advance(&wi, nid, sfd); } if (local != -1 && err_ret == SD_RES_SUCCESS) { assert(op); ret = sheep_do_op_work(op, req); if (ret != SD_RES_SUCCESS) { sd_err("fail to write local %"PRIx64", %s", oid, sd_strerror(ret)); err_ret = ret; } } sd_debug("nr_sent %d, err %x", wi.nr_sent, err_ret); if (wi.nr_sent > 0) { ret = wait_forward_request(&wi, req); if (ret != SD_RES_SUCCESS) err_ret = ret; } return err_ret; }