struct ctdb_call_state *state;
struct ctdb_db_context *ctdb_db;
- state = idr_find_type(ctdb->idr, reqid, struct ctdb_call_state);
+ state = ctdb_reqid_find(ctdb, reqid, struct ctdb_call_state);
+
if (state == NULL) {
return;
}
+ if (reqid != state->reqid) {
+ /* we found a record but it was the wrong one */
+ DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",reqid));
+ return;
+ }
+
ctdb_db = state->ctdb_db;
DEBUG(2,("vnn %u dmaster response %08x\n",
struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
struct ctdb_call_state *state;
- state = idr_find_type(ctdb->idr, hdr->reqid, struct ctdb_call_state);
+ state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state);
if (state == NULL) {
DEBUG(0, (__location__ " reqid %d not found\n", hdr->reqid));
return;
}
+ if (hdr->reqid != state->reqid) {
+ /* we found a record but it was the wrong one */
+ DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
+ return;
+ }
+
state->call.reply_data.dptr = c->data;
state->call.reply_data.dsize = c->datalen;
state->call.status = c->status;
TDB_DATA data;
int ret;
- state = idr_find_type(ctdb->idr, hdr->reqid, struct ctdb_call_state);
+ state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state);
+
if (state == NULL) {
return;
}
+ if (hdr->reqid != state->reqid) {
+ /* we found a record but it was the wrong one */
+ DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
+ return;
+ }
+
ctdb_db = state->ctdb_db;
ret = ctdb_ltdb_lock_requeue(ctdb_db, state->call.key, hdr,
struct ctdb_reply_error *c = (struct ctdb_reply_error *)hdr;
struct ctdb_call_state *state;
- state = idr_find_type(ctdb->idr, hdr->reqid, struct ctdb_call_state);
- if (state == NULL) return;
+ state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state);
+ if (state == NULL) {
+ return;
+ }
+
+ if (hdr->reqid != state->reqid) {
+ /* we found a record but it was the wrong one */
+ DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
+ return;
+ }
talloc_steal(state, c);
struct ctdb_reply_redirect *c = (struct ctdb_reply_redirect *)hdr;
struct ctdb_call_state *state;
- state = idr_find_type(ctdb->idr, hdr->reqid, struct ctdb_call_state);
- if (state == NULL) return;
+ state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state);
+ if (state == NULL) {
+ return;
+ }
+
+ if (hdr->reqid != state->reqid) {
+ /* we found a record but it was the wrong one */
+ DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
+ return;
+ }
/* don't allow for too many redirects */
if (state->redirect_count++ == CTDB_MAX_REDIRECT) {
*/
static int ctdb_call_destructor(struct ctdb_call_state *state)
{
- idr_remove(state->node->ctdb->idr, state->c->hdr.reqid);
+ ctdb_reqid_remove(state->node->ctdb, state->reqid);
return 0;
}
state = talloc_zero(ctdb_db, struct ctdb_call_state);
CTDB_NO_MEMORY_NULL(ctdb, state);
+ state->reqid = ctdb_reqid_new(ctdb, state);
+ talloc_set_destructor(state, ctdb_call_destructor);
len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
state->c = ctdb->methods->allocate_pkt(state, len);
state->c->hdr.srcnode = ctdb->vnn;
/* this limits us to 16k outstanding messages - not unreasonable */
- state->c->hdr.reqid = idr_get_new(ctdb->idr, state, 0xFFFF);
+ state->c->hdr.reqid = state->reqid;
state->c->flags = call->flags;
state->c->db_id = ctdb_db->db_id;
state->c->callid = call->call_id;
state->header = *header;
state->ctdb_db = ctdb_db;
- talloc_set_destructor(state, ctdb_call_destructor);
-
ctdb_queue_packet(ctdb, &state->c->hdr);
#if CTDB_REQ_TIMEOUT
struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
struct ctdb_client_call_state *state;
- state = idr_find_type(ctdb->idr, hdr->reqid, struct ctdb_client_call_state);
+ state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_call_state);
if (state == NULL) {
DEBUG(0,(__location__ " reqid %d not found\n", hdr->reqid));
return;
}
+ if (hdr->reqid != state->reqid) {
+ /* we found a record but it was the wrong one */
+ DEBUG(0, ("Dropped orphaned reply with reqid:%d\n",hdr->reqid));
+ return;
+ }
+
state->call.reply_data.dptr = c->data;
state->call.reply_data.dsize = c->datalen;
state->call.status = c->status;
*/
static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
{
- idr_remove(state->ctdb_db->ctdb->idr, state->reqid);
+ ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
return 0;
}
c->hdr.ctdb_version = CTDB_VERSION;
c->hdr.operation = CTDB_REQ_CALL;
/* this limits us to 16k outstanding messages - not unreasonable */
- c->hdr.reqid = idr_get_new(ctdb->idr, state, 0xFFFF);
+ c->hdr.reqid = ctdb_reqid_new(ctdb, state);
c->flags = call->flags;
c->db_id = ctdb_db->db_id;
c->callid = call->call_id;
struct ctdb_reply_status *r = (struct ctdb_reply_status *)hdr;
struct ctdb_status_state *state;
- state = idr_find_type(ctdb->idr, hdr->reqid, struct ctdb_status_state);
+ state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_status_state);
if (state == NULL) {
DEBUG(0,(__location__ " reqid %d not found\n", hdr->reqid));
return;
}
+ if (hdr->reqid != state->reqid) {
+ /* we found a record but it was the wrong one */
+ DEBUG(0, ("Dropped orphaned reply with reqid:%d\n",hdr->reqid));
+ return;
+ }
+
*state->status = r->status;
state->state = CTDB_STATUS_DONE;
}
state = talloc(ctdb, struct ctdb_status_state);
CTDB_NO_MEMORY(ctdb, state);
- state->reqid = idr_get_new(ctdb->idr, state, 0xFFFF);
+ state->reqid = ctdb_reqid_new(ctdb, state);
state->status = status;
state->state = CTDB_STATUS_WAIT;
/*
a type checking varient of idr_find
*/
-void *_idr_find_type(struct idr_context *idp, int id, const char *type, const char *location)
+static void *_idr_find_type(struct idr_context *idp, int id, const char *type, const char *location)
{
void *p = idr_find(idp, id);
if (p && talloc_check_name(p, type) == NULL) {
*latency = l;
}
}
+
+uint32_t ctdb_reqid_new(struct ctdb_context *ctdb, void *state)
+{
+ uint32_t id;
+
+ id = ctdb->idr_cnt++ & 0xFFFF;
+ id |= (idr_get_new(ctdb->idr, state, 0xFFFF)<<16);
+ return id;
+}
+
+void *_ctdb_reqid_find(struct ctdb_context *ctdb, uint32_t reqid, const char *type, const char *location)
+{
+ void *p;
+
+ p = _idr_find_type(ctdb->idr, (reqid>>16)&0xFFFF, type, location);
+ if (p == NULL) {
+ DEBUG(0, ("Could not find idr:%d\n",reqid));
+ }
+
+ return p;
+}
+
+
+void ctdb_reqid_remove(struct ctdb_context *ctdb, uint32_t reqid)
+{
+ int ret;
+
+ ret = idr_remove(ctdb->idr, (reqid>>16)&0xFFFF);
+ if (ret != 0) {
+ DEBUG(0, ("Removing idr that does not exist\n"));
+ }
+}
uint32_t num_finished;
unsigned flags;
struct idr_context *idr;
+ uint16_t idr_cnt;
struct ctdb_node **nodes; /* array of nodes in the cluster - indexed by vnn */
char *err_msg;
const struct ctdb_methods *methods; /* transport methods */
*/
struct ctdb_call_state {
enum call_state state;
+ uint32_t reqid;
struct ctdb_req_call *c;
struct ctdb_db_context *ctdb_db;
struct ctdb_node *node;
struct ctdb_ltdb_header *header, TDB_DATA *data,
uint32_t caller);
-void *_idr_find_type(struct idr_context *idp, int id, const char *type, const char *location);
-#define idr_find_type(idp, id, type) (type *)_idr_find_type(idp, id, #type, __location__)
+#define ctdb_reqid_find(ctdb, reqid, type) (type *)_ctdb_reqid_find(ctdb, reqid, #type, __location__)
void ctdb_recv_raw_pkt(void *p, uint8_t *data, uint32_t length);
void ctdb_latency(double *latency, struct timeval t);
+uint32_t ctdb_reqid_new(struct ctdb_context *ctdb, void *state);
+void *_ctdb_reqid_find(struct ctdb_context *ctdb, uint32_t reqid, const char *type, const char *location);
+void ctdb_reqid_remove(struct ctdb_context *ctdb, uint32_t reqid);
+
#endif