ldap/servers/slapd/back-ldbm/back-ldbm.h | 6 +- ldap/servers/slapd/back-ldbm/dblayer.c | 6 +- ldap/servers/slapd/back-ldbm/filterindex.c | 43 +++++++++++++------ ldap/servers/slapd/back-ldbm/instance.c | 6 +- ldap/servers/slapd/back-ldbm/ldbm_add.c | 22 +++++++--- ldap/servers/slapd/back-ldbm/ldbm_bind.c | 4 + ldap/servers/slapd/back-ldbm/ldbm_compare.c | 4 + ldap/servers/slapd/back-ldbm/ldbm_delete.c | 7 ++- ldap/servers/slapd/back-ldbm/ldbm_modify.c | 21 +++++++-- ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 37 +++++++++++----- ldap/servers/slapd/back-ldbm/ldbm_search.c | 28 ++++++++---- ldap/servers/slapd/back-ldbm/misc.c | 6 +- ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 3 + ldap/servers/slapd/back-ldbm/sort.c | 6 +- ldap/servers/slapd/back-ldbm/vlv.c | 55 +++++++++++++++++-------- ldap/servers/slapd/back-ldbm/vlv_srch.c | 4 + 16 files changed, 180 insertions(+), 78 deletions(-)
New commits: commit 6120b3d50ad10b00e98e517e5947e3e3d5ea3652 Author: Rich Megginson rmeggins@redhat.com Date: Thu Sep 15 14:16:12 2011 -0600
Make all backend operations transaction aware
All backend functions will use the parent transaction (if any) to perform all database read/write operations, and for the creation of nested transactions. The pseudocode looks like this: begin operation grab parent txn from pblock SLAPI_TXN and save to a local variable use this parent txn to perform any searches or other ops before the nested txn is created (if created - search ops do not do this) create the nested txn (if a write op) using the parent_txn stash the new txn in the pblock SLAPI_TXN call the betxnpreop plugins perform the backend ops inside the txn call the betxnpostop plugins commit the nested txn restore the saved parent_txn to the pblock SLAPI_TXN upon failure, abort the nested txn and restore the saved parent_txn to the pblock SLAPI_TXN
There were a few api changes to allow the txn to be passed in wherever it is needed. The database lock was changed from a mutex to a monitor to allow plugins to call other plugins inside the same parent transaction. Reviewed by: nhosoi (Thanks!)
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index adf593e..f9939d4 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -729,8 +729,10 @@ typedef struct ldbm_instance { * parent of the instance name dir */ char *inst_parent_dir_name; /* Absolute parent dir for this inst */
- PRLock *inst_db_mutex; /* Used to synchronize modify operations - * on this instance. */ + PRMonitor *inst_db_mutex; /* Used to synchronize write operations + * on this instance - the monitor is re-entrant + * which allows plugins in the same transaction + * to share the lock */
dblayer_handle *inst_handle_head; /* These are used to maintain a list */ dblayer_handle *inst_handle_tail; /* of open db handles for this instance */ diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index b158311..0e5804c 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -639,7 +639,7 @@ int dblayer_terminate(struct ldbminfo *li) inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) { inst = (ldbm_instance *)object_get_data(inst_obj); if (NULL != inst->inst_db_mutex) { - PR_DestroyLock(inst->inst_db_mutex); + PR_DestroyMonitor(inst->inst_db_mutex); inst->inst_db_mutex = NULL; } if (NULL != inst->inst_handle_list_mutex) { @@ -3564,7 +3564,7 @@ void dblayer_lock_backend(backend *be) PR_ASSERT(NULL != inst);
if (NULL != inst->inst_db_mutex) { - PR_Lock(inst->inst_db_mutex); + PR_EnterMonitor(inst->inst_db_mutex); } }
@@ -3577,7 +3577,7 @@ void dblayer_unlock_backend(backend *be) PR_ASSERT(NULL != inst);
if (NULL != inst->inst_db_mutex) { - PR_Unlock(inst->inst_db_mutex); + PR_ExitMonitor(inst->inst_db_mutex); } }
diff --git a/ldap/servers/slapd/back-ldbm/filterindex.c b/ldap/servers/slapd/back-ldbm/filterindex.c index e237749..eacb6ef 100644 --- a/ldap/servers/slapd/back-ldbm/filterindex.c +++ b/ldap/servers/slapd/back-ldbm/filterindex.c @@ -71,7 +71,8 @@ keys2idl( const char *indextype, Slapi_Value **ivals, int *err, - int *unindexed + int *unindexed, + back_txn *txn );
IDList * @@ -100,11 +101,13 @@ filter_candidates( }
if (li->li_use_vlv) { + back_txn txn = {NULL}; /* first, check to see if this particular filter node matches any * vlv indexes we're keeping. if so, we can use that index * instead. */ - result = vlv_find_index_by_filter(be, base, f); + slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); + result = vlv_find_index_by_filter_txn(be, base, f, &txn); if (result) { LDAPDebug( LDAP_DEBUG_TRACE, "<= filter_candidates %lu (vlv)\n", (u_long)IDL_NIDS(result), 0, 0 ); @@ -197,6 +200,7 @@ ava_candidates( IDList *idl = NULL; int unindexed = 0; Slapi_Attr sattr; + back_txn txn = {NULL};
LDAPDebug( LDAP_DEBUG_TRACE, "=> ava_candidates\n", 0, 0, 0 );
@@ -270,6 +274,7 @@ ava_candidates( * reset ivals[0]->bv.bv_val) or alloc an entirely new ivals array. */
+ slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); if(ftype==LDAP_FILTER_EQUALITY) { Slapi_Value tmp, *ptr[2], fake; char buf[1024]; @@ -283,7 +288,7 @@ ava_candidates( ivals=ptr;
slapi_attr_assertion2keys_ava_sv( &sattr, &tmp, (Slapi_Value ***)&ivals, LDAP_FILTER_EQUALITY_FAST); - idl = keys2idl( be, type, indextype, ivals, err, &unindexed ); + idl = keys2idl( be, type, indextype, ivals, err, &unindexed, &txn ); if ( unindexed ) { unsigned int opnote = SLAPI_OP_NOTE_UNINDEXED; slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote ); @@ -315,7 +320,7 @@ ava_candidates( idl = idl_allids( be ); goto done; } - idl = keys2idl( be, type, indextype, ivals, err, &unindexed ); + idl = keys2idl( be, type, indextype, ivals, err, &unindexed, &txn ); if ( unindexed ) { unsigned int opnote = SLAPI_OP_NOTE_UNINDEXED; slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote ); @@ -341,6 +346,7 @@ presence_candidates( char *type; IDList *idl; int unindexed = 0; + back_txn txn = {NULL};
LDAPDebug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 );
@@ -349,8 +355,9 @@ presence_candidates( 0, 0, 0 ); return( NULL ); } + slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); idl = index_read_ext( be, type, indextype_PRESENCE, - NULL, NULL, err, &unindexed ); + NULL, &txn, err, &unindexed );
if ( unindexed ) { unsigned int opnote = SLAPI_OP_NOTE_UNINDEXED; @@ -366,7 +373,7 @@ presence_candidates( idl_free(idl); idl = index_range_read(pb, be, type, indextype_EQUALITY, SLAPI_OP_GREATER_OR_EQUAL, - NULL, NULL, 0, NULL, err); + NULL, NULL, 0, &txn, err); }
LDAPDebug( LDAP_DEBUG_TRACE, "<= presence_candidates %lu\n", @@ -386,7 +393,9 @@ extensible_candidates( Slapi_PBlock* pb = slapi_pblock_new(); int mrOP = 0; Slapi_Operation *op = NULL; + back_txn txn = {NULL}; LDAPDebug (LDAP_DEBUG_TRACE, "=> extensible_candidates\n", 0, 0, 0); + slapi_pblock_get(glob_pb, SLAPI_TXN, &txn.back_txn_txn); if ( ! slapi_mr_filter_index (f, pb) && !slapi_pblock_get (pb, SLAPI_PLUGIN_MR_QUERY_OPERATOR, &mrOP)) { switch (mrOP) @@ -453,10 +462,10 @@ extensible_candidates( { int unindexed = 0; IDList* idl3 = (mrOP == SLAPI_OP_EQUAL) ? - index_read_ext(be, mrTYPE, mrOID, *key, NULL, + index_read_ext(be, mrTYPE, mrOID, *key, &txn, err, &unindexed) : index_range_read (pb, be, mrTYPE, mrOID, mrOP, - *key, NULL, 0, NULL, err); + *key, NULL, 0, &txn, err); if ( unindexed ) { unsigned int opnote = SLAPI_OP_NOTE_UNINDEXED; slapi_pblock_set( glob_pb, @@ -534,9 +543,12 @@ range_candidates( IDList *idl = NULL; struct berval *low = NULL, *high = NULL; struct berval **lows = NULL, **highs = NULL; + back_txn txn = {NULL};
LDAPDebug(LDAP_DEBUG_TRACE, "=> range_candidates attr=%s\n", type, 0, 0);
+ slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); + if (low_val != NULL) { slapi_attr_assertion2keys_ava(sattr, low_val, &lows, LDAP_FILTER_EQUALITY); if (lows == NULL || *lows == NULL) { @@ -562,15 +574,15 @@ range_candidates( if (low == NULL) { idl = index_range_read(pb, be, type, (char*)indextype_EQUALITY, SLAPI_OP_LESS_OR_EQUAL, - high, NULL, 0, NULL, err); + high, NULL, 0, &txn, err); } else if (high == NULL) { idl = index_range_read(pb, be, type, (char*)indextype_EQUALITY, SLAPI_OP_GREATER_OR_EQUAL, - low, NULL, 0, NULL, err); + low, NULL, 0, &txn, err); } else { idl = index_range_read(pb, be, type, (char*)indextype_EQUALITY, SLAPI_OP_GREATER_OR_EQUAL, - low, high, 1, NULL, err); + low, high, 1, &txn, err); }
done: @@ -850,6 +862,7 @@ substring_candidates( int unindexed = 0; unsigned int opnote = SLAPI_OP_NOTE_UNINDEXED; Slapi_Attr sattr; + back_txn txn = {NULL};
LDAPDebug( LDAP_DEBUG_TRACE, "=> sub_candidates\n", 0, 0, 0 );
@@ -878,7 +891,8 @@ substring_candidates( * look up each key in the index, ANDing the resulting * IDLists together. */ - idl = keys2idl( be, type, indextype_SUB, ivals, err, &unindexed ); + slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); + idl = keys2idl( be, type, indextype_SUB, ivals, err, &unindexed, &txn ); if ( unindexed ) { slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote ); pagedresults_set_unindexed( pb->pb_conn ); @@ -897,7 +911,8 @@ keys2idl( const char *indextype, Slapi_Value **ivals, int *err, - int *unindexed + int *unindexed, + back_txn *txn ) { IDList *idl; @@ -909,7 +924,7 @@ keys2idl( for ( i = 0; ivals[i] != NULL; i++ ) { IDList *idl2;
- idl2 = index_read_ext( be, type, indextype, slapi_value_get_berval(ivals[i]), NULL, err, unindexed ); + idl2 = index_read_ext( be, type, indextype, slapi_value_get_berval(ivals[i]), txn, err, unindexed );
#ifdef LDAP_DEBUG /* XXX if ( slapd_ldap_debug & LDAP_DEBUG_TRACE ) { XXX */ diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c index 7e5a4cd..74a01a8 100644 --- a/ldap/servers/slapd/back-ldbm/instance.c +++ b/ldap/servers/slapd/back-ldbm/instance.c @@ -95,9 +95,9 @@ int ldbm_instance_create(backend *be, char *name) }
/* Lock used to synchronize modify operations. */ - inst->inst_db_mutex = PR_NewLock(); + inst->inst_db_mutex = PR_NewMonitor(); if (NULL == inst->inst_db_mutex) { - LDAPDebug(LDAP_DEBUG_ANY, "ldbm_instance_create: PR_NewLock failed\n", + LDAPDebug(LDAP_DEBUG_ANY, "ldbm_instance_create: PR_NewMonitor failed\n", 0, 0, 0); rc = -1; goto error; @@ -385,7 +385,7 @@ ldbm_instance_destructor(void **arg) PR_DestroyLock(inst->inst_config_mutex); slapi_ch_free_string(&inst->inst_dir_name); slapi_ch_free_string(&inst->inst_parent_dir_name); - PR_DestroyLock(inst->inst_db_mutex); + PR_DestroyMonitor(inst->inst_db_mutex); PR_DestroyLock(inst->inst_handle_list_mutex); PR_DestroyLock(inst->inst_nextid_mutex); PR_DestroyCondVar(inst->inst_indexer_cv); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c index 274e3d7..5ade337 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_add.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c @@ -121,7 +121,7 @@ ldbm_back_add( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ); slapi_pblock_get( pb, SLAPI_REQUESTOR_ISROOT, &isroot ); slapi_pblock_get( pb, SLAPI_MANAGEDSAIT, &managedsait ); - slapi_pblock_get( pb, SLAPI_PARENT_TXN, (void**)&parent_txn ); + slapi_pblock_get( pb, SLAPI_TXN, (void**)&parent_txn ); slapi_pblock_get( pb, SLAPI_OPERATION, &operation ); slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation ); slapi_pblock_get( pb, SLAPI_BACKEND, &be); @@ -142,6 +142,9 @@ ldbm_back_add( Slapi_PBlock *pb ) slapi_entry_delete_values( e, numsubordinates, NULL );
dblayer_txn_init(li,&txn); + /* the calls to get_copy_of_entry require the parent txn if any + so set txn to the parent_txn until we begin the child transaction */ + txn.back_txn_txn = parent_txn;
/* The dblock serializes writes to the database, * which reduces deadlocking in the db code, @@ -354,7 +357,7 @@ ldbm_back_add( Slapi_PBlock *pb ) */ addr.dn = addr.udn = NULL; addr.uniqueid = (char *)slapi_entry_get_uniqueid(e); /* jcm - cast away const */ - tombstoneentry = find_entry2modify( pb, be, &addr, NULL ); + tombstoneentry = find_entry2modify( pb, be, &addr, &txn ); if ( tombstoneentry==NULL ) { ldap_result_code= -1; @@ -647,10 +650,13 @@ ldbm_back_add( Slapi_PBlock *pb ) * So, we believe that no code up till here actually added anything * to persistent store. From now on, we're transacted */ - + txn.back_txn_txn = NULL; /* ready to create the child transaction */ for (retry_count = 0; retry_count < RETRY_TIMES; retry_count++) { if (retry_count > 0) { dblayer_txn_abort(li,&txn); + /* txn is no longer valid - reset slapi_txn to the parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); /* We're re-trying */ LDAPDebug( LDAP_DEBUG_TRACE, "Add Retrying Transaction\n", 0, 0, 0 ); #ifndef LDBM_NO_BACKOFF_DELAY @@ -672,8 +678,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto error_return; }
- /* stash the transaction */ - slapi_pblock_set(pb, SLAPI_TXN, (void *)txn.back_txn_txn); + /* stash the transaction for plugins */ + slapi_pblock_set(pb, SLAPI_TXN, txn.back_txn_txn);
/* call the transaction pre add plugins just after creating the transaction */ if ((retval = plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN))) { @@ -904,6 +910,9 @@ ldbm_back_add( Slapi_PBlock *pb ) }
retval = dblayer_txn_commit(li,&txn); + /* after commit - txn is no longer valid - replace SLAPI_TXN with parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); if (0 != retval) { ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count); @@ -950,6 +959,9 @@ diskfull_return: /* It is safer not to abort when the transaction is not started. */ if (retry_count > 0) { dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + /* txn is no longer valid - reset the txn pointer to the parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); } rc= SLAPI_FAIL_GENERAL; } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c index c9ba5db..49b2cca 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c @@ -210,6 +210,7 @@ ldbm_back_bind( Slapi_PBlock *pb ) Slapi_Attr *attr; Slapi_Value **bvals; entry_address *addr; + back_txn txn = {NULL};
/* get parameters */ slapi_pblock_get( pb, SLAPI_BACKEND, &be ); @@ -217,6 +218,7 @@ ldbm_back_bind( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_TARGET_ADDRESS, &addr ); slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method ); slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &cred ); + slapi_pblock_get( pb, SLAPI_TXN, &txn.back_txn_txn ); inst = (ldbm_instance *) be->be_instance_info;
@@ -229,7 +231,7 @@ ldbm_back_bind( Slapi_PBlock *pb ) * find the target entry. find_entry() takes care of referrals * and sending errors if the entry does not exist. */ - if (( e = find_entry( pb, be, addr, NULL /* no txn */ )) == NULL ) { + if (( e = find_entry( pb, be, addr, &txn )) == NULL ) { return( SLAPI_BIND_FAIL ); }
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_compare.c b/ldap/servers/slapd/back-ldbm/ldbm_compare.c index 5deb688..b510a08 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_compare.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_compare.c @@ -59,6 +59,7 @@ ldbm_back_compare( Slapi_PBlock *pb ) int result; int ret = 0; Slapi_DN *namespace_dn; + back_txn txn = {NULL};
slapi_pblock_get( pb, SLAPI_BACKEND, &be ); @@ -66,12 +67,13 @@ ldbm_back_compare( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_TARGET_ADDRESS, &addr); slapi_pblock_get( pb, SLAPI_COMPARE_TYPE, &type ); slapi_pblock_get( pb, SLAPI_COMPARE_VALUE, &bval ); + slapi_pblock_get( pb, SLAPI_TXN, &txn.back_txn_txn ); inst = (ldbm_instance *) be->be_instance_info; /* get the namespace dn */ namespace_dn = (Slapi_DN*)slapi_be_getsuffix(be, 0);
- if ( (e = find_entry( pb, be, addr, NULL )) == NULL ) { + if ( (e = find_entry( pb, be, addr, &txn )) == NULL ) { return( -1 ); /* error result sent by find_entry() */ }
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c index 088d1b5..10f8f68 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c @@ -99,7 +99,7 @@ ldbm_back_delete( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); slapi_pblock_get( pb, SLAPI_DELETE_TARGET, &dn ); slapi_pblock_get( pb, SLAPI_TARGET_ADDRESS, &addr); - slapi_pblock_get( pb, SLAPI_PARENT_TXN, (void**)&parent_txn ); + slapi_pblock_get( pb, SLAPI_TXN, (void**)&parent_txn ); slapi_pblock_get( pb, SLAPI_OPERATION, &operation ); slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation ); @@ -108,6 +108,9 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* dblayer_txn_init needs to be called before "goto error_return" */ dblayer_txn_init(li,&txn); + /* the calls to perform searches require the parent txn if any + so set txn to the parent_txn until we begin the child transaction */ + txn.back_txn_txn = parent_txn;
if (pb->pb_conn) { @@ -165,7 +168,7 @@ ldbm_back_delete( Slapi_PBlock *pb ) }
/* find and lock the entry we are about to modify */ - if ( (e = find_entry2modify( pb, be, addr, NULL )) == NULL ) + if ( (e = find_entry2modify( pb, be, addr, &txn )) == NULL ) { ldap_result_code= LDAP_NO_SUCH_OBJECT; /* retval is -1 */ diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c index 9dbf2b9..ff2fc97 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c @@ -223,7 +223,7 @@ ldbm_back_modify( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); slapi_pblock_get( pb, SLAPI_TARGET_ADDRESS, &addr ); slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods ); - slapi_pblock_get( pb, SLAPI_PARENT_TXN, (void**)&parent_txn ); + slapi_pblock_get( pb, SLAPI_TXN, (void**)&parent_txn );
slapi_pblock_get( pb, SLAPI_OPERATION, &operation ); if (NULL == operation) @@ -237,6 +237,9 @@ ldbm_back_modify( Slapi_PBlock *pb ) inst = (ldbm_instance *) be->be_instance_info;
dblayer_txn_init(li,&txn); + /* the calls to search for entries require the parent txn if any + so set txn to the parent_txn until we begin the child transaction */ + txn.back_txn_txn = parent_txn; if (NULL == addr) { goto error_return; @@ -263,7 +266,7 @@ ldbm_back_modify( Slapi_PBlock *pb ) }
/* find and lock the entry we are about to modify */ - if ( (e = find_entry2modify( pb, be, addr, NULL )) == NULL ) { + if ( (e = find_entry2modify( pb, be, addr, &txn )) == NULL ) { ldap_result_code= -1; goto error_return; /* error result sent by find_entry2modify() */ } @@ -399,10 +402,14 @@ ldbm_back_modify( Slapi_PBlock *pb ) } }
+ txn.back_txn_txn = NULL; /* ready to create the child transaction */ for (retry_count = 0; retry_count < RETRY_TIMES; retry_count++) {
if (retry_count > 0) { dblayer_txn_abort(li,&txn); + /* txn is no longer valid - reset slapi_txn to the parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); LDAPDebug( LDAP_DEBUG_TRACE, "Modify Retrying Transaction\n", 0, 0, 0 ); #ifndef LDBM_NO_BACKOFF_DELAY { @@ -422,8 +429,8 @@ ldbm_back_modify( Slapi_PBlock *pb ) goto error_return; }
- /* stash the transaction */ - slapi_pblock_set(pb, SLAPI_TXN, (void *)txn.back_txn_txn); + /* stash the transaction for plugins */ + slapi_pblock_set(pb, SLAPI_TXN, txn.back_txn_txn);
/* call the transaction pre modify plugins just after creating the transaction */ if ((retval = plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN))) { @@ -557,6 +564,9 @@ ldbm_back_modify( Slapi_PBlock *pb ) }
retval = dblayer_txn_commit(li,&txn); + /* after commit - txn is no longer valid - replace SLAPI_TXN with parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); if (0 != retval) { if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; ldap_result_code= LDAP_OPERATIONS_ERROR; @@ -599,6 +609,9 @@ error_return: if (retry_count > 0) { /* It is safer not to abort when the transaction is not started. */ dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + /* txn is no longer valid - reset the txn pointer to the parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); } rc= SLAPI_FAIL_GENERAL; } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c index be5787a..4aa771f 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c @@ -120,7 +120,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_MODRDN_TARGET, &dn ); slapi_pblock_get( pb, SLAPI_BACKEND, &be); slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); - slapi_pblock_get( pb, SLAPI_PARENT_TXN, (void**)&parent_txn ); + slapi_pblock_get( pb, SLAPI_TXN, (void**)&parent_txn ); slapi_pblock_get( pb, SLAPI_REQUESTOR_ISROOT, &isroot ); slapi_pblock_get( pb, SLAPI_OPERATION, &operation ); slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation ); @@ -129,6 +129,9 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/* dblayer_txn_init needs to be called before "goto error_return" */ dblayer_txn_init(li,&txn); + /* the calls to search for entries require the parent txn if any + so set txn to the parent_txn until we begin the child transaction */ + txn.back_txn_txn = parent_txn;
if (pb->pb_conn) { @@ -313,7 +316,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) /* find and lock the entry we are about to modify */ /* JCMREPL - Argh, what happens about the stinking referrals? */ slapi_pblock_get (pb, SLAPI_TARGET_ADDRESS, &old_addr); - e = find_entry2modify( pb, be, old_addr, NULL ); + e = find_entry2modify( pb, be, old_addr, &txn ); if ( e == NULL ) { ldap_result_code= -1; @@ -336,14 +339,14 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) /* Fetch and lock the parent of the entry that is moving */ oldparent_addr.dn = (char*)slapi_sdn_get_dn (&dn_parentdn); oldparent_addr.uniqueid = NULL; - parententry = find_entry2modify_only( pb, be, &oldparent_addr, NULL ); + parententry = find_entry2modify_only( pb, be, &oldparent_addr, &txn ); modify_init(&parent_modify_context,parententry);
/* Fetch and lock the new parent of the entry that is moving */ if(slapi_sdn_get_ndn(&dn_newsuperiordn)!=NULL) { slapi_pblock_get (pb, SLAPI_MODRDN_NEWSUPERIOR_ADDRESS, &newsuperior_addr); - newparententry = find_entry2modify_only( pb, be, newsuperior_addr, NULL); + newparententry = find_entry2modify_only( pb, be, newsuperior_addr, &txn ); modify_init(&newparent_modify_context,newparententry); }
@@ -680,11 +683,15 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) * So, we believe that no code up till here actually added anything * to persistent store. From now on, we're transacted */ + txn.back_txn_txn = NULL; /* ready to create the child transaction */ for (retry_count = 0; retry_count < RETRY_TIMES; retry_count++) { if (retry_count > 0) { dblayer_txn_abort(li,&txn); + /* txn is no longer valid - reset slapi_txn to the parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); /* We're re-trying */ LDAPDebug( LDAP_DEBUG_TRACE, "Modrdn Retrying Transaction\n", 0, 0, 0 ); } @@ -909,15 +916,18 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) modify_switch_entries( &newparent_modify_context,be); }
- /* call the transaction post modrdn plugins just before the commit */ - if ((retval = plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN))) { - LDAPDebug1Arg( LDAP_DEBUG_ANY, "SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN plugin " - "returned error code %d\n", retval ); - slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code); - goto error_return; - } + /* call the transaction post modrdn plugins just before the commit */ + if ((retval = plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN))) { + LDAPDebug1Arg( LDAP_DEBUG_ANY, "SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN plugin " + "returned error code %d\n", retval ); + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code); + goto error_return; + }
retval = dblayer_txn_commit(li,&txn); + /* after commit - txn is no longer valid - replace SLAPI_TXN with parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); if (0 != retval) { if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; @@ -1047,6 +1057,9 @@ error_return: /* It is safer not to abort when the transaction is not started. */ if (retry_count > 0) { dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + /* txn is no longer valid - reset the txn pointer to the parent */ + txn.back_txn_txn = NULL; + slapi_pblock_set(pb, SLAPI_TXN, parent_txn); } retval= SLAPI_FAIL_GENERAL; } @@ -1737,7 +1750,7 @@ moddn_get_children(back_txn *ptxn, if ( id!=NOID ) { int err= 0; - e = id2entry( be, id, NULL, &err ); + e = id2entry( be, id, ptxn, &err ); if (e!=NULL) { /* The subtree search will have included the parent diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c index b204428..43b4fab 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_search.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c @@ -203,6 +203,7 @@ ldbm_back_search( Slapi_PBlock *pb ) int lookup_returned_allids = 0; int backend_count = 1; static int print_once = 1; + back_txn txn = {NULL};
slapi_pblock_get( pb, SLAPI_BACKEND, &be ); slapi_pblock_get( pb, SLAPI_OPERATION, &operation); @@ -212,7 +213,8 @@ ldbm_back_search( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ); slapi_pblock_get( pb, SLAPI_REQCONTROLS, &controls ); slapi_pblock_get( pb, SLAPI_BACKEND_COUNT, &backend_count ); - + slapi_pblock_get( pb, SLAPI_TXN, &txn.back_txn_txn ); + inst = (ldbm_instance *) be->be_instance_info;
slapi_sdn_init_dn_ndn_byref(&basesdn,base); /* normalized by front end*/ @@ -401,7 +403,7 @@ ldbm_back_search( Slapi_PBlock *pb ) } else { - if ( ( e = find_entry( pb, be, addr, NULL )) == NULL ) + if ( ( e = find_entry( pb, be, addr, &txn )) == NULL ) { /* error or referral sent by find_entry */ return ldbm_back_search_cleanup(pb, li, sort_control, @@ -431,9 +433,9 @@ ldbm_back_search( Slapi_PBlock *pb ) if ((NULL != controls) && (sort) && (vlv)) { /* This candidate list is for vlv, no need for sort only. */ switch (vlv_search_build_candidate_list(pb, &basesdn, &vlv_rc, - sort_control, - (vlv ? &vlv_request_control : NULL), - &candidates, &vlv_response_control)) { + sort_control, + (vlv ? &vlv_request_control : NULL), + &candidates, &vlv_response_control)) { case VLV_ACCESS_DENIED: return ldbm_back_search_cleanup(pb, li, sort_control, vlv_rc, "VLV Control", @@ -638,9 +640,11 @@ ldbm_back_search( Slapi_PBlock *pb ) if (NULL != candidates && candidates->b_nids>0) { IDList *idl= NULL; + back_txn txn = {NULL}; + slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); vlv_response_control.result = - vlv_trim_candidates(be, candidates, sort_control, - &vlv_request_control, &idl, &vlv_response_control); + vlv_trim_candidates_txn(be, candidates, sort_control, + &vlv_request_control, &idl, &vlv_response_control, &txn); if(vlv_response_control.result==0) { idl_free(candidates); @@ -983,18 +987,20 @@ subtree_candidates( */ if(candidates!=NULL && (idl_length(candidates)>FILTER_TEST_THRESHOLD)) { IDList *tmp = candidates, *descendants = NULL; + back_txn txn = {NULL};
+ slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); if (entryrdn_get_noancestorid()) { /* subtree-rename: on && no ancestorid */ *err = entryrdn_get_subordinates(be, slapi_entry_get_sdn_const(e->ep_entry), - e->ep_id, &descendants, NULL); + e->ep_id, &descendants, &txn); idl_insert(&descendants, e->ep_id); candidates = idl_intersection(be, candidates, descendants); idl_free(tmp); idl_free(descendants); } else if (!has_tombstone_filter) { - *err = ldbm_ancestorid_read(be, NULL, e->ep_id, &descendants); + *err = ldbm_ancestorid_read(be, &txn, e->ep_id, &descendants); idl_insert(&descendants, e->ep_id); candidates = idl_intersection(be, candidates, descendants); idl_free(tmp); @@ -1164,6 +1170,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension ) char *target_uniqueid; int rc = 0; int estimate = 0; /* estimated search result count */ + back_txn txn = {NULL};
slapi_pblock_get( pb, SLAPI_BACKEND, &be ); slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); @@ -1179,6 +1186,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension ) slapi_pblock_get( pb, SLAPI_SEARCH_REFERRALS, &urls ); slapi_pblock_get( pb, SLAPI_TARGET_UNIQUEID, &target_uniqueid ); slapi_pblock_get( pb, SLAPI_SEARCH_RESULT_SET, &sr ); + slapi_pblock_get( pb, SLAPI_TXN, &txn.back_txn_txn );
if (NULL == sr) { goto bail; @@ -1297,7 +1305,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension ) ++sr->sr_lookthroughcount; /* checked above */
/* get the entry */ - e = id2entry( be, id, NULL, &err ); + e = id2entry( be, id, &txn, &err ); if ( e == NULL ) { if ( err != 0 && err != DB_NOTFOUND ) diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c index 9255ddb..6e350c9 100644 --- a/ldap/servers/slapd/back-ldbm/misc.c +++ b/ldap/servers/slapd/back-ldbm/misc.c @@ -405,9 +405,11 @@ ldbm_txn_ruv_modify_context( Slapi_PBlock *pb, modify_context *mc ) entry_address bentry_addr; IFP fn = NULL; int rc = 0; + back_txn txn = {NULL};
slapi_pblock_get(pb, SLAPI_TXN_RUV_MODS_FN, (void *)&fn); - + slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); + if (NULL == fn) { return (0); } @@ -428,7 +430,7 @@ ldbm_txn_ruv_modify_context( Slapi_PBlock *pb, modify_context *mc )
/* Note: if we find the bentry, it will stay locked until someone calls * modify_term on the mc we'll be associating the bentry with */ - bentry = find_entry2modify_only( pb, be, &bentry_addr, NULL ); + bentry = find_entry2modify_only( pb, be, &bentry_addr, &txn );
if (NULL == bentry) { /* Uh oh, we couldn't find and lock the RUV entry! */ diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h index b2dce18..a087a05 100644 --- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -527,6 +527,7 @@ int vlv_search_build_candidate_list(Slapi_PBlock *pb, const Slapi_DN *base, int int vlv_update_index(struct vlvIndex* p, back_txn *txn, struct ldbminfo *li, Slapi_PBlock *pb, struct backentry* oldEntry, struct backentry* newEntry); int vlv_update_all_indexes(back_txn *txn, backend *be, Slapi_PBlock *pb, struct backentry* oldEntry, struct backentry* newEntry); int vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, const Slapi_DN *base, int scope, Slapi_Filter *filter, IDList** filteredCandidates,int lookthrough_limit, time_t time_up); +int vlv_trim_candidates_txn(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, IDList** filteredCandidates,struct vlv_response *pResponse, back_txn *txn); int vlv_trim_candidates(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, IDList** filteredCandidates,struct vlv_response *pResponse); int vlv_parse_request_control(backend *be, struct berval *vlv_spec_ber, struct vlv_request* vlvp); int vlv_make_response_control(Slapi_PBlock *pb, const struct vlv_response* vlvp); @@ -535,6 +536,8 @@ void vlv_print_access_log(Slapi_PBlock *pb,struct vlv_request* vlvi, struct vlv_ void vlv_grok_new_import_entry(const struct backentry *e, backend *be); IDList *vlv_find_index_by_filter(struct backend *be, const char *base, Slapi_Filter *f); +IDList *vlv_find_index_by_filter_txn(struct backend *be, const char *base, + Slapi_Filter *f, back_txn *txn); int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *inst); void vlv_acquire_lock(backend *be); void vlv_release_lock(backend *be); diff --git a/ldap/servers/slapd/back-ldbm/sort.c b/ldap/servers/slapd/back-ldbm/sort.c index ae3f3d6..501765c 100644 --- a/ldap/servers/slapd/back-ldbm/sort.c +++ b/ldap/servers/slapd/back-ldbm/sort.c @@ -625,9 +625,11 @@ static int compare_entries_sv(ID *id_a, ID *id_b, sort_spec *s,baggage_carrier * backend *be = bc->be; ldbm_instance *inst = (ldbm_instance *) be->be_instance_info; int err; + back_txn txn = {NULL};
+ slapi_pblock_get(bc->pb, SLAPI_TXN, &txn.back_txn_txn); *error = 1; - a = id2entry(be,*id_a,NULL,&err); + a = id2entry(be,*id_a,&txn,&err); if (NULL == a) { if (0 != err ) { LDAPDebug(LDAP_DEBUG_TRACE,"compare_entries db err %d\n",err,0,0); @@ -636,7 +638,7 @@ static int compare_entries_sv(ID *id_a, ID *id_b, sort_spec *s,baggage_carrier * /* Best to log error and set some flag */ return 0; } - b = id2entry(be,*id_b,NULL,&err); + b = id2entry(be,*id_b,&txn,&err); if (NULL == b) { if (0 != err ) { LDAPDebug(LDAP_DEBUG_TRACE,"compare_entries db err %d\n",err,0,0); diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c index 4cda3d0..a953030 100644 --- a/ldap/servers/slapd/back-ldbm/vlv.c +++ b/ldap/servers/slapd/back-ldbm/vlv.c @@ -58,8 +58,8 @@ #include "vlv_key.h"
static PRUint32 vlv_trim_candidates_byindex(PRUint32 length, const struct vlv_request *vlv_request_control); -static PRUint32 vlv_trim_candidates_byvalue(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control); -static int vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control, int is_srchlist_locked); +static PRUint32 vlv_trim_candidates_byvalue(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, back_txn *txn); +static int vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control, int is_srchlist_locked, back_txn *txn);
/* New mutex for vlv locking Slapi_RWLock * vlvSearchList_lock=NULL; @@ -1150,7 +1150,9 @@ vlv_search_build_candidate_list(Slapi_PBlock *pb, const Slapi_DN *base, int *vlv backend *be; int scope, rc=LDAP_SUCCESS; char *fstr; + back_txn txn = {NULL};
+ slapi_pblock_get( pb, SLAPI_TXN, &txn.back_txn_txn ); slapi_pblock_get( pb, SLAPI_BACKEND, &be ); slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ); slapi_pblock_get( pb, SLAPI_SEARCH_STRFILTER, &fstr ); @@ -1164,7 +1166,8 @@ vlv_search_build_candidate_list(Slapi_PBlock *pb, const Slapi_DN *base, int *vlv } else if((*vlv_rc=vlvIndex_accessallowed(pi, pb)) != LDAP_SUCCESS) { slapi_rwlock_unlock(be->vlvSearchList_lock); rc = VLV_ACCESS_DENIED; - } else if ((*vlv_rc=vlv_build_candidate_list(be,pi,vlv_request_control,candidates,vlv_response_control, 1)) != LDAP_SUCCESS) { + } else if ((*vlv_rc=vlv_build_candidate_list(be,pi,vlv_request_control,candidates, + vlv_response_control, 1, &txn)) != LDAP_SUCCESS) { rc = VLV_BLD_LIST_FAILED; vlv_response_control->result=*vlv_rc; } @@ -1187,7 +1190,7 @@ vlv_search_build_candidate_list(Slapi_PBlock *pb, const Slapi_DN *base, int *vlv
static int -vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control, int is_srchlist_locked) +vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control, int is_srchlist_locked, back_txn *txn) { int return_value = LDAP_SUCCESS; DB *db = NULL; @@ -1196,6 +1199,7 @@ vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_requ PRUint32 si = 0; /* The Selected Index */ PRUint32 length; int do_trim= 1; + DB_TXN *db_txn = NULL;
LDAPDebug(LDAP_DEBUG_TRACE, "=> vlv_build_candidate_list: %s %s Using VLV Index %s\n", @@ -1226,7 +1230,10 @@ vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_requ if (is_srchlist_locked) { slapi_rwlock_unlock(be->vlvSearchList_lock); } - err = db->cursor(db, 0 /* txn */, &dbc, 0); + if (txn) { + db_txn = txn->back_txn_txn; + } + err = db->cursor(db, db_txn, &dbc, 0); if (err != 0) { /* shouldn't happen */ LDAPDebug(LDAP_DEBUG_ANY, "VLV: couldn't get cursor (err %d)\n", @@ -1241,8 +1248,7 @@ vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_requ si = vlv_trim_candidates_byindex(length, vlv_request_control); break; case 1: /* byValue */ - si = vlv_build_candidate_list_byvalue(p, dbc, length, - vlv_request_control); + si = vlv_build_candidate_list_byvalue(p, dbc, length, vlv_request_control); if (si==length) { do_trim = 0; /* minimum idl_alloc size should be 1; 0 is considered ALLID */ @@ -1314,8 +1320,10 @@ vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, c int done= 0; int counter= 0; ID id = NOID; + back_txn txn = {NULL}; idl_iterator current = idl_iterator_init(candidates); resultIdl= idl_alloc(candidates->b_nids); + slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); do { id = idl_iterator_dereference_increment(¤t, candidates); @@ -1323,7 +1331,7 @@ vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, c { int err= 0; struct backentry *e= NULL; - e = id2entry( be, id, NULL, &err ); + e = id2entry( be, id, &txn, &err ); if ( e == NULL ) { /* @@ -1393,7 +1401,7 @@ vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, c * other (80) */ int -vlv_trim_candidates(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, IDList** trimmedCandidates,struct vlv_response *vlv_response_control) +vlv_trim_candidates_txn(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, IDList** trimmedCandidates,struct vlv_response *vlv_response_control, back_txn *txn) { IDList* resultIdl= NULL; int return_value= LDAP_SUCCESS; @@ -1412,7 +1420,7 @@ vlv_trim_candidates(backend *be, const IDList *candidates, const sort_spec* sort si= vlv_trim_candidates_byindex(candidates->b_nids, vlv_request_control); break; case 1: /* byValue */ - si= vlv_trim_candidates_byvalue(be, candidates, sort_control, vlv_request_control); + si= vlv_trim_candidates_byvalue(be, candidates, sort_control, vlv_request_control, txn); /* Don't bother sending results if the attribute value wasn't found */ if(si==candidates->b_nids) { @@ -1457,6 +1465,12 @@ vlv_trim_candidates(backend *be, const IDList *candidates, const sort_spec* sort return return_value; }
+int +vlv_trim_candidates(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, IDList** trimmedCandidates,struct vlv_response *vlv_response_control) +{ + return vlv_trim_candidates_txn(be, candidates, sort_control, vlv_request_control, trimmedCandidates, vlv_response_control, NULL); +} + /* * Work out the Selected Index given the length of the candidate list * and the request control from the client. @@ -1523,7 +1537,7 @@ vlv_trim_candidates_byindex(PRUint32 length, const struct vlv_request *vlv_reque * Iterate over the Candidate ID List looking for an entry >= the provided attribute value. */ static PRUint32 -vlv_trim_candidates_byvalue(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control) +vlv_trim_candidates_byvalue(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, back_txn *txn) { PRUint32 si= 0; /* The Selected Index */ PRUint32 low= 0; @@ -1592,7 +1606,7 @@ retry: current = (1 + low + high)/2; } id= candidates->b_ids[current]; - e = id2entry( be, id, NULL, &err ); + e = id2entry( be, id, txn, &err ); if ( e == NULL ) { int rval; @@ -1942,8 +1956,8 @@ vlv_parse_request_control( backend *be, struct berval *vlv_spec_ber,struct vlv_r * has the same search base and search filter. * added read lock */
-IDList *vlv_find_index_by_filter(struct backend *be, const char *base, - Slapi_Filter *f) +IDList *vlv_find_index_by_filter_txn(struct backend *be, const char *base, + Slapi_Filter *f, back_txn *txn) { struct vlvSearch *t = NULL; struct vlvIndex *vi; @@ -1954,6 +1968,11 @@ IDList *vlv_find_index_by_filter(struct backend *be, const char *base, DBC *dbc = NULL; IDList *idl; Slapi_Filter *vlv_f; + DB_TXN *db_txn = NULL; + + if (txn) { + db_txn = txn->back_txn_txn; + }
slapi_sdn_init_dn_byref(&base_sdn, base); slapi_rwlock_rdlock(be->vlvSearchList_lock); @@ -1984,7 +2003,7 @@ IDList *vlv_find_index_by_filter(struct backend *be, const char *base, if (dblayer_get_index_file(be, vi->vlv_attrinfo, &db, 0) == 0) { length = vlvIndex_get_indexlength(vi, db, 0 /* txn */); slapi_rwlock_unlock(be->vlvSearchList_lock); - err = db->cursor(db, 0 /* txn */, &dbc, 0); + err = db->cursor(db, db_txn, &dbc, 0); if (err == 0) { if (length == 0) /* 609377: index size could be 0 */ { @@ -2015,7 +2034,11 @@ IDList *vlv_find_index_by_filter(struct backend *be, const char *base, return NULL; }
- +IDList *vlv_find_index_by_filter(struct backend *be, const char *base, + Slapi_Filter *f) +{ + return vlv_find_index_by_filter_txn(be, base, f, NULL); +}
/* replace c with c2 in string -- probably exists somewhere but I can't find it slapi maybe? */
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c index 9195b28..c160507 100644 --- a/ldap/servers/slapd/back-ldbm/vlv_srch.c +++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c @@ -181,15 +181,17 @@ vlvSearch_init(struct vlvSearch* p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm if ( !slapi_sdn_isempty(p->vlv_base)) { Slapi_Backend *oldbe = NULL; entry_address addr; + back_txn txn = {NULL};
/* switch context to the target backend */ slapi_pblock_get(pb, SLAPI_BACKEND, &oldbe); slapi_pblock_set(pb, SLAPI_BACKEND, inst->inst_be); slapi_pblock_set(pb, SLAPI_PLUGIN, inst->inst_be->be_database); + slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn);
addr.dn = (char*)slapi_sdn_get_ndn (p->vlv_base); addr.uniqueid = NULL; - e = find_entry( pb, inst->inst_be, &addr, NULL ); + e = find_entry( pb, inst->inst_be, &addr, &txn ); /* Check to see if the entry is absent. If it is, mark this search * as not initialized */ if (NULL == e) {
389-commits@lists.fedoraproject.org