From: Ronnie Sahlberg Date: Mon, 23 Apr 2007 08:19:50 +0000 (+1000) Subject: split the 32bit idr field into two. X-Git-Tag: tevent-0.9.20~348^2~2845^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bd62c78154836da65524e76ac580d703edea9c67;p=thirdparty%2Fsamba.git split the 32bit idr field into two. store the idr as the high 16 bits and use a rotating counter for the low 16 bits. (This used to be ctdb commit 7c763b7b5e6ca54a6df4586893ddaf1b508b4c22) --- diff --git a/ctdb/common/ctdb_call.c b/ctdb/common/ctdb_call.c index 8db795d8897..99a27fbf80c 100644 --- a/ctdb/common/ctdb_call.c +++ b/ctdb/common/ctdb_call.c @@ -305,11 +305,18 @@ static void ctdb_become_dmaster(struct ctdb_context *ctdb, 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", @@ -510,12 +517,18 @@ void ctdb_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) 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; @@ -544,11 +557,18 @@ void ctdb_reply_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) 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, @@ -576,8 +596,16 @@ void ctdb_reply_error(struct ctdb_context *ctdb, struct ctdb_req_header *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); @@ -601,8 +629,16 @@ void ctdb_reply_redirect(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) 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) { @@ -621,7 +657,7 @@ void ctdb_reply_redirect(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) */ 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; } @@ -705,6 +741,8 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctd 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); @@ -726,7 +764,7 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctd 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; @@ -744,8 +782,6 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctd 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 diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index 1b14c3b90df..f00697bc26d 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -70,12 +70,18 @@ static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_he 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; @@ -230,7 +236,7 @@ int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call) */ 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; } @@ -329,7 +335,7 @@ struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db, 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; @@ -627,12 +633,18 @@ static void ctdb_reply_status(struct ctdb_context *ctdb, struct ctdb_req_header 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; } @@ -655,7 +667,7 @@ int ctdb_status(struct ctdb_context *ctdb, struct ctdb_status *status) 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; diff --git a/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c index 9a5e51bfa0b..c7b2af7d44a 100644 --- a/ctdb/common/ctdb_util.c +++ b/ctdb/common/ctdb_util.c @@ -106,7 +106,7 @@ uint32_t ctdb_hash(const TDB_DATA *key) /* 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) { @@ -128,3 +128,35 @@ void ctdb_latency(double *latency, struct timeval t) *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")); + } +} diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 96ca6d04c95..9feb098a628 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -161,6 +161,7 @@ struct ctdb_context { 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 */ @@ -222,6 +223,7 @@ enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR}; */ 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; @@ -501,8 +503,7 @@ int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call, 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); @@ -510,4 +511,8 @@ int ctdb_socket_connect(struct ctdb_context *ctdb); 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