The branch, master has been updated
       via  5e5f569 lib/dbwrap: make it possible to delete/store the current 
record during traverse
       via  39ac945 lib/dbwrap: don't alter the record on failure in 
db_rbt_store()
       via  a06b9b4 lib/dbwrap: fix db_rbt_store and update the per record node 
pointer
       via  5b8cb6b lib/dbwrap: remove unused per db_record pointer in 
dbwrap_rbt
      from  fc7e111 Fix bad bugfix for bug #8910 - resolve_ads() code can 
return zero addresses and miss valid DC IP addresses

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5e5f5692b8061e7151f80b155a229ce9bbb31ef9
Author: Stefan Metzmacher <[email protected]>
Date:   Wed May 30 15:06:12 2012 +0200

    lib/dbwrap: make it possible to delete/store the current record during 
traverse
    
    metze
    
    Autobuild-User: Stefan Metzmacher <[email protected]>
    Autobuild-Date: Thu May 31 02:50:09 CEST 2012 on sn-devel-104

commit 39ac9457a3d75a344b6ca41a7df3122eb9c5b26e
Author: Stefan Metzmacher <[email protected]>
Date:   Wed May 30 16:50:06 2012 +0200

    lib/dbwrap: don't alter the record on failure in db_rbt_store()
    
    metze

commit a06b9b413e6e739310d6f0e95ad5d31f9503482a
Author: Stefan Metzmacher <[email protected]>
Date:   Wed May 30 16:48:39 2012 +0200

    lib/dbwrap: fix db_rbt_store and update the per record node pointer
    
    metze

commit 5b8cb6b2be4008d3f985e304f6c7cf259672e616
Author: Stefan Metzmacher <[email protected]>
Date:   Wed May 30 16:05:03 2012 +0200

    lib/dbwrap: remove unused per db_record pointer in dbwrap_rbt
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/dbwrap/dbwrap_rbt.c |  117 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 90 insertions(+), 27 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
index d468953..3dca3ba 100644
--- a/lib/dbwrap/dbwrap_rbt.c
+++ b/lib/dbwrap/dbwrap_rbt.c
@@ -30,7 +30,6 @@ struct db_rbt_ctx {
 };
 
 struct db_rbt_rec {
-       struct db_rbt_ctx *db_ctx;
        struct db_rbt_node *node;
 };
 
@@ -92,6 +91,8 @@ static void db_rbt_parse_node(struct db_rbt_node *node,
 
 static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
 {
+       struct db_rbt_ctx *db_ctx = talloc_get_type_abort(
+               rec->db->private_data, struct db_rbt_ctx);
        struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data;
        struct db_rbt_node *node;
 
@@ -120,13 +121,23 @@ static NTSTATUS db_rbt_store(struct db_record *rec, 
TDB_DATA data, int flag)
                        rec_priv->node->valuesize = data.dsize;
                        return NT_STATUS_OK;
                }
+       }
+
+       node = (struct db_rbt_node *)talloc_size(db_ctx,
+               offsetof(struct db_rbt_node, data) + rec->key.dsize
+               + data.dsize);
+
+       if (node == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
+       if (rec_priv->node != NULL) {
                /*
                 * We need to delete the key from the tree and start fresh,
                 * there's not enough space in the existing record
                 */
 
-               rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree);
+               rb_erase(&rec_priv->node->rb_node, &db_ctx->tree);
 
                /*
                 * Keep the existing node around for a while: If the record
@@ -134,15 +145,6 @@ static NTSTATUS db_rbt_store(struct db_record *rec, 
TDB_DATA data, int flag)
                 */
        }
 
-       node = (struct db_rbt_node *)talloc_size(rec_priv->db_ctx,
-               offsetof(struct db_rbt_node, data) + rec->key.dsize
-               + data.dsize);
-
-       if (node == NULL) {
-               TALLOC_FREE(rec_priv->node);
-               return NT_STATUS_NO_MEMORY;
-       }
-
        ZERO_STRUCT(node->rb_node);
 
        node->keysize = rec->key.dsize;
@@ -152,11 +154,12 @@ static NTSTATUS db_rbt_store(struct db_record *rec, 
TDB_DATA data, int flag)
 
        memcpy(this_key.dptr, rec->key.dptr, node->keysize);
        TALLOC_FREE(rec_priv->node);
+       rec_priv->node = node;
 
        memcpy(this_val.dptr, data.dptr, node->valuesize);
 
        parent = NULL;
-       p = &rec_priv->db_ctx->tree.rb_node;
+       p = &db_ctx->tree.rb_node;
 
        while (*p) {
                struct db_rbt_node *r;
@@ -183,24 +186,37 @@ static NTSTATUS db_rbt_store(struct db_record *rec, 
TDB_DATA data, int flag)
        }
 
        rb_link_node(&node->rb_node, parent, p);
-       rb_insert_color(&node->rb_node, &rec_priv->db_ctx->tree);
+       rb_insert_color(&node->rb_node, &db_ctx->tree);
 
        return NT_STATUS_OK;
 }
 
 static NTSTATUS db_rbt_delete(struct db_record *rec)
 {
+       struct db_rbt_ctx *db_ctx = talloc_get_type_abort(
+               rec->db->private_data, struct db_rbt_ctx);
        struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data;
 
        if (rec_priv->node == NULL) {
                return NT_STATUS_OK;
        }
 
-       rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree);
+       rb_erase(&rec_priv->node->rb_node, &db_ctx->tree);
        TALLOC_FREE(rec_priv->node);
 
        return NT_STATUS_OK;
 }
