From d5ab80054d3c1dde396c18ae506bb3713e84e7e6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 9 Nov 2007 23:43:24 +0100 Subject: dbwrap_rbt This is meant as a replacement for the internal tdb. To me it seems a bit silly that for in-memory structures we do our own memory management. With this rbt based approach we can make use of the system-supplied malloc. (This used to be commit 54e5d4404619443caed32e2acff8921cdbff9ed1) --- source3/lib/dbwrap_rbt.c | 303 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 source3/lib/dbwrap_rbt.c (limited to 'source3/lib/dbwrap_rbt.c') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c new file mode 100644 index 0000000000..df568a0410 --- /dev/null +++ b/source3/lib/dbwrap_rbt.c @@ -0,0 +1,303 @@ +/* + Unix SMB/CIFS implementation. + Database interface wrapper around red-black trees + Copyright (C) Volker Lendecke 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "rbtree.h" + +struct db_rbt_ctx { + struct rb_root tree; +}; + +struct db_rbt_rec { + struct db_rbt_ctx *db_ctx; + struct db_rbt_node *node; +}; + +/* The structure that ends up in the tree */ + +struct db_rbt_node { + struct rb_node rb_node; + size_t keysize, valuesize; + + /* + * key and value are appended implicitly, "data" is only here as a + * target for offsetof() + */ + + char data[]; +}; + +/* + * dissect a db_rbt_node into its implicit key and value parts + */ + +static void db_rbt_parse_node(struct db_rbt_node *node, + TDB_DATA *key, TDB_DATA *value) +{ + key->dptr = ((uint8 *)node) + offsetof(struct db_rbt_node, data); + key->dsize = node->keysize; + value->dptr = key->dptr + node->keysize; + value->dsize = node->valuesize; +} + +static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) +{ + struct db_rbt_rec *rec_priv = talloc_get_type_abort( + rec->private_data, struct db_rbt_rec); + + struct db_rbt_node *node; + + struct rb_node ** p; + struct rb_node * parent; + + TDB_DATA this_key, this_val; + + if (rec_priv->node != NULL) { + + /* + * The record was around previously + */ + + db_rbt_parse_node(rec_priv->node, &this_key, &this_val); + + SMB_ASSERT(this_key.dsize == rec->key.dsize); + SMB_ASSERT(memcmp(this_key.dptr, rec->key.dptr, + this_key.dsize) == 0); + + if (this_val.dsize >= data.dsize) { + /* + * The new value fits into the old space + */ + memcpy(this_val.dptr, data.dptr, data.dsize); + rec_priv->node->valuesize = data.dsize; + return NT_STATUS_OK; + } + + /* + * 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); + SAFE_FREE(rec_priv->node); + } + + node = (struct db_rbt_node *)SMB_MALLOC( + offsetof(struct db_rbt_node, data) + rec->key.dsize + + data.dsize); + + if (node == NULL) { + return NT_STATUS_NO_MEMORY; + } + + ZERO_STRUCT(node->rb_node); + + node->keysize = rec->key.dsize; + node->valuesize = data.dsize; + + db_rbt_parse_node(node, &this_key, &this_val); + + memcpy(this_key.dptr, rec->key.dptr, node->keysize); + memcpy(this_val.dptr, data.dptr, node->valuesize); + + parent = NULL; + p = &rec_priv->db_ctx->tree.rb_node; + + while (*p) { + struct db_rbt_node *r; + TDB_DATA search_key, search_val; + int res; + + parent = (*p); + + r = (struct db_rbt_node *) + ((char *)(*p) - offsetof(struct db_rbt_node, rb_node)); + + db_rbt_parse_node(r, &search_key, &search_val); + + res = memcmp(this_key.dptr, search_key.dptr, + MIN(this_key.dsize, search_key.dsize)); + + if ((res < 0) + || ((res == 0) + && (this_key.dsize < search_key.dsize))) { + p = &(*p)->rb_left; + } + else if ((res > 0) + || ((res == 0) + && (this_key.dsize > search_key.dsize))) { + p = &(*p)->rb_right; + } + else { + smb_panic("someone messed with the tree"); + } + } + + rb_link_node(&node->rb_node, parent, p); + rb_insert_color(&node->rb_node, &rec_priv->db_ctx->tree); + + return NT_STATUS_OK; +} + +static NTSTATUS db_rbt_delete(struct db_record *rec) +{ + struct db_rbt_rec *rec_priv = talloc_get_type_abort( + rec->private_data, struct db_rbt_rec); + + if (rec_priv->node == NULL) { + return NT_STATUS_OK; + } + + rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree); + SAFE_FREE(rec_priv->node); + + return NT_STATUS_OK; +} + +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; + struct rb_node *n; + + result = talloc(mem_ctx, struct db_record); + + if (result == NULL) { + return NULL; + } + + rec_priv = talloc(result, struct db_rbt_rec); + + if (rec_priv == NULL) { + TALLOC_FREE(result); + return NULL; + } + + rec_priv->db_ctx = ctx; + + result->store = db_rbt_store; + result->delete_rec = db_rbt_delete; + result->private_data = rec_priv; + + n = ctx->tree.rb_node; + + while (n != NULL) { + struct db_rbt_node *r; + TDB_DATA search_key, search_val; + int res; + + r = (struct db_rbt_node *) + ((char *)n - offsetof(struct db_rbt_node, rb_node)); + + db_rbt_parse_node(r, &search_key, &search_val); + + res = memcmp(key.dptr, search_key.dptr, + MIN(key.dsize, search_key.dsize)); + + if ((res < 0) + || ((res == 0) && (key.dsize < search_key.dsize))) { + n = n->rb_left; + } + else if ((res > 0) + || ((res == 0) && (key.dsize > search_key.dsize))) { + n = n->rb_right; + } + else { + rec_priv->node = r; + result->key = search_key; + result->value = search_val; + return result; + } + } + + result->key.dsize = key.dsize; + result->key.dptr = (uint8_t *)talloc_memdup( + result, key.dptr, key.dsize); + + if (result->key.dptr == NULL) { + TALLOC_FREE(result); + return NULL; + } + + rec_priv->node = NULL; + result->value.dsize = 0; + result->value.dptr = NULL; + return result; +} + +static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, + TDB_DATA key, TDB_DATA *data) +{ + struct db_record *rec; + + if (!(rec = db->fetch_locked(db, mem_ctx, key))) { + return -1; + } + + data->dsize = rec->value.dsize; + data->dptr = (uint8 *)talloc_memdup(mem_ctx, rec->value.dptr, + rec->value.dsize); + TALLOC_FREE(rec); + return 0; +} + + +static int db_rbt_traverse(struct db_context *db, + int (*f)(struct db_record *db, + void *private_data), + void *private_data) +{ + return -1; +} + +static int db_rbt_get_seqnum(struct db_context *db) +{ + return 0; +} + +struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx) +{ + struct db_context *result; + + result = talloc(mem_ctx, struct db_context); + + if (result == NULL) { + return NULL; + } + + result->private_data = TALLOC_ZERO_P(result, struct db_rbt_ctx); + + if (result->private_data == NULL) { + TALLOC_FREE(result); + return NULL; + } + + result->fetch_locked = db_rbt_fetch_locked; + result->fetch = db_rbt_fetch; + result->traverse = db_rbt_traverse; + result->traverse_read = db_rbt_traverse; + result->get_seqnum = db_rbt_get_seqnum; + + return result; +} -- cgit From 537c4cf9cdb1f76c317c8fbd12068ce1f3fbbf0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Dec 2007 16:03:57 -0800 Subject: Fix valgrind error in dbwrap_rbt where rec_priv->node was being accessed after free. VALOKER PLEASE CHECK THIS VERY CAREFULLY !!!! This is a correct fix in that it fixes the valgrind error, but it looks inelegant to me. I think if I understood this code better I could craft a more subtle fix. Still looking at it.... Jeremy. (This used to be commit 12cce3be2a24fd72106d747890caf6c7f29db43d) --- source3/lib/dbwrap_rbt.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/lib/dbwrap_rbt.c') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index df568a0410..15d9b67414 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -68,6 +68,8 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) TDB_DATA this_key, this_val; + bool del_old_keyval = false; + if (rec_priv->node != NULL) { /* @@ -95,7 +97,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) */ rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree); - SAFE_FREE(rec_priv->node); + del_old_keyval = true; } node = (struct db_rbt_node *)SMB_MALLOC( @@ -103,6 +105,9 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) + data.dsize); if (node == NULL) { + if (del_old_keyval) { + SAFE_FREE(rec_priv->node); + } return NT_STATUS_NO_MEMORY; } @@ -152,6 +157,10 @@ 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); + if (del_old_keyval) { + SAFE_FREE(rec_priv->node); + } + return NT_STATUS_OK; } -- cgit From c99dc69a453a67a38b1a1d5c5088a55d22a68651 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Dec 2007 17:30:02 -0800 Subject: We've finished with the old node once we've copied the keyval. Jeremy. (This used to be commit 39f3efbcc5fbdff1db1b12e5fc7368968f240993) --- source3/lib/dbwrap_rbt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib/dbwrap_rbt.c') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 15d9b67414..468b9405ee 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -121,6 +121,10 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) memcpy(this_key.dptr, rec->key.dptr, node->keysize); memcpy(this_val.dptr, data.dptr, node->valuesize); + if (del_old_keyval) { + SAFE_FREE(rec_priv->node); + } + parent = NULL; p = &rec_priv->db_ctx->tree.rb_node; @@ -157,10 +161,6 @@ 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); - if (del_old_keyval) { - SAFE_FREE(rec_priv->node); - } - return NT_STATUS_OK; } -- cgit From 873b6f0f21e61be6e4f7084fc0ded768dfa077ab Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 13:48:49 +0100 Subject: Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-716-g12cce3b On Tue, Dec 18, 2007 at 06:04:32PM -0600, Jeremy Allison wrote: > Fix valgrind error in dbwrap_rbt where rec_priv->node was > being accessed after free. VALOKER PLEASE CHECK THIS VERY > CAREFULLY !!!! This is a correct fix in that it fixes the > valgrind error, but it looks inelegant to me. I think if > I understood this code better I could craft a more subtle > fix. Still looking at it.... Thanks a lot. Fully correct. What about the attached little simplification? Volker (This used to be commit 5b72828600fb057a7aeb5f1a6fb6c23c23f28cd8) --- source3/lib/dbwrap_rbt.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'source3/lib/dbwrap_rbt.c') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 468b9405ee..93d73f29d1 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -68,8 +68,6 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) TDB_DATA this_key, this_val; - bool del_old_keyval = false; - if (rec_priv->node != NULL) { /* @@ -97,7 +95,11 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) */ rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree); - del_old_keyval = true; + + /* + * Keep the existing node around for a while: If the record + * existed before, we reference the key data in there. + */ } node = (struct db_rbt_node *)SMB_MALLOC( @@ -105,9 +107,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) + data.dsize); if (node == NULL) { - if (del_old_keyval) { - SAFE_FREE(rec_priv->node); - } + SAFE_FREE(rec_priv->node); return NT_STATUS_NO_MEMORY; } @@ -119,11 +119,9 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) db_rbt_parse_node(node, &this_key, &this_val); memcpy(this_key.dptr, rec->key.dptr, node->keysize); - memcpy(this_val.dptr, data.dptr, node->valuesize); + SAFE_FREE(rec_priv->node); - if (del_old_keyval) { - SAFE_FREE(rec_priv->node); - } + memcpy(this_val.dptr, data.dptr, node->valuesize); parent = NULL; p = &rec_priv->db_ctx->tree.rb_node; -- cgit From 4af27ec877d67afc719bccd350dae33ef8dd62b5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 12 Jan 2008 10:38:17 +0100 Subject: Restructure dbwrap_rbt In this low-level code, play tricks to reduce the number of allocations to the possible minimum. I would not recommend this for higher-level code, but here it pays off. (This used to be commit 71b1e6ff1595fbaa8dd49b996c45541531c7e98c) --- source3/lib/dbwrap_rbt.c | 186 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 127 insertions(+), 59 deletions(-) (limited to 'source3/lib/dbwrap_rbt.c') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 93d73f29d1..633b695b52 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Database interface wrapper around red-black trees - Copyright (C) Volker Lendecke 2007 + Copyright (C) Volker Lendecke 2007, 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ #include "includes.h" #include "rbtree.h" +#define ALIGN(_size_) (((_size_)+15)&~15) + struct db_rbt_ctx { struct rb_root tree; }; @@ -43,6 +45,35 @@ struct db_rbt_node { char data[]; }; +/* + * Hide the ugly pointer calculations in a function + */ + +static struct db_rbt_node *db_rbt2node(struct rb_node *node) +{ + return (struct db_rbt_node *) + ((char *)node - offsetof(struct db_rbt_node, rb_node)); +} + +/* + * Compare two keys + */ + +static int db_rbt_compare(TDB_DATA a, TDB_DATA b) +{ + int res; + + res = memcmp(a.dptr, b.dptr, MIN(a.dsize, b.dsize)); + + if ((res < 0) || ((res == 0) && (a.dsize < b.dsize))) { + return -1; + } + if ((res > 0) || ((res == 0) && (a.dsize > b.dsize))) { + return 1; + } + return 0; +} + /* * dissect a db_rbt_node into its implicit key and value parts */ @@ -58,9 +89,7 @@ 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_rec *rec_priv = talloc_get_type_abort( - rec->private_data, struct db_rbt_rec); - + struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data; struct db_rbt_node *node; struct rb_node ** p; @@ -133,22 +162,16 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) parent = (*p); - r = (struct db_rbt_node *) - ((char *)(*p) - offsetof(struct db_rbt_node, rb_node)); + r = db_rbt2node(*p); db_rbt_parse_node(r, &search_key, &search_val); - res = memcmp(this_key.dptr, search_key.dptr, - MIN(this_key.dsize, search_key.dsize)); + res = db_rbt_compare(this_key, search_key); - if ((res < 0) - || ((res == 0) - && (this_key.dsize < search_key.dsize))) { + if (res == -1) { p = &(*p)->rb_left; } - else if ((res > 0) - || ((res == 0) - && (this_key.dsize > search_key.dsize))) { + else if (res == 1) { p = &(*p)->rb_right; } else { @@ -164,8 +187,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) static NTSTATUS db_rbt_delete(struct db_record *rec) { - struct db_rbt_rec *rec_priv = talloc_get_type_abort( - rec->private_data, struct db_rbt_rec); + struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data; if (rec_priv->node == NULL) { return NT_STATUS_OK; @@ -187,85 +209,128 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx, struct db_rbt_rec *rec_priv; struct db_record *result; struct rb_node *n; + size_t size; + bool found = false; + struct db_rbt_node *r = NULL; + TDB_DATA search_key = tdb_null, search_val = tdb_null; - result = talloc(mem_ctx, struct db_record); + n = ctx->tree.rb_node; - if (result == NULL) { - return NULL; + while (n != NULL) { + int res; + + r = db_rbt2node(n); + + db_rbt_parse_node(r, &search_key, &search_val); + + res = db_rbt_compare(key, search_key); + + if (res == -1) { + n = n->rb_left; + } + else if (res == 1) { + n = n->rb_right; + } + else { + found = true; + break; + } } - rec_priv = talloc(result, struct db_rbt_rec); + /* + * In this low-level routine, play tricks to reduce the number of + * tallocs to one. Not recommened for general use, but here it pays + * off. + */ - if (rec_priv == NULL) { - TALLOC_FREE(result); + size = ALIGN(sizeof(struct db_record)) + sizeof(struct db_rbt_rec); + + if (!found) { + /* + * We need to keep the key around for later store + */ + size += key.dsize; + } + + result = (struct db_record *)talloc_size(mem_ctx, size); + if (result == NULL) { return NULL; } + rec_priv = (struct db_rbt_rec *) + ((char *)result + ALIGN(sizeof(struct db_record))); rec_priv->db_ctx = ctx; result->store = db_rbt_store; result->delete_rec = db_rbt_delete; result->private_data = rec_priv; + if (found) { + rec_priv->node = r; + result->key = search_key; + result->value = search_val; + } + else { + rec_priv->node = NULL; + result->key.dptr = (uint8 *) + ((char *)rec_priv + sizeof(*rec_priv)); + result->key.dsize = key.dsize; + memcpy(result->key.dptr, key.dptr, key.dsize); + + result->value = tdb_null; + } + + return result; +} + +static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, + TDB_DATA key, TDB_DATA *data) +{ + struct db_rbt_ctx *ctx = talloc_get_type_abort( + db->private_data, struct db_rbt_ctx); + + struct rb_node *n; + bool found = false; + struct db_rbt_node *r = NULL; + TDB_DATA search_key, search_val; + uint8_t *result; + n = ctx->tree.rb_node; while (n != NULL) { - struct db_rbt_node *r; - TDB_DATA search_key, search_val; int res; - r = (struct db_rbt_node *) - ((char *)n - offsetof(struct db_rbt_node, rb_node)); + r = db_rbt2node(n); db_rbt_parse_node(r, &search_key, &search_val); - res = memcmp(key.dptr, search_key.dptr, - MIN(key.dsize, search_key.dsize)); + res = db_rbt_compare(key, search_key); - if ((res < 0) - || ((res == 0) && (key.dsize < search_key.dsize))) { + if (res == -1) { n = n->rb_left; } - else if ((res > 0) - || ((res == 0) && (key.dsize > search_key.dsize))) { + else if (res == 1) { n = n->rb_right; } else { - rec_priv->node = r; - result->key = search_key; - result->value = search_val; - return result; + found = true; + break; } } - result->key.dsize = key.dsize; - result->key.dptr = (uint8_t *)talloc_memdup( - result, key.dptr, key.dsize); - - if (result->key.dptr == NULL) { - TALLOC_FREE(result); - return NULL; + if (!found) { + *data = tdb_null; + return 0; } - rec_priv->node = NULL; - result->value.dsize = 0; - result->value.dptr = NULL; - return result; -} - -static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - struct db_record *rec; - - if (!(rec = db->fetch_locked(db, mem_ctx, key))) { + result = (uint8 *)talloc_memdup(mem_ctx, search_val.dptr, + search_val.dsize); + if (result == NULL) { return -1; } - data->dsize = rec->value.dsize; - data->dptr = (uint8 *)talloc_memdup(mem_ctx, rec->value.dptr, - rec->value.dsize); - TALLOC_FREE(rec); + data->dptr = result; + data->dsize = search_val.dsize; return 0; } @@ -275,6 +340,9 @@ static int db_rbt_traverse(struct db_context *db, void *private_data), void *private_data) { + /* + * Nobody uses this so far, and unused code is broken code :-) + */ return -1; } -- cgit From 541b8dec4e21e0a88ccc0d85bc01433b66eb3588 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Mar 2008 10:17:05 +0100 Subject: Add transactions to the dbwrap API Only filled in for tdb so far, for rbt it's pointless, and ctdb itself needs to be extended (This used to be commit 0a55e018dd68af06d84332d54148bbfb0b510b22) --- source3/lib/dbwrap_rbt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/lib/dbwrap_rbt.c') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 633b695b52..46459c86da 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -351,6 +351,14 @@ static int db_rbt_get_seqnum(struct db_context *db) return 0; } +static int db_rbt_trans_dummy(struct db_context *db) +{ + /* + * Transactions are pretty pointless in-memory, just return success. + */ + return 0; +} + struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx) { struct db_context *result; @@ -373,6 +381,9 @@ struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx) result->traverse = db_rbt_traverse; result->traverse_read = db_rbt_traverse; result->get_seqnum = db_rbt_get_seqnum; + result->transaction_start = db_rbt_trans_dummy; + result->transaction_commit = db_rbt_trans_dummy; + result->transaction_cancel = db_rbt_trans_dummy; return result; } -- cgit From bdc93910211b17587be3746b66f21a95ba0d7eb5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 19 Jun 2008 09:50:34 +0200 Subject: Fix the build on FreeBSD 4.6.2 (This used to be commit 4f50cb63e9b565ae0747127baa651a1a1874298b) --- source3/lib/dbwrap_rbt.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/lib/dbwrap_rbt.c') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 46459c86da..b70ce3dfa0 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -20,7 +20,7 @@ #include "includes.h" #include "rbtree.h" -#define ALIGN(_size_) (((_size_)+15)&~15) +#define DBWRAP_RBT_ALIGN(_size_) (((_size_)+15)&~15) struct db_rbt_ctx { struct rb_root tree; @@ -42,7 +42,7 @@ struct db_rbt_node { * target for offsetof() */ - char data[]; + char data[1]; }; /* @@ -243,7 +243,8 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx, * off. */ - size = ALIGN(sizeof(struct db_record)) + sizeof(struct db_rbt_rec); + size = DBWRAP_RBT_ALIGN(sizeof(struct db_record)) + + sizeof(struct db_rbt_rec); if (!found) { /* @@ -258,7 +259,7 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx, } rec_priv = (struct db_rbt_rec *) - ((char *)result + ALIGN(sizeof(struct db_record))); + ((char *)result + DBWRAP_RBT_ALIGN(sizeof(struct db_record))); rec_priv->db_ctx = ctx; result->store = db_rbt_store; -- cgit