*res = eip;
return rc;
}
- } else if ( ei2->bei_state == CACHE_ENTRY_DELETED ) {
+ } else if ( ei2->bei_state & CACHE_ENTRY_DELETED ) {
/* In the midst of deleting? Give it a chance to
* complete.
*/
/* Ok, we found the info, do we have the entry? */
if ( *eip && rc == 0 ) {
- if ( (*eip)->bei_state == CACHE_ENTRY_DELETED ) {
+ if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
rc = DB_NOTFOUND;
} else if (!(*eip)->bei_e ) {
if (!ep) {
rc = bdb_entryinfo_add_internal( bdb, ei, e->e_id, nrdn, &new, locker );
new->bei_e = e;
e->e_private = new;
+ new->bei_state = CACHE_ENTRY_NO_KIDS;
+ ei->bei_state &= ~CACHE_ENTRY_NO_KIDS;
bdb_cache_entryinfo_unlock( ei );
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
return rc;
assert( e->e_private );
/* Set this early, warn off any queriers */
- ei->bei_state = CACHE_ENTRY_DELETED;
+ ei->bei_state |= CACHE_ENTRY_DELETED;
/* Get write lock on the data */
bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock );
/*
* flag entry to be freed later by a call to cache_return_entry()
*/
- e->bei_state = CACHE_ENTRY_DELETED;
+ e->bei_state |= CACHE_ENTRY_DELETED;
return( 0 );
}
int
bdb_dn2id_children(
- BackendDB *be,
+ Operation *op,
DB_TXN *txn,
- struct berval *dn,
- int flags )
+ Entry *e )
{
int rc;
- DBT key, data;
- struct bdb_info *bdb = (struct bdb_info *) be->be_private;
- DB *db = bdb->bi_dn2id->bdi_db;
- ID id;
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, ARGS,
- "=> bdb_dn2id_children( %s )\n", dn->bv_val, 0, 0 );
+ "=> bdb_dn2id_children( %s )\n", e->e_nname.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_children( %s )\n",
- dn->bv_val, 0, 0 );
+ e->e_nname.bv_val, 0, 0 );
#endif
+ if ( BEI(e)->bei_kids ) {
+ rc = 0;
+ }
+ if ( BEI(e)->bei_state & CACHE_ENTRY_NO_KIDS ) {
+ rc = DB_NOTFOUND;
+ } else {
+
+ DBT key, data;
+ struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
+ DB *db = bdb->bi_dn2id->bdi_db;
+ ID id;
+
DBTzero( &key );
- key.size = dn->bv_len + 2;
- key.data = ch_malloc( key.size );
+ key.size = e->e_nname.bv_len + 2;
+ key.data = sl_malloc( key.size, op->o_tmpmemctx );
((char *)key.data)[0] = DN_ONE_PREFIX;
- AC_MEMCPY( &((char *)key.data)[1], dn->bv_val, key.size - 1 );
+ AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 );
/* we actually could do a empty get... */
DBTzero( &data );
data.doff = 0;
data.dlen = sizeof(id);
- rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags | flags );
- free( key.data );
+ rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
+ sl_free( key.data, op->o_tmpmemctx );
+
+ if ( rc == DB_NOTFOUND ) {
+ BEI(e)->bei_state |= CACHE_ENTRY_NO_KIDS;
+ }
+
+ }
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, DETAIL1,
"<= bdb_dn2id_children( %s ): %s (%d)\n",
- dn->bv_val, rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
+ e->e_nname.bv_val, rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
db_strerror(rc)), rc );
#else
Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %s (%d)\n",
- dn->bv_val,
+ e->e_nname.bv_val,
rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
db_strerror(rc) ), rc );
#endif
}
#ifndef BDB_HIER
- rs->sr_err = ei->bei_kids ? 0 : bdb_dn2id_children( op->o_bd, ltid,
- &e->e_nname, 0 );
+ rs->sr_err = bdb_dn2id_children( op, ltid, e );
if ( rs->sr_err != DB_NOTFOUND ) {
switch( rs->sr_err ) {
case DB_LOCK_DEADLOCK:
}
goto return_results;
}
+ ei->bei_state |= CACHE_ENTRY_NO_KIDS;
#endif
if (!manageDSAit && is_entry_referral( e ) ) {
/* parent is a referral, don't allow add */