summaryrefslogtreecommitdiff
path: root/source3/lib/ldb/ldb_tdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2006-10-21 00:10:19 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:15:35 -0500
commit7a390a0dabcdadb30196662b6cdec512bf81dcb4 (patch)
tree8ed126e072e4446ad47d25f277059af5ccd556cc /source3/lib/ldb/ldb_tdb
parentaa3ca346d82da2501406cc1f482643b20905e467 (diff)
downloadsamba-7a390a0dabcdadb30196662b6cdec512bf81dcb4.tar.gz
samba-7a390a0dabcdadb30196662b6cdec512bf81dcb4.tar.bz2
samba-7a390a0dabcdadb30196662b6cdec512bf81dcb4.zip
r19430: merge recent ldb changes from Samba4. This includes memory leak fixes
and significant speedups (This used to be commit bb5c205fef90aa8b89ba400fb9f2f37a111676a8)
Diffstat (limited to 'source3/lib/ldb/ldb_tdb')
-rw-r--r--source3/lib/ldb/ldb_tdb/ldb_cache.c33
-rw-r--r--source3/lib/ldb/ldb_tdb/ldb_index.c12
-rw-r--r--source3/lib/ldb/ldb_tdb/ldb_search.c24
-rw-r--r--source3/lib/ldb/ldb_tdb/ldb_tdb.c27
-rw-r--r--source3/lib/ldb/ldb_tdb/ldb_tdb.h8
5 files changed, 50 insertions, 54 deletions
diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c
index a6092c45f9..467f1ac34d 100644
--- a/source3/lib/ldb/ldb_tdb/ldb_cache.c
+++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c
@@ -71,13 +71,7 @@ static void ltdb_attributes_unload(struct ldb_module *module)
msg = ltdb->cache->attributes;
for (i=0;i<msg->num_elements;i++) {
- const struct ldb_attrib_handler *h;
- /* this is rather ugly - a consequence of const handling */
- h = ldb_attrib_handler(module->ldb, msg->elements[i].name);
ldb_remove_attrib_handler(module->ldb, msg->elements[i].name);
- if (strcmp(h->attr, msg->elements[i].name) == 0) {
- talloc_steal(msg, h->attr);
- }
}
talloc_free(ltdb->cache->attributes);
@@ -163,7 +157,8 @@ static int ltdb_attributes_load(struct ldb_module *module)
goto failed;
}
h2 = *h;
- h2.attr = talloc_strdup(module, msg->elements[i].name);
+ h2.attr = msg->elements[i].name;
+ h2.flags |= LDB_ATTR_FLAG_ALLOCATED;
if (ldb_set_attrib_handlers(module->ldb, &h2, 1) != 0) {
goto failed;
}
@@ -319,6 +314,13 @@ int ltdb_cache_load(struct ldb_module *module)
struct ldb_dn *baseinfo_dn = NULL;
struct ldb_dn *indexlist_dn = NULL;
uint64_t seq;
+ struct ldb_message *baseinfo;
+
+ /* a very fast check to avoid extra database reads */
+ if (ltdb->cache != NULL &&
+ tdb_get_seqnum(ltdb->tdb) == ltdb->tdb_seqnum) {
+ return 0;
+ }
if (ltdb->cache == NULL) {
ltdb->cache = talloc_zero(ltdb, struct ltdb_cache);
@@ -333,30 +335,31 @@ int ltdb_cache_load(struct ldb_module *module)
}
}
- talloc_free(ltdb->cache->baseinfo);
- ltdb->cache->baseinfo = talloc(ltdb->cache, struct ldb_message);
- if (ltdb->cache->baseinfo == NULL) goto failed;
+ baseinfo = talloc(ltdb->cache, struct ldb_message);
+ if (baseinfo == NULL) goto failed;
baseinfo_dn = ldb_dn_explode(module->ldb, LTDB_BASEINFO);
if (baseinfo_dn == NULL) goto failed;
- if (ltdb_search_dn1(module, baseinfo_dn, ltdb->cache->baseinfo) == -1) {
+ if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) == -1) {
goto failed;
}
/* possibly initialise the baseinfo */
- if (!ltdb->cache->baseinfo->dn) {
+ if (!baseinfo->dn) {
if (ltdb_baseinfo_init(module) != 0) {
goto failed;
}
- if (ltdb_search_dn1(module, baseinfo_dn, ltdb->cache->baseinfo) != 1) {
+ if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) != 1) {
goto failed;
}
}
+ ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb);
+
/* if the current internal sequence number is the same as the one
in the database then assume the rest of the cache is OK */
- seq = ldb_msg_find_attr_as_uint64(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0);
+ seq = ldb_msg_find_attr_as_uint64(baseinfo, LTDB_SEQUENCE_NUMBER, 0);
if (seq == ltdb->sequence_number) {
goto done;
}
@@ -395,11 +398,13 @@ int ltdb_cache_load(struct ldb_module *module)
}
done:
+ talloc_free(baseinfo);
talloc_free(baseinfo_dn);
talloc_free(indexlist_dn);
return 0;
failed:
+ talloc_free(baseinfo);
talloc_free(baseinfo_dn);
talloc_free(indexlist_dn);
return -1;
diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c
index 8a9a82a98c..0c9d1f33a1 100644
--- a/source3/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source3/lib/ldb/ldb_tdb/ldb_index.c
@@ -1030,6 +1030,12 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg)
char *dn;
unsigned int i, j;
+ /* find the list of indexed fields */
+ if (ltdb->cache->indexlist->num_elements == 0) {
+ /* no indexed fields */
+ return 0;
+ }
+
if (ldb_dn_is_special(msg->dn)) {
return 0;
}
@@ -1039,12 +1045,6 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg)
return -1;
}
- /* find the list of indexed fields */
- if (ltdb->cache->indexlist->num_elements == 0) {
- /* no indexed fields */
- return 0;
- }
-
for (i = 0; i < msg->num_elements; i++) {
ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name,
NULL, LTDB_IDXATTR);
diff --git a/source3/lib/ldb/ldb_tdb/ldb_search.c b/source3/lib/ldb/ldb_tdb/ldb_search.c
index 7cdb2b672f..4b76c437b6 100644
--- a/source3/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source3/lib/ldb/ldb_tdb/ldb_search.c
@@ -248,25 +248,13 @@ int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct l
return 1;
}
-/* the lock key for search locking. Note that this is not a DN, its
- just an arbitrary key to give to tdb. Also note that as we and
- using transactions for all write operations and transactions take
- care of their own locks, we don't need to do any locking anywhere
- other than in ldb_search() */
-#define LDBLOCK "INT_LDBLOCK"
-
/*
lock the database for read - use by ltdb_search
*/
static int ltdb_lock_read(struct ldb_module *module)
{
struct ltdb_private *ltdb = module->private_data;
- TDB_DATA key;
-
- key.dptr = discard_const(LDBLOCK);
- key.dsize = strlen(LDBLOCK);
-
- return tdb_chainlock_read(ltdb->tdb, key);
+ return tdb_lockall_read(ltdb->tdb);
}
/*
@@ -275,12 +263,7 @@ static int ltdb_lock_read(struct ldb_module *module)
static int ltdb_unlock_read(struct ldb_module *module)
{
struct ltdb_private *ltdb = module->private_data;
- TDB_DATA key;
-
- key.dptr = discard_const(LDBLOCK);
- key.dsize = strlen(LDBLOCK);
-
- return tdb_chainunlock_read(ltdb->tdb, key);
+ return tdb_unlockall_read(ltdb->tdb);
}
/*
@@ -499,12 +482,11 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)
return LDB_ERR_OPERATIONS_ERROR;
}
- req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
+ req->handle = init_ltdb_handle(ltdb, module, req);
if (req->handle == NULL) {
ltdb_unlock_read(module);
return LDB_ERR_OPERATIONS_ERROR;
}
-
ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
ltdb_ac->tree = req->op.search.tree;
diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c
index 608120e3a7..3f9db39097 100644
--- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -79,13 +79,12 @@ static int ltdb_err_map(enum TDB_ERROR tdb_code)
struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module,
- void *context,
- int (*callback)(struct ldb_context *, void *, struct ldb_reply *))
+ struct ldb_request *req)
{
struct ltdb_context *ac;
struct ldb_handle *h;
- h = talloc_zero(ltdb, struct ldb_handle);
+ h = talloc_zero(req, struct ldb_handle);
if (h == NULL) {
ldb_set_errstring(module->ldb, "Out of Memory");
return NULL;
@@ -106,8 +105,8 @@ struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module
h->status = LDB_SUCCESS;
ac->module = module;
- ac->context = context;
- ac->callback = callback;
+ ac->context = req->context;
+ ac->callback = req->callback;
return h;
}
@@ -307,7 +306,7 @@ static int ltdb_add(struct ldb_module *module, struct ldb_request *req)
}
}
- req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
+ req->handle = init_ltdb_handle(ltdb, module, req);
if (req->handle == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -387,6 +386,7 @@ static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *
ret = ltdb_modified(module, dn);
if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -416,7 +416,7 @@ static int ltdb_delete(struct ldb_module *module, struct ldb_request *req)
return LDB_ERR_OPERATIONS_ERROR;
}
- req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
+ req->handle = init_ltdb_handle(ltdb, module, req);
if (req->handle == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -772,7 +772,7 @@ static int ltdb_modify(struct ldb_module *module, struct ldb_request *req)
req->handle = NULL;
- req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
+ req->handle = init_ltdb_handle(ltdb, module, req);
if (req->handle == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -826,7 +826,7 @@ static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)
return LDB_ERR_OPERATIONS_ERROR;
}
- req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
+ req->handle = init_ltdb_handle(ltdb, module, req);
if (req->handle == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1021,7 +1021,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
path = url;
}
- tdb_flags = TDB_DEFAULT;
+ tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
/* check for the 'nosync' option */
if (flags & LDB_FLG_NOSYNC) {
@@ -1058,11 +1058,18 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
talloc_free(ltdb);
return -1;
}
+ talloc_set_name_const(*module, "ldb_tdb backend");
(*module)->ldb = ldb;
(*module)->prev = (*module)->next = NULL;
(*module)->private_data = ltdb;
(*module)->ops = &ltdb_ops;
+ if (ltdb_cache_load(*module) != 0) {
+ talloc_free(*module);
+ talloc_free(ltdb);
+ return -1;
+ }
+
return 0;
}
diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.h b/source3/lib/ldb/ldb_tdb/ldb_tdb.h
index 670d3b6801..42f3dc2421 100644
--- a/source3/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -21,8 +21,11 @@ struct ltdb_private {
handling. It has plenty of digits of precision */
unsigned long long sequence_number;
+ /* the low level tdb seqnum - used to avoid loading BASEINFO when
+ possible */
+ int tdb_seqnum;
+
struct ltdb_cache {
- struct ldb_message *baseinfo;
struct ldb_message *indexlist;
struct ldb_message *attributes;
struct ldb_message *subclasses;
@@ -110,8 +113,7 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req);
/* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */
struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module,
- void *context,
- int (*callback)(struct ldb_context *, void *, struct ldb_reply *));
+ struct ldb_request *req);
struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn);
int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs);
int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn);