summaryrefslogtreecommitdiff
path: root/lib/dbwrap/dbwrap_rbt.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dbwrap/dbwrap_rbt.c')
-rw-r--r--lib/dbwrap/dbwrap_rbt.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
index eb5ef10fddc..d9c743b80e8 100644
--- a/lib/dbwrap/dbwrap_rbt.c
+++ b/lib/dbwrap/dbwrap_rbt.c
@@ -118,7 +118,8 @@ overflow:
return -1;
}
-static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
+static NTSTATUS db_rbt_storev(struct db_record *rec,
+ const TDB_DATA *dbufs, int num_dbufs, int flag)
{
struct db_rbt_ctx *db_ctx = talloc_get_type_abort(
rec->db->private_data, struct db_rbt_ctx);
@@ -130,12 +131,23 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
struct db_rbt_node *parent_node = NULL;
ssize_t reclen;
- TDB_DATA this_key, this_val;
+ TDB_DATA data, this_key, this_val;
+ void *to_free = NULL;
if (db_ctx->traverse_read > 0) {
return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
+ if (num_dbufs == 1) {
+ data = dbufs[0];
+ } else {
+ data = dbwrap_merge_dbufs(rec, dbufs, num_dbufs);
+ if (data.dptr == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ to_free = data.dptr;
+ }
+
if (rec_priv->node != NULL) {
/*
@@ -154,17 +166,20 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
*/
memcpy(this_val.dptr, data.dptr, data.dsize);
rec_priv->node->valuesize = data.dsize;
+ TALLOC_FREE(to_free);
return NT_STATUS_OK;
}
}
reclen = db_rbt_reclen(rec->key.dsize, data.dsize);
if (reclen == -1) {
+ TALLOC_FREE(to_free);
return NT_STATUS_INSUFFICIENT_RESOURCES;
}
node = talloc_zero_size(db_ctx, reclen);
if (node == NULL) {
+ TALLOC_FREE(to_free);
return NT_STATUS_NO_MEMORY;
}
@@ -232,6 +247,8 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
DLIST_ADD_AFTER(db_ctx->nodes, node, parent_node);
rb_insert_color(&node->rb_node, &db_ctx->tree);
+ TALLOC_FREE(to_free);
+
return NT_STATUS_OK;
}
@@ -350,7 +367,7 @@ 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)));
- result->store = db_rbt_store;
+ result->storev = db_rbt_storev;
result->delete_rec = db_rbt_delete;
result->private_data = rec_priv;
@@ -425,7 +442,7 @@ static int db_rbt_traverse_internal(struct db_context *db,
ZERO_STRUCT(rec);
rec.db = db;
rec.private_data = &rec_priv;
- rec.store = db_rbt_store;
+ rec.storev = db_rbt_storev;
rec.delete_rec = db_rbt_delete;
db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);