From: Kurt Zeilenga Date: Thu, 13 Mar 2003 04:35:26 +0000 (+0000) Subject: Suck in BDB changes including fixes for X-Git-Tag: OPENLDAP_REL_ENG_2_1_16~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de3a5e130f1bce8c52a3237dfdcfafad222b0a76;p=thirdparty%2Fopenldap.git Suck in BDB changes including fixes for and LDBM idl fixes --- diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 079b44081c..c97bd6bb42 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -384,8 +384,6 @@ retry: /* transaction retry */ case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; - default: - rc = LDAP_OTHER; } #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -396,6 +394,7 @@ retry: /* transaction retry */ db_strerror(rc), rc, 0 ); #endif text = "DN index delete failed"; + rc = LDAP_OTHER; goto return_results; } @@ -406,8 +405,6 @@ retry: /* transaction retry */ case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; - default: - rc = LDAP_OTHER; } #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -419,6 +416,7 @@ retry: /* transaction retry */ db_strerror(rc), rc, 0 ); #endif text = "entry delete failed"; + rc = LDAP_OTHER; goto return_results; } @@ -429,8 +427,6 @@ retry: /* transaction retry */ case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; - default: - rc = LDAP_OTHER; } #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -440,6 +436,7 @@ retry: /* transaction retry */ 0, 0, 0 ); #endif text = "entry index delete failed"; + rc = LDAP_OTHER; goto return_results; } diff --git a/servers/slapd/back-bdb/idl.c b/servers/slapd/back-bdb/idl.c index 1454e18f93..5d7f321857 100644 --- a/servers/slapd/back-bdb/idl.c +++ b/servers/slapd/back-bdb/idl.c @@ -44,7 +44,7 @@ } \ } while ( 0 ) -static int +int bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 ) { const bdb_idl_cache_entry_t *idl1 = v_idl1, *idl2 = v_idl2; @@ -493,8 +493,18 @@ bdb_idl_fetch_key( int i = 0; while ( bdb->bi_idl_lru_tail != NULL && i < 10 ) { ee = bdb->bi_idl_lru_tail; - avl_delete( &bdb->bi_idl_tree, (caddr_t) ee, - bdb_idl_entry_cmp ); + if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) ee, + bdb_idl_entry_cmp ) == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "bdb_idl_fetch_key: AVL delete failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " + "AVL delete failed\n", + 0, 0, 0 ); +#endif + } IDL_LRU_DELETE( bdb, ee ); i++; --bdb->bi_idl_cache_size; @@ -551,8 +561,18 @@ bdb_idl_insert_key( matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, bdb_idl_entry_cmp ); if ( matched_idl_entry != NULL ) { - avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry, - bdb_idl_entry_cmp ); + if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry, + bdb_idl_entry_cmp ) == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "bdb_idl_fetch_key: AVL delete failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " + "AVL delete failed\n", + 0, 0, 0 ); +#endif + } --bdb->bi_idl_cache_size; IDL_LRU_DELETE( bdb, matched_idl_entry ); free( matched_idl_entry->kstr.bv_val ); @@ -763,8 +783,18 @@ bdb_idl_delete_key( matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, bdb_idl_entry_cmp ); if ( matched_idl_entry != NULL ) { - avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry, - bdb_idl_entry_cmp ); + if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry, + bdb_idl_entry_cmp ) == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "bdb_idl_fetch_key: AVL delete failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " + "AVL delete failed\n", + 0, 0, 0 ); +#endif + } --bdb->bi_idl_cache_size; IDL_LRU_DELETE( bdb, matched_idl_entry ); free( matched_idl_entry->kstr.bv_val ); @@ -820,20 +850,17 @@ bdb_idl_delete_key( /* It's a range, see if we need to rewrite * the boundaries */ - hi = 0; data.data = &lo; rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); if ( rc != 0 ) { err = "c_get lo"; goto fail; } - if ( id > lo ) { - data.data = &hi; - rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); - if ( rc != 0 ) { - err = "c_get hi"; - goto fail; - } + data.data = &hi; + rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); + if ( rc != 0 ) { + err = "c_get hi"; + goto fail; } if ( id == lo || id == hi ) { if ( id == lo ) { @@ -851,6 +878,12 @@ bdb_idl_delete_key( goto fail; } } else { + if ( id == lo ) { + /* reposition on lo slot */ + data.data = &lo; + cursor->c_get( cursor, key, &data, DB_PREV ); + lo = id; + } rc = cursor->c_del( cursor, 0 ); if ( rc != 0 ) { err = "c_del"; diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 8e0669ea02..db9d00f914 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -12,10 +12,9 @@ #include #include -#include - #include "back-bdb.h" #include "external.h" +#include static struct bdbi_database { char *file; @@ -447,6 +446,7 @@ bdb_db_close( BackendDB *be ) entry = bdb->bi_idl_lru_head; while ( entry != NULL ) { next_entry = entry->idl_lru_next; + avl_delete( &bdb->bi_idl_tree, (caddr_t) entry, bdb_idl_entry_cmp ); free( entry->idl ); free( entry->kstr.bv_val ); free( entry ); diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 167938a960..7e71175130 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -252,6 +252,13 @@ int bdb_modify_internal( } } + /* If we've done repeated mods on a cached entry, then e_attrs + * is no longer contiguous with the entry. + */ + if( (void *) save_attrs != (void *) (e+1)) { + attrs_free( save_attrs ); + } + return rc; } diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 94745198f7..7365a2d655 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -82,12 +82,15 @@ retry: /* transaction retry */ if (e != NULL) { bdb_cache_delete_entry(&bdb->bi_cache, e); bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); + e = NULL; } if (p != NULL) { bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); + p = NULL; } if (np != NULL) { bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np); + np = NULL; } #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "==>bdb_modrdn: retrying...\n", 0, 0, 0); @@ -654,9 +657,9 @@ retry: /* transaction retry */ } /* Build target dn and make sure target entry doesn't exist already. */ - build_new_dn( &new_dn, new_parent_dn, newrdn ); + if (!new_dn.bv_val) build_new_dn( &new_dn, new_parent_dn, newrdn ); - dnNormalize2( NULL, &new_dn, &new_ndn ); + if (!new_ndn.bv_val) dnNormalize2( NULL, &new_dn, &new_ndn ); #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, RESULTS, @@ -685,7 +688,7 @@ retry: /* transaction retry */ /* Get attribute type and attribute value of our new rdn, we will * need to add that to our new entry */ - if ( ldap_bv2rdn( newrdn, &new_rdn, (char **)&text, + if ( !new_rdn && ldap_bv2rdn( newrdn, &new_rdn, (char **)&text, LDAP_DN_FORMAT_LDAP ) ) { #ifdef NEW_LOGGING @@ -719,7 +722,7 @@ retry: /* transaction retry */ #endif if ( deleteoldrdn ) { - if ( ldap_bv2rdn( dn, &old_rdn, (char **)&text, + if ( !old_rdn && ldap_bv2rdn( dn, &old_rdn, (char **)&text, LDAP_DN_FORMAT_LDAP ) ) { #ifdef NEW_LOGGING @@ -740,10 +743,12 @@ retry: /* transaction retry */ } /* prepare modlist of modifications from old/new rdn */ - rc = slap_modrdn2mods( be, conn, op, e, old_rdn, new_rdn, + if (!mod) { + rc = slap_modrdn2mods( be, conn, op, e, old_rdn, new_rdn, deleteoldrdn, &mod ); - if ( rc != LDAP_SUCCESS ) { - goto return_results; + if ( rc != LDAP_SUCCESS ) { + goto return_results; + } } /* delete old one */ @@ -762,9 +767,16 @@ retry: /* transaction retry */ (void) bdb_cache_delete_entry(&bdb->bi_cache, e); /* Binary format uses a single contiguous block, cannot - * free individual fields. Leave new_dn/new_ndn set so - * they can be individually freed later. + * free individual fields. But if a previous modrdn has + * already happened, must free the names. */ + if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > + e->e_bv.bv_val + e->e_bv.bv_len ) { + ch_free(e->e_name.bv_val); + ch_free(e->e_nname.bv_val); + e->e_name.bv_val = NULL; + e->e_nname.bv_val = NULL; + } e->e_name = new_dn; e->e_nname = new_ndn; diff --git a/servers/slapd/back-bdb/operational.c b/servers/slapd/back-bdb/operational.c index 8ffb72c2fb..60249c610b 100644 --- a/servers/slapd/back-bdb/operational.c +++ b/servers/slapd/back-bdb/operational.c @@ -27,7 +27,6 @@ bdb_hasSubordinates( Entry *e, int *hasSubordinates ) { - struct bdb_info *bdb = (struct bdb_info *) be->be_private; int rc; assert( e ); diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index fe7a308468..01103d1585 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -171,6 +171,10 @@ void bdb_entry_free ( Entry *e ); /* * idl.c */ +#ifdef SLAP_IDL_CACHE +int bdb_idl_entry_cmp( const void*, const void* ); +#endif + unsigned bdb_idl_search( ID *ids, ID id ); int bdb_bt_compare( diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c index cd7a446041..446b9712ba 100644 --- a/servers/slapd/back-bdb/tools.c +++ b/servers/slapd/back-bdb/tools.c @@ -182,10 +182,10 @@ int bdb_tool_next_id( } else if ( hole ) { if ( nholes == nhmax - 1 ) { if ( holes == hbuf ) { - holes = malloc( nhmax * sizeof(ID) * 2 ); + holes = ch_malloc( nhmax * sizeof(ID) * 2 ); AC_MEMCPY( holes, hbuf, sizeof(hbuf) ); } else { - holes = realloc( holes, nhmax * sizeof(ID) * 2 ); + holes = ch_realloc( holes, nhmax * sizeof(ID) * 2 ); } nhmax *= 2; } diff --git a/servers/slapd/back-ldbm/idl.c b/servers/slapd/back-ldbm/idl.c index 79f55a6ffb..16c3e6da51 100644 --- a/servers/slapd/back-ldbm/idl.c +++ b/servers/slapd/back-ldbm/idl.c @@ -553,14 +553,13 @@ idl_insert_key( #ifndef USE_INDIRECT_NIDS /* select the block to try inserting into *//* XXX linear search XXX */ - for ( i = 0; !ID_BLOCK_NOID(idl, i) && id > ID_BLOCK_ID(idl, i); i++ ) + for ( i = 0; !ID_BLOCK_NOID(idl, i) && id >= ID_BLOCK_ID(idl, i); i++ ) ; /* NULL */ #else i = idl_find(idl, id); - if (ID_BLOCK_ID(idl, i) < id) + if (ID_BLOCK_ID(idl, i) <= id) i++; #endif - if ( i != 0 ) { i--; first = 0; @@ -568,6 +567,11 @@ idl_insert_key( first = 1; } + /* At this point, the following condition must be true: + * ID_BLOCK_ID(idl, i) <= id && id < ID_BLOCK_ID(idl, i+1) + * except when i is the first or the last block. + */ + /* get the block */ cont_alloc( &k2, &key ); cont_id( &k2, ID_BLOCK_ID(idl, i) );