#ifdef BDB_HIER
 #define bdb_cache_lru_purge    hdb_cache_lru_purge
 #endif
-static void bdb_cache_lru_purge( struct bdb_info *bdb );
+static void bdb_cache_lru_purge( struct bdb_info *bdb, uint32_t locker );
 
 static int     bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr);
 #ifdef LDAP_DEBUG
 #endif
 
 static void
-bdb_cache_lru_purge( struct bdb_info *bdb )
+bdb_cache_lru_purge( struct bdb_info *bdb, uint32_t locker )
 {
-       DB_LOCK         lock, *lockp;
+       DB_LOCK         lock;
        EntryInfo *elru, *elnext;
        int count, islocked;
 
                return;
        }
 
-       if ( bdb->bi_cache.c_locker ) {
-               lockp = &lock;
-       } else {
-               lockp = NULL;
-       }
-
        count = 0;
        /* Look for an unused entry to remove */
        for (elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) {
                /* If we can successfully writelock it, then
                 * the object is idle.
                 */
-               if ( bdb_cache_entry_db_lock( bdb,
-                       bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
+               if ( bdb_cache_entry_db_lock( bdb, locker, elru, 1, 1, &lock ) == 0 ) {
 
                        /* Free entry for this node if it's present */
                        if ( elru->bei_e ) {
                                elru->bei_e = NULL;
                                count++;
                        }
-                       bdb_cache_entry_db_unlock( bdb, lockp );
+                       bdb_cache_entry_db_unlock( bdb, &lock );
 
                        /* ITS#4010 if we're in slapcat, and this node is a leaf
                         * node, free it.
 #endif
                                                ep = NULL;
                                        }
-                                       bdb_cache_entryinfo_lock( *eip );
-                                       (*eip)->bei_state ^= CACHE_ENTRY_LOADING;
-                                       bdb_cache_entryinfo_unlock( *eip );
                                        if ( rc == 0 ) {
                                                /* If we succeeded, downgrade back to a readlock. */
                                                rc = bdb_cache_entry_db_relock( bdb, locker,
                                                /* Otherwise, release the lock. */
                                                bdb_cache_entry_db_unlock( bdb, lock );
                                        }
+                                       bdb_cache_entryinfo_lock( *eip );
+                                       (*eip)->bei_state ^= CACHE_ENTRY_LOADING;
+                                       bdb_cache_entryinfo_unlock( *eip );
                                } else if ( !(*eip)->bei_e ) {
                                        /* Some other thread is trying to load the entry,
                                         * wait for it to finish.
                        ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
                }
                if ( purge )
-                       bdb_cache_lru_purge( bdb );
+                       bdb_cache_lru_purge( bdb, locker );
        }
 
 #ifdef SLAP_ZONE_ALLOC
        ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
 
        if ( purge )
-               bdb_cache_lru_purge( bdb );
+               bdb_cache_lru_purge( bdb, locker );
 
        return rc;
 }
 
 
 static int presence_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeDescription *desc,
        ID *ids );
 
 static int equality_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeAssertion *ava,
        ID *ids,
        ID *tmp );
 static int inequality_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeAssertion *ava,
        ID *ids,
        ID *tmp,
        int gtorlt );
 static int approx_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeAssertion *ava,
        ID *ids,
        ID *tmp );
 static int substring_candidates(
        Operation *op,
+       u_int32_t locker,
        SubstringsAssertion *sub,
        ID *ids,
        ID *tmp );
 
 static int list_candidates(
        Operation *op,
+       u_int32_t locker,
        Filter *flist,
        int ftype,
        ID *ids,
 static int
 ext_candidates(
         Operation *op,
+               u_int32_t locker,
         MatchingRuleAssertion *mra,
         ID *ids,
         ID *tmp,
 static int
 comp_candidates (
        Operation *op,
+       u_int32_t locker,
        MatchingRuleAssertion *mra,
        ComponentFilter *f,
        ID *ids,
 static int
 ava_comp_candidates (
                Operation *op,
+               u_int32_t locker,
                AttributeAssertion *ava,
                AttributeAliasing *aa,
                ID *ids,
 int
 bdb_filter_candidates(
        Operation *op,
+       u_int32_t locker,
        Filter  *f,
        ID *ids,
        ID *tmp,
                break;
        case LDAP_FILTER_PRESENT:
                Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
-               rc = presence_candidates( op, f->f_desc, ids );
+               rc = presence_candidates( op, locker, f->f_desc, ids );
                break;
 
        case LDAP_FILTER_EQUALITY:
                Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
 #ifdef LDAP_COMP_MATCH
                if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) {
-                       rc = ava_comp_candidates ( op, f->f_ava, aa, ids, tmp, stack );
+                       rc = ava_comp_candidates ( op, locker, f->f_ava, aa, ids, tmp, stack );
                }
                else
 #endif
                {
-                       rc = equality_candidates( op, f->f_ava, ids, tmp );
+                       rc = equality_candidates( op, locker, f->f_ava, ids, tmp );
                }
                break;
 
        case LDAP_FILTER_APPROX:
                Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
-               rc = approx_candidates( op, f->f_ava, ids, tmp );
+               rc = approx_candidates( op, locker, f->f_ava, ids, tmp );
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
                Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
-               rc = substring_candidates( op, f->f_sub, ids, tmp );
+               rc = substring_candidates( op, locker, f->f_sub, ids, tmp );
                break;
 
        case LDAP_FILTER_GE:
                Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
                if( f->f_ava->aa_desc->ad_type->sat_ordering &&
                        ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
-                       rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_GE );
+                       rc = inequality_candidates( op, locker, f->f_ava, ids, tmp, LDAP_FILTER_GE );
                else
-                       rc = presence_candidates( op, f->f_ava->aa_desc, ids );
+                       rc = presence_candidates( op, locker, f->f_ava->aa_desc, ids );
                break;
 
        case LDAP_FILTER_LE:
                Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
                if( f->f_ava->aa_desc->ad_type->sat_ordering &&
                        ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
-                       rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_LE );
+                       rc = inequality_candidates( op, locker, f->f_ava, ids, tmp, LDAP_FILTER_LE );
                else
-                       rc = presence_candidates( op, f->f_ava->aa_desc, ids );
+                       rc = presence_candidates( op, locker, f->f_ava->aa_desc, ids );
                break;
 
        case LDAP_FILTER_NOT:
 
        case LDAP_FILTER_AND:
                Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
-               rc = list_candidates( op, 
+               rc = list_candidates( op, locker, 
                        f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
                break;
 
        case LDAP_FILTER_OR:
                Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
-               rc = list_candidates( op, 
+               rc = list_candidates( op, locker,
                        f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
                break;
 #ifdef LDAP_COMP_MATCH
        case LDAP_FILTER_EXT:
                 Debug( LDAP_DEBUG_FILTER, "\tEXT\n", 0, 0, 0 );
-                rc = ext_candidates( op, f->f_mra, ids, tmp, stack );
+                rc = ext_candidates( op, locker, f->f_mra, ids, tmp, stack );
                 break;
 #endif
        default:
 static int
 comp_list_candidates(
        Operation *op,
+       u_int32_t locker,
        MatchingRuleAssertion* mra,
        ComponentFilter *flist,
        int     ftype,
                        continue;
                }
                BDB_IDL_ZERO( save );
-               rc = comp_candidates( op, mra, f, save, tmp, save+BDB_IDL_UM_SIZE );
+               rc = comp_candidates( op, locker, mra, f, save, tmp, save+BDB_IDL_UM_SIZE );
 
                if ( rc != 0 ) {
                        if ( ftype == LDAP_COMP_FILTER_AND ) {
 static int
 comp_equality_candidates (
         Operation *op,
+       u_int32_t locker,
         MatchingRuleAssertion *mra,
        ComponentAssertion *ca,
         ID *ids,
                 return 0;
         }
         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-                rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+                rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
                 if( rc == DB_NOTFOUND ) {
                         BDB_IDL_ZERO( ids );
 static int
 ava_comp_candidates (
        Operation *op,
+       u_int32_t locker,
        AttributeAssertion *ava,
        AttributeAliasing *aa,
        ID *ids,
        mra.ma_desc = aa->aa_aliased_ad;
        mra.ma_rule = ava->aa_desc->ad_type->sat_equality;
        
-       return comp_candidates ( op, &mra, ava->aa_cf, ids, tmp, stack );
+       return comp_candidates ( op, locker, &mra, ava->aa_cf, ids, tmp, stack );
 }
 
 static int
 comp_candidates (
        Operation *op,
+       u_int32_t locker,
        MatchingRuleAssertion *mra,
        ComponentFilter *f,
        ID *ids,
                rc = f->cf_result;
                break;
        case LDAP_COMP_FILTER_AND:
-               rc = comp_list_candidates( op, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack );
+               rc = comp_list_candidates( op, locker, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack );
                break;
        case LDAP_COMP_FILTER_OR:
-               rc = comp_list_candidates( op, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack );
+               rc = comp_list_candidates( op, locker, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack );
                break;
        case LDAP_COMP_FILTER_NOT:
                /* No component indexing supported for NOT filter */
                rc = LDAP_PROTOCOL_ERROR;
                break;
        case LDAP_COMP_FILTER_ITEM:
-               rc = comp_equality_candidates( op, mra, f->cf_ca, ids, tmp, stack );
+               rc = comp_equality_candidates( op, locker, mra, f->cf_ca, ids, tmp, stack );
                break;
        default:
                {
 static int
 ext_candidates(
         Operation *op,
+               u_int32_t locker,
         MatchingRuleAssertion *mra,
         ID *ids,
         ID *tmp,
                return 0;
        }
 
-       return comp_candidates ( op, mra, mra->ma_cf, ids, tmp, stack);
+       return comp_candidates ( op, locker, mra, mra->ma_cf, ids, tmp, stack);
 }
 #endif
 
 static int
 list_candidates(
        Operation *op,
+       u_int32_t locker,
        Filter  *flist,
        int             ftype,
        ID *ids,
                        continue;
                }
                BDB_IDL_ZERO( save );
-               rc = bdb_filter_candidates( op, f, save, tmp,
+               rc = bdb_filter_candidates( op, locker, f, save, tmp,
                        save+BDB_IDL_UM_SIZE );
 
                if ( rc != 0 ) {
 static int
 presence_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeDescription *desc,
        ID *ids )
 {
                return -1;
        }
 
-       rc = bdb_key_read( op->o_bd, db, NULL, &prefix, ids, NULL, 0 );
+       rc = bdb_key_read( op->o_bd, db, locker, &prefix, ids, NULL, 0 );
 
        if( rc == DB_NOTFOUND ) {
                BDB_IDL_ZERO( ids );
 static int
 equality_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeAssertion *ava,
        ID *ids,
        ID *tmp )
        }
 
        for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-               rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+               rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
                if( rc == DB_NOTFOUND ) {
                        BDB_IDL_ZERO( ids );
 static int
 approx_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeAssertion *ava,
        ID *ids,
        ID *tmp )
        }
 
        for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-               rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+               rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
                if( rc == DB_NOTFOUND ) {
                        BDB_IDL_ZERO( ids );
 static int
 substring_candidates(
        Operation *op,
+       u_int32_t locker,
        SubstringsAssertion     *sub,
        ID *ids,
        ID *tmp )
        }
 
        for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-               rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+               rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
                if( rc == DB_NOTFOUND ) {
                        BDB_IDL_ZERO( ids );
 static int
 inequality_candidates(
        Operation *op,
+       u_int32_t locker,
        AttributeAssertion *ava,
        ID *ids,
        ID *tmp,
 
        BDB_IDL_ZERO( ids );
        while(1) {
-               rc = bdb_key_read( op->o_bd, db, NULL, &keys[0], tmp, &cursor, gtorlt );
+               rc = bdb_key_read( op->o_bd, db, locker, &keys[0], tmp, &cursor, gtorlt );
 
                if( rc == DB_NOTFOUND ) {
                        rc = 0;