int dnet_trans_alloc_send(struct dnet_session *s, struct dnet_trans_control *ctl) { struct dnet_node *n = s->node; struct dnet_net_state *st; struct dnet_addr *addr = NULL; int err; if (dnet_session_get_cflags(s) & DNET_FLAGS_DIRECT) { st = dnet_state_search_by_addr(n, &s->direct_addr); addr = &s->direct_addr; } else if(dnet_session_get_cflags(s) & DNET_FLAGS_FORWARD) { st = dnet_state_search_by_addr(n, &s->forward_addr); addr = &s->forward_addr; }else { st = dnet_state_get_first(n, &ctl->id); } if (!st) { dnet_log(n, DNET_LOG_ERROR, "%s: direct: %d, direct-addr: %s, forward: %d: trans_send: could not find network state for address", dnet_dump_id(&ctl->id), !!(dnet_session_get_cflags(s) & DNET_FLAGS_DIRECT), dnet_addr_string(&s->direct_addr), !!(dnet_session_get_cflags(s) & DNET_FLAGS_FORWARD)); err = dnet_trans_send_fail(s, addr, ctl, -ENXIO, 1); } else { err = dnet_trans_alloc_send_state(s, st, ctl); dnet_state_put(st); } return err; }
int dnet_request_bulk_check(struct dnet_node *n, struct dnet_bulk_state *state, struct dnet_check_params *params) { struct dnet_trans_control ctl; struct dnet_net_state *st; struct dnet_bulk_check_priv *p; struct timespec wait_ts; int err; p = (struct dnet_bulk_check_priv *)malloc(sizeof(struct dnet_bulk_check_priv)); if (!p) { err = -ENOMEM; goto err_out_exit; } atomic_init(&p->refcnt, 2); p->db = params->db; dnet_check_temp_db_get(p->db); p->w = dnet_wait_alloc(0); if (!p->w) { err = -ENOMEM; goto err_out_free; } p->group_num = params->group_num; p->groups = (int *)malloc(sizeof(int) * params->group_num); if (!p->groups) { err = -ENOMEM; goto err_out_put; } memcpy(p->groups, params->groups, sizeof(int) * params->group_num); memset(&ctl, 0, sizeof(struct dnet_trans_control)); ctl.cmd = DNET_CMD_LIST; ctl.complete = dnet_bulk_check_complete; ctl.priv = p; ctl.cflags = DNET_FLAGS_NEED_ACK | DNET_FLAGS_NOLOCK | DNET_ATTR_BULK_CHECK; ctl.data = state->ids; ctl.size = sizeof(struct dnet_bulk_id) * state->num; st = dnet_state_search_by_addr(n, &state->addr); if (!st) { err = -ENOENT; goto err_out_put; } dnet_setup_id(&ctl.id, st->idc->group->group_id, st->idc->ids[0].raw.id); dnet_wait_get(p->w); dnet_log(n, DNET_LOG_DEBUG, "BULK: sending %u bytes of data to %s (%s)\n", ctl.size, dnet_dump_id(&ctl.id), dnet_server_convert_dnet_addr(&state->addr)); err = dnet_trans_alloc_send_state(st, &ctl); dnet_state_put(st); wait_ts = n->wait_ts; wait_ts.tv_sec *= DNET_BULK_IDS_SIZE; err = dnet_wait_event(p->w, p->w->cond != 0, &wait_ts); if (err) goto err_out_put; if (p->w->status) { err = p->w->status; goto err_out_put; } dnet_wait_put(p->w); if (atomic_dec_and_test(&p->refcnt)) { free(p->groups); free(p); } return 0; err_out_put: dnet_wait_put(p->w); err_out_free: if (atomic_dec_and_test(&p->refcnt)) { free(p->groups); free(p); } err_out_exit: dnet_log(n, DNET_LOG_ERROR, "Bulk check exited with status %d\n", err); return err; }