]> git.sur5r.net Git - openldap/commitdiff
ITS#6177
authorQuanah Gibson-Mount <quanah@openldap.org>
Fri, 19 Jun 2009 23:55:56 +0000 (23:55 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Fri, 19 Jun 2009 23:55:56 +0000 (23:55 +0000)
CHANGES
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/dn2id.c

diff --git a/CHANGES b/CHANGES
index 52b1fffef58859fe367709e6d3fff1aa5f236634..8befeffa7d8128af167df64dd893c9f401d3d639 100644 (file)
--- 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)
index 5b79b665a2aaba44d07dd41ce5c99b98f35f8422..5d36a2db29c45e72a8cc17e545443ab6632f4f26 100644 (file)
@@ -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 ) {
index 24c82666768fb3b5b23f380a387b77a05f85ef0f..2d1748c328585fa5ead21ab0487519e911e4155d 100644 (file)
@@ -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 );