]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
split the 32bit idr field into two.
authorRonnie Sahlberg <sahlberg@ronnie>
Mon, 23 Apr 2007 08:19:50 +0000 (18:19 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Mon, 23 Apr 2007 08:19:50 +0000 (18:19 +1000)
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)

ctdb/common/ctdb_call.c
ctdb/common/ctdb_client.c
ctdb/common/ctdb_util.c
ctdb/include/ctdb_private.h

index 8db795d8897adc5760fbcb28f2207597720485c3..99a27fbf80c28df64e1057da4602bede0b6e6877 100644 (file)
@@ -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
index 1b14c3b90dfa8bac75b4cf68a85771b449101775..f00697bc26da7afe0dffd918d9b7ea531ce81e7c 100644 (file)
@@ -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;
        
index 9a5e51bfa0bedfd60dd8a89a6540e962161621a4..c7b2af7d44a21832beffd7cb9c4ec148fe0d724b 100644 (file)
@@ -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"));
+       }
+}
index 96ca6d04c9523a394428aa5cb5a15cb1c2a47e60..9feb098a628688d1abeb72d9df30925377c1436e 100644 (file)
@@ -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