diff --git a/CHANGES b/CHANGES index 52b1fffef58859fe367709e6d3fff1aa5f236634..8befeffa7d8128af167df64dd893c9f401d3d639 100644 --- a/CHANGES +++ b/CHANGES @@ -29,6 +29,7 @@ OpenLDAP 2.4.17 Engineering Fixed slapd some abandon and cancel race conditions (ITS#6104) Fixed slapd tls context after changes (ITS#6135) Fixed slapd-bdb/hdb adjust dncachesize if too low (ITS#6176) + Fixed slapd-bdb/hdb crashes during delete (ITS#6177) Fixed slapd-hdb freeing of already freed entries (ITS#6074) Fixed slapd-hdb entryinfo cleanup (ITS#6088) Fixed slapd-hdb dncache lockups (ITS#6095) diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index 5b79b665a2aaba44d07dd41ce5c99b98f35f8422..5d36a2db29c45e72a8cc17e545443ab6632f4f26 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -979,6 +979,9 @@ load1: if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) { rc = DB_NOTFOUND; bdb_cache_entry_db_unlock( bdb, lock ); + bdb_cache_entryinfo_lock( *eip ); + (*eip)->bei_finders--; + bdb_cache_entryinfo_unlock( *eip ); } else if ( rc == 0 ) { if ( load ) { if ( !ep) { @@ -1336,7 +1339,7 @@ bdb_cache_delete( DB_LOCK *lock ) { EntryInfo *ei = BEI(e); - int rc; + int rc, busy = 0; assert( e->e_private != NULL ); @@ -1346,8 +1349,24 @@ bdb_cache_delete( /* Set this early, warn off any queriers */ ei->bei_state |= CACHE_ENTRY_DELETED; + if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED | + CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) || + ei->bei_finders > 0 ) + busy = 1; + bdb_cache_entryinfo_unlock( ei ); + while ( busy ) { + ldap_pvt_thread_yield(); + busy = 0; + bdb_cache_entryinfo_lock( ei ); + if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED | + CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) || + ei->bei_finders > 0 ) + busy = 1; + bdb_cache_entryinfo_unlock( ei ); + } + /* Get write lock on the data */ rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock ); if ( rc ) { diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c index 24c82666768fb3b5b23f380a387b77a05f85ef0f..2d1748c328585fa5ead21ab0487519e911e4155d 100644 --- a/servers/slapd/back-bdb/dn2id.c +++ b/servers/slapd/back-bdb/dn2id.c @@ -1156,18 +1156,18 @@ gotit: if ( bdb_cache_find_id( cx->op, cx->txn, cx->id, &cx->ei, ID_NOENTRY, NULL )) continue; - if ( !cx->ei || - ( cx->ei->bei_state & CACHE_ENTRY_NO_KIDS )) - continue; - - ei2 = cx->ei; - BDB_ID2DISK( cx->id, &cx->nid ); - hdb_dn2idl_internal( cx ); - if ( !BDB_IDL_IS_ZERO( cx->tmp )) - nokids = 0; - bdb_cache_entryinfo_lock( ei2 ); - ei2->bei_finders--; - bdb_cache_entryinfo_unlock( ei2 ); + if ( cx->ei ) { + ei2 = cx->ei; + if ( !( ei2->bei_state & CACHE_ENTRY_NO_KIDS )) { + BDB_ID2DISK( cx->id, &cx->nid ); + hdb_dn2idl_internal( cx ); + if ( !BDB_IDL_IS_ZERO( cx->tmp )) + nokids = 0; + } + bdb_cache_entryinfo_lock( ei2 ); + ei2->bei_finders--; + bdb_cache_entryinfo_unlock( ei2 ); + } } cx->depth--; cx->op->o_tmpfree( save, cx->op->o_tmpmemctx );