case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
- default:
- rc = LDAP_OTHER;
}
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
db_strerror(rc), rc, 0 );
#endif
text = "DN index delete failed";
+ rc = LDAP_OTHER;
goto return_results;
}
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
- default:
- rc = LDAP_OTHER;
}
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
db_strerror(rc), rc, 0 );
#endif
text = "entry delete failed";
+ rc = LDAP_OTHER;
goto return_results;
}
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
- default:
- rc = LDAP_OTHER;
}
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
0, 0, 0 );
#endif
text = "entry index delete failed";
+ rc = LDAP_OTHER;
goto return_results;
}
} \
} 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;
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;
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 );
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 );
/* 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 ) {
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";
#include <ac/unistd.h>
#include <ac/stdlib.h>
-#include <lutil.h>
-
#include "back-bdb.h"
#include "external.h"
+#include <lutil.h>
static struct bdbi_database {
char *file;
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 );
}
}
+ /* 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;
}
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);
}
/* 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,
/* 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
#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
}
/* 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 */
(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;
Entry *e,
int *hasSubordinates )
{
- struct bdb_info *bdb = (struct bdb_info *) be->be_private;
int rc;
assert( 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(
} 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;
}
#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;
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) );