]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Suck in BDB changes including fixes for
authorKurt Zeilenga <kurt@openldap.org>
Thu, 13 Mar 2003 04:35:26 +0000 (04:35 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Thu, 13 Mar 2003 04:35:26 +0000 (04:35 +0000)
and LDBM idl fixes

servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/operational.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/tools.c
servers/slapd/back-ldbm/idl.c

index 079b44081ca4e2b3155167a3924e99be92b35422..c97bd6bb42c0d1a356fdac4e295c97071b64d146 100644 (file)
@@ -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;
        }
 
index 1454e18f93967a9112d8e025db9bec0c2d1274cb..5d7f321857e43aca864e412703ecded9c8b110ee 100644 (file)
@@ -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";
index 8e0669ea0263917ec90d58311f6b73d0ac59e822..db9d00f914dfee8307b1504ae1943e8604550058 100644 (file)
 #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;
@@ -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 );
index 167938a9605af9f4c25798b9987c15019d418759..7e71175130661520d143f62a164ecde7fb4c4cb2 100644 (file)
@@ -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;
 }
 
index 94745198f785730043f8d652474f1cf43f896e6e..7365a2d6551412839a2e3edfec0f26922e9308b1 100644 (file)
@@ -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;
 
index 8ffb72c2fb01db2f7741117a3cccd5283c6faaa9..60249c610bb3479c0df1b59d130dab925d33333e 100644 (file)
@@ -27,7 +27,6 @@ bdb_hasSubordinates(
        Entry           *e,
        int             *hasSubordinates )
 {
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        int             rc;
        
        assert( e );
index fe7a308468aa4f385212dd1b513b14cb12c10f8a..01103d1585597e3bff6ea8be5ddb4694ef420296 100644 (file)
@@ -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(
index cd7a4460412582d98e7806d4b3979ffa99bb40e9..446b9712bacc0cf48c594c08d65ffed5e46c6b0a 100644 (file)
@@ -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;
                        }
index 79f55a6ffbf8e5d0af7a90d5ed62e77be592320b..16c3e6da519b6b7decbdaee40696cf4a07d909cc 100644 (file)
@@ -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) );