From 0906096ee4fbca6338863319edb68cfe338fd6a3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Oct 2007 02:03:21 +0200 Subject: r25690: - only use a readonly traverse in ldb_search when not in a transaction. When we are in a transaction then we could be in a top level modify operation (such as rename), so we must use a writeable traverse so that the async callbacks can do the modifies while the search is progressing. - don't do the lockall operation on the tdb during a ldb search if in a transaction, as this would prevent modifies by callbacks as well (This used to be commit aa9ab431e071882f42ebc882e809ae1d4b8778d4) --- source4/lib/ldb/ldb_tdb/ldb_search.c | 16 +++++++++++++--- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 6 ++++++ source4/lib/ldb/ldb_tdb/ldb_tdb.h | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) (limited to 'source4/lib') diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index a195a39391..8151b458d4 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -253,7 +253,10 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes static int ltdb_lock_read(struct ldb_module *module) { struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; - return tdb_lockall_read(ltdb->tdb); + if (ltdb->in_transaction == 0) { + return tdb_lockall_read(ltdb->tdb); + } + return 0; } /* @@ -262,7 +265,10 @@ static int ltdb_lock_read(struct ldb_module *module) static int ltdb_unlock_read(struct ldb_module *module) { struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; - return tdb_unlockall_read(ltdb->tdb); + if (ltdb->in_transaction == 0) { + return tdb_unlockall_read(ltdb->tdb); + } + return 0; } /* @@ -442,7 +448,11 @@ static int ltdb_search_full(struct ldb_handle *handle) struct ltdb_private *ltdb = talloc_get_type(ac->module->private_data, struct ltdb_private); int ret; - ret = tdb_traverse_read(ltdb->tdb, search_func, handle); + if (ltdb->in_transaction != 0) { + ret = tdb_traverse(ltdb->tdb, search_func, handle); + } else { + ret = tdb_traverse_read(ltdb->tdb, search_func, handle); + } if (ret == -1) { handle->status = LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 3461f98d5f..949164a505 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -907,6 +907,8 @@ static int ltdb_start_trans(struct ldb_module *module) return ltdb_err_map(tdb_error(ltdb->tdb)); } + ltdb->in_transaction++; + return LDB_SUCCESS; } @@ -915,6 +917,8 @@ static int ltdb_end_trans(struct ldb_module *module) struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); + ltdb->in_transaction--; + if (tdb_transaction_commit(ltdb->tdb) != 0) { return ltdb_err_map(tdb_error(ltdb->tdb)); } @@ -927,6 +931,8 @@ static int ltdb_del_trans(struct ldb_module *module) struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); + ltdb->in_transaction--; + if (tdb_transaction_cancel(ltdb->tdb) != 0) { return ltdb_err_map(tdb_error(ltdb->tdb)); } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index d4a8ff2fb1..b5e6472054 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -27,6 +27,8 @@ struct ltdb_private { int flags; } last_attribute; } *cache; + + int in_transaction; }; /* -- cgit