+
+static NTSTATUS db_rbt_store_deny(struct db_record *rec, TDB_DATA data, int 
flag)
+{
+       return NT_STATUS_MEDIA_WRITE_PROTECTED;
+}
+
+static NTSTATUS db_rbt_delete_deny(struct db_record *rec)
+{
+       return NT_STATUS_MEDIA_WRITE_PROTECTED;
+}
+
 struct db_rbt_search_result {
        TDB_DATA key;
        TDB_DATA val;
@@ -256,9 +272,6 @@ static struct db_record *db_rbt_fetch_locked(struct 
db_context *db_ctx,
                                             TALLOC_CTX *mem_ctx,
                                             TDB_DATA key)
 {
-       struct db_rbt_ctx *ctx = talloc_get_type_abort(
-               db_ctx->private_data, struct db_rbt_ctx);
-
        struct db_rbt_rec *rec_priv;
        struct db_record *result;
        size_t size;
@@ -290,7 +303,6 @@ static struct db_record *db_rbt_fetch_locked(struct 
db_context *db_ctx,
 
        rec_priv = (struct db_rbt_rec *)
                ((char *)result + DBWRAP_RBT_ALIGN(sizeof(struct db_record)));
-       rec_priv->db_ctx = ctx;
 
        result->store = db_rbt_store;
        result->delete_rec = db_rbt_delete;
@@ -345,27 +357,47 @@ static NTSTATUS db_rbt_parse_record(struct db_context 
*db, TDB_DATA key,
        return NT_STATUS_OK;
 }
 
-static int db_rbt_traverse_internal(struct rb_node *n,
+static int db_rbt_traverse_internal(struct db_context *db,
+                                   struct rb_node *n,
                                    int (*f)(struct db_record *db,
                                             void *private_data),
-                                   void *private_data, uint32_t* count)
+                                   void *private_data, uint32_t* count,
+                                   bool rw)
 {
-       struct db_rbt_node *r;
+       struct rb_node *rb_right;
+       struct rb_node *rb_left;
        struct db_record rec;
+       struct db_rbt_rec rec_priv;
        int ret;
 
        if (n == NULL) {
                return 0;
        }
 
-       ret = db_rbt_traverse_internal(n->rb_left, f, private_data, count);
+       rb_left = n->rb_left;
+       rb_right = n->rb_right;
+
+       ret = db_rbt_traverse_internal(db, rb_left, f, private_data, count, rw);
        if (ret != 0) {
                return ret;
        }
 
-       r = db_rbt2node(n);
+       ZERO_STRUCT(rec_priv);
+       rec_priv.node = db_rbt2node(n);
+       /* n might be altered by the callback function */
+       n = NULL;
+
        ZERO_STRUCT(rec);
-       db_rbt_parse_node(r, &rec.key, &rec.value);
+       rec.db = db;
+       rec.private_data = &rec_priv;
+       if (rw) {
+               rec.store = db_rbt_store;
+               rec.delete_rec = db_rbt_delete;
+       } else {
+               rec.store = db_rbt_store_deny;
+               rec.delete_rec = db_rbt_delete_deny;
+       }
+       db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);
 
        ret = f(&rec, private_data);
        (*count) ++;
@@ -373,7 +405,15 @@ static int db_rbt_traverse_internal(struct rb_node *n,
                return ret;
        }
 
-       return db_rbt_traverse_internal(n->rb_right, f, private_data, count);
+       if (rec_priv.node != NULL) {
+               /*
+                * If the current record is still there
+                * we should take the current rb_right.
+                */
+               rb_right = rec_priv.node->rb_node.rb_right;
+       }
+
+       return db_rbt_traverse_internal(db, rb_right, f, private_data, count, 
rw);
 }
 
 static int db_rbt_traverse(struct db_context *db,
@@ -385,7 +425,30 @@ static int db_rbt_traverse(struct db_context *db,
                db->private_data, struct db_rbt_ctx);
        uint32_t count = 0;
 
-       int ret =  db_rbt_traverse_internal(ctx->tree.rb_node, f, private_data, 
&count);
+       int ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
+                                          f, private_data, &count,
+                                          true /* rw */);
+       if (ret != 0) {
+               return -1;
+       }
+       if (count > INT_MAX) {
+               return -1;
+       }
+       return count;
+}
+
+static int db_rbt_traverse_read(struct db_context *db,
+                               int (*f)(struct db_record *db,
+                                        void *private_data),
+                               void *private_data)
+{
+       struct db_rbt_ctx *ctx = talloc_get_type_abort(
+               db->private_data, struct db_rbt_ctx);
+       uint32_t count = 0;
+
+       int ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
+                                          f, private_data, &count,
+                                          false /* rw */);
        if (ret != 0) {
                return -1;
        }
@@ -434,7 +497,7 @@ struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx)
        result->fetch_locked = db_rbt_fetch_locked;
        result->try_fetch_locked = NULL;
        result->traverse = db_rbt_traverse;
-       result->traverse_read = db_rbt_traverse;
+       result->traverse_read = db_rbt_traverse_read;
        result->get_seqnum = db_rbt_get_seqnum;
        result->transaction_start = db_rbt_trans_dummy;
        result->transaction_commit = db_rbt_trans_dummy;


-- 
Samba Shared Repository

Reply via email to