]> git.sur5r.net Git - openldap/commitdiff
Sync back-bdb with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Wed, 21 Dec 2005 21:06:26 +0000 (21:06 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 21 Dec 2005 21:06:26 +0000 (21:06 +0000)
13 files changed:
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/bind.c
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/config.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/search.c
servers/slapd/back-bdb/tools.c
servers/slapd/modrdn.c
servers/slapd/proto-slap.h

index a7273ef7c7291ee08cd25018b8bbd62c4c97e231..c9eb98c816e325fbc13cb1536cd475f13f95a9e3 100644 (file)
@@ -34,9 +34,7 @@ bdb_add(Operation *op, SlapReply *rs )
        AttributeDescription *entry = slap_schema.si_ad_entry;
        DB_TXN          *ltid = NULL, *lt2;
        struct bdb_op_info opinfo = {0};
-#ifdef BDB_SUBENTRIES
        int subentry;
-#endif
        u_int32_t       locker = 0;
        DB_LOCK         lock;
 
@@ -65,9 +63,7 @@ bdb_add(Operation *op, SlapReply *rs )
                goto return_results;
        }
 
-#ifdef BDB_SUBENTRIES
        subentry = is_entry_subentry( op->oq_add.rs_e );
-#endif
 
        /*
         * acquire an ID outside of the operation transaction
@@ -196,7 +192,6 @@ retry:      /* transaction retry */
                        goto return_results;;
                }
 
-#ifdef BDB_SUBENTRIES
                if ( is_entry_subentry( p ) ) {
                        /* parent is a subentry, don't allow add */
                        Debug( LDAP_DEBUG_TRACE,
@@ -206,7 +201,6 @@ retry:      /* transaction retry */
                        rs->sr_text = "parent is a subentry";
                        goto return_results;;
                }
-#endif
                if ( is_entry_alias( p ) ) {
                        /* parent is an alias, don't allow add */
                        Debug( LDAP_DEBUG_TRACE,
@@ -233,12 +227,10 @@ retry:    /* transaction retry */
                        goto return_results;
                }
 
-#ifdef BDB_SUBENTRIES
                if ( subentry ) {
                        /* FIXME: */
                        /* parent must be an administrative point of the required kind */
                }
-#endif
 
                /* free parent and reader lock */
                bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
@@ -261,14 +253,6 @@ retry:     /* transaction retry */
                }
        }
 
-       if ( get_assert( op ) &&
-               ( test_filter( op, op->oq_add.rs_e, get_assertion( op ))
-                       != LDAP_COMPARE_TRUE ))
-       {
-               rs->sr_err = LDAP_ASSERTION_FAILED;
-               goto return_results;
-       }
-
        rs->sr_err = access_allowed( op, op->oq_add.rs_e,
                entry, NULL, ACL_WADD, NULL );
 
@@ -320,11 +304,11 @@ retry:    /* transaction retry */
                goto return_results;
        }
 
-       /* id2entry index */
-       rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->oq_add.rs_e );
-       if ( rs->sr_err != 0 ) {
+       /* attribute indexes */
+       rs->sr_err = bdb_index_entry_add( op, lt2, op->oq_add.rs_e );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": id2entry_add failed\n",
+                       LDAP_XSTRING(bdb_add) ": index_entry_add failed\n",
                        0, 0, 0 );
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
@@ -333,15 +317,15 @@ retry:    /* transaction retry */
                default:
                        rs->sr_err = LDAP_OTHER;
                }
-               rs->sr_text = "entry store failed";
+               rs->sr_text = "index generation failed";
                goto return_results;
        }
 
-       /* attribute indexes */
-       rs->sr_err = bdb_index_entry_add( op, lt2, op->oq_add.rs_e );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
+       /* id2entry index */
+       rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->oq_add.rs_e );
+       if ( rs->sr_err != 0 ) {
                Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": index_entry_add failed\n",
+                       LDAP_XSTRING(bdb_add) ": id2entry_add failed\n",
                        0, 0, 0 );
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
@@ -350,9 +334,10 @@ retry:     /* transaction retry */
                default:
                        rs->sr_err = LDAP_OTHER;
                }
-               rs->sr_text = "index generation failed";
+               rs->sr_text = "entry store failed";
                goto return_results;
        }
+
        if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "txn_commit(2) failed";
index 854a9b80ffa927f88ea4f00e201b62f10deaef6d..7190b4d8444c7016a1a43c66bf247e74c5226bbd 100644 (file)
@@ -26,8 +26,6 @@ LDAP_BEGIN_DECL
 
 #define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH)
 
-#define BDB_SUBENTRIES 1
-
 #define DN_BASE_PREFIX         SLAP_INDEX_EQUALITY_PREFIX
 #define DN_ONE_PREFIX          '%'
 #define DN_SUBTREE_PREFIX      '@'
@@ -125,6 +123,7 @@ typedef struct bdb_entry_info {
 typedef struct bdb_cache {
        int             c_maxsize;
        int             c_cursize;
+       int             c_minfree;
        int             c_eiused;       /* EntryInfo's in use */
        int             c_leaves;       /* EntryInfo leaf nodes */
        EntryInfo       c_dntree;
@@ -133,7 +132,8 @@ typedef struct bdb_cache {
        EntryInfo       *c_lruhead;     /* lru - add accessed entries here */
        EntryInfo       *c_lrutail;     /* lru - rem lru entries from here */
        ldap_pvt_thread_rdwr_t c_rwlock;
-       ldap_pvt_thread_mutex_t lru_mutex;
+       ldap_pvt_thread_mutex_t lru_head_mutex;
+       ldap_pvt_thread_mutex_t lru_tail_mutex;
        u_int32_t       c_locker;       /* used by lru cleaner */
 #ifdef SLAP_ZONE_ALLOC
        void *c_zctx;
@@ -177,6 +177,7 @@ struct bdb_info {
        u_int32_t       bi_txn_cp_kbyte;
        void            *bi_txn_cp_task;
        void            *bi_index_task;
+       void            *bi_cache_task;
 
        int                     bi_lock_detect;
        long            bi_shm_key;
index 69d37564624622c771b70112e81f286fb095037b..ed76a6283ffb5f05088ad09ca141357de4135a0b 100644 (file)
@@ -104,7 +104,6 @@ dn2entry_retry:
        ber_dupbv( &op->oq_bind.rb_edn, &e->e_name );
 
        /* check for deleted */
-#ifdef BDB_SUBENTRIES
        if ( is_entry_subentry( e ) ) {
                /* entry is an subentry, don't allow bind */
                Debug( LDAP_DEBUG_TRACE, "entry is subentry\n", 0,
@@ -112,7 +111,6 @@ dn2entry_retry:
                rs->sr_err = LDAP_INVALID_CREDENTIALS;
                goto done;
        }
-#endif
 
        if ( is_entry_alias( e ) ) {
                /* entry is an alias, don't allow bind */
index 92711b243b17b76845e15a077a714c9f91e7a7eb..4c4f7418ffed5f9e9eb001e630cf2250cf23c46e 100644 (file)
 
 #include "back-bdb.h"
 
+#include "ldap_rq.h"
+
 #ifdef BDB_HIER
 #define bdb_cache_lru_add      hdb_cache_lru_add
 #endif
+static void bdb_cache_lru_add( struct bdb_info *bdb, EntryInfo *ei );
 
 static int     bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr);
 #ifdef LDAP_DEBUG
@@ -460,9 +463,8 @@ hdb_cache_find_parent(
                ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
 
                if ( addlru ) {
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
-                       LRU_ADD( &bdb->bi_cache, ein );
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_mutex );
+                       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_head_mutex );
+                       bdb_cache_lru_add( bdb, ein );
                }
                addlru = 1;
 
@@ -527,94 +529,131 @@ int hdb_cache_load(
 }
 #endif
 
-/* caller must have lru_mutex locked. mutex
- * will be unlocked on return.
- */
-static void
-bdb_cache_lru_add(
-       struct bdb_info *bdb,
-       u_int32_t       locker,
-       EntryInfo *ei )
+static void *
+bdb_cache_lru_purge(void *ctx, void *arg)
 {
+       struct re_s *rtask = arg;
+       struct bdb_info *bdb = rtask->arg;
        DB_LOCK         lock, *lockp;
+       EntryInfo *elru, *elprev;
+       int count = 0;
 
-       if ( locker ) {
+       if ( bdb->bi_cache.c_locker ) {
                lockp = &lock;
        } else {
                lockp = NULL;
        }
 
-       /* See if we're above the cache size limit */
-       if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) {
-               EntryInfo *elru, *elprev;
-               int i = 0;
-
-               /* Look for an unused entry to remove */
-               for (elru = bdb->bi_cache.c_lrutail; elru; elru = elprev, i++ ) {
-                       elprev = elru->bei_lruprev;
+       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_tail_mutex );
 
-                       /* Too many probes, not enough idle, give up */
-                       if (i > 10)
-                               break;
+       /* Look for an unused entry to remove */
+       for (elru = bdb->bi_cache.c_lrutail; elru; elru = elprev ) {
+               elprev = elru->bei_lruprev;
 
-                       /* If we can successfully writelock it, then
-                        * the object is idle.
-                        */
-                       if ( bdb_cache_entry_db_lock( bdb->bi_dbenv,
-                                       bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
+               /* If we can successfully writelock it, then
+                * the object is idle.
+                */
+               if ( bdb_cache_entry_db_lock( bdb->bi_dbenv,
+                               bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
 
-                               int stop = 0, decr = 0;
+                       int stop = 0;
 
-                               /* If this node is in the process of linking into the cache,
-                                * or this node is being deleted, skip it.
-                                */
-                               if ( elru->bei_state &
-                                       ( CACHE_ENTRY_NOT_LINKED | CACHE_ENTRY_DELETED )) {
-                                       bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
-                                       continue;
-                               }
-                               /* Free entry for this node if it's present */
-                               if ( elru->bei_e ) {
-                                       elru->bei_e->e_private = NULL;
+                       /* If this node is in the process of linking into the cache,
+                        * or this node is being deleted, skip it.
+                        */
+                       if ( elru->bei_state &
+                               ( CACHE_ENTRY_NOT_LINKED | CACHE_ENTRY_DELETED )) {
+                               bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
+                               continue;
+                       }
+                       /* Free entry for this node if it's present */
+                       if ( elru->bei_e ) {
+                               elru->bei_e->e_private = NULL;
 #ifdef SLAP_ZONE_ALLOC
-                                       bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
+                               bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
 #else
-                                       bdb_entry_return( elru->bei_e );
+                               bdb_entry_return( elru->bei_e );
 #endif
-                                       elru->bei_e = NULL;
-                                       decr = 1;
-                               }
-                               /* ITS#4010 if we're in slapcat, and this node is a leaf
-                                * node, free it.
-                                *
-                                * FIXME: we need to do this for slapd as well, (which is
-                                * why we compute bi_cache.c_leaves now) but at the moment
-                                * we can't because it causes unresolvable deadlocks. 
-                                */
-                               if ( slapMode & SLAP_TOOL_READONLY ) {
-                                       if ( !elru->bei_kids ) {
-                                               /* This does LRU_DELETE for us */
-                                               bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
-                                               bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
-                                       }
-                                       /* Leave node on LRU list for a future pass */
-                               } else {
-                                       LRU_DELETE( &bdb->bi_cache, elru );
+                               elru->bei_e = NULL;
+                               count++;
+                       }
+                       /* ITS#4010 if we're in slapcat, and this node is a leaf
+                        * node, free it.
+                        *
+                        * FIXME: we need to do this for slapd as well, (which is
+                        * why we compute bi_cache.c_leaves now) but at the moment
+                        * we can't because it causes unresolvable deadlocks. 
+                        */
+                       if ( slapMode & SLAP_TOOL_READONLY ) {
+                               if ( !elru->bei_kids ) {
+                                       /* This does LRU_DELETE for us */
+                                       bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
+                                       bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
                                }
-                               bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
+                               /* Leave node on LRU list for a future pass */
+                       } else {
+                               LRU_DELETE( &bdb->bi_cache, elru );
+                       }
+                       bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
 
+                       if ( count == bdb->bi_cache.c_minfree ) {
                                ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-                               if ( decr )
-                                       --bdb->bi_cache.c_cursize;
-                               if (bdb->bi_cache.c_cursize <= bdb->bi_cache.c_maxsize)
+                               bdb->bi_cache.c_cursize -= bdb->bi_cache.c_minfree;
+                               if ( bdb->bi_cache.c_maxsize - bdb->bi_cache.c_cursize >=
+                                       bdb->bi_cache.c_minfree )
                                        stop = 1;
+                               count = 0;
                                ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-                               if (stop) break;
                        }
+                       if (stop) break;
+               }
+       }
+
+       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_tail_mutex );
+
+       /* If we're running as a task, drop the task */
+       if ( ctx ) {
+               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+               ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );
+               /* Defer processing till we're needed again */
+               ldap_pvt_runqueue_resched( &slapd_rq, rtask, 1 );
+               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
                }
        }
+
+/* caller must have lru_head_mutex locked. mutex
+ * will be unlocked on return.
+ */
+static void
+bdb_cache_lru_add(
+       struct bdb_info *bdb,
+       EntryInfo *ei )
+{
        LRU_ADD( &bdb->bi_cache, ei );
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_mutex );
+       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_head_mutex );
+
+       /* See if we're above the cache size limit */
+       if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) {
+               if ( slapMode & SLAP_TOOL_MODE ) {
+                       struct re_s rtask;
+
+                       rtask.arg = bdb;
+                       bdb_cache_lru_purge( NULL, &rtask );
+               } else {
+                       ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+                       if ( bdb->bi_cache_task ) {
+                               if ( !ldap_pvt_runqueue_isrunning( &slapd_rq,
+                                       bdb->bi_cache_task ))
+                                       ldap_pvt_runqueue_resched( &slapd_rq, bdb->bi_cache_task,
+                                               0 );
+                       } else {
+                               bdb->bi_cache_task = ldap_pvt_runqueue_insert( &slapd_rq, 0,
+                                       bdb_cache_lru_purge, bdb, "bdb_cache_lru_purge",
+                                       bdb->bi_dbenv_home );
+                       }
+                       ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+               }
+       }
 }
 
 EntryInfo *
@@ -821,22 +860,23 @@ load1:
                        ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
                }
 
-               ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
+               ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_head_mutex );
 
                /* If the LRU list has only one entry and this is it, it
                 * doesn't need to be added again.
                 */
                if ( bdb->bi_cache.c_lruhead == bdb->bi_cache.c_lrutail &&
                        bdb->bi_cache.c_lruhead == *eip ) {
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_mutex );
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_head_mutex );
                } else {
-
                        /* if entry is on LRU list, remove from old spot */
                        if ( (*eip)->bei_lrunext || (*eip)->bei_lruprev ) {
+                               ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_tail_mutex );
                                LRU_DELETE( &bdb->bi_cache, *eip );
+                               ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_tail_mutex );
                        }
-                       /* lru_mutex is unlocked for us */
-                       bdb_cache_lru_add( bdb, locker, *eip );
+                       /* lru_head_mutex is unlocked for us */
+                       bdb_cache_lru_add( bdb, *eip );
                }
        }
 
@@ -933,10 +973,10 @@ bdb_cache_add(
        ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
 
        /* set lru mutex */
-       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
+       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_head_mutex );
 
-       /* lru_mutex is unlocked for us */
-       bdb_cache_lru_add( bdb, locker, new );
+       /* lru_head_mutex is unlocked for us */
+       bdb_cache_lru_add( bdb, new );
 
        return rc;
 }
@@ -1082,7 +1122,7 @@ bdb_cache_delete(
                e->e_id, 0, 0 );
 
        /* set lru mutex */
-       ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
+       ldap_pvt_thread_mutex_lock( &cache->lru_tail_mutex );
 
        /* set cache write lock */
        ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
@@ -1093,7 +1133,7 @@ bdb_cache_delete(
        ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
        /* free lru mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
+       ldap_pvt_thread_mutex_unlock( &cache->lru_tail_mutex );
 
        /* Leave entry info locked */
 
@@ -1201,7 +1241,7 @@ bdb_cache_release_all( Cache *cache )
        /* set cache write lock */
        ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
        /* set lru mutex */
-       ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
+       ldap_pvt_thread_mutex_lock( &cache->lru_tail_mutex );
 
        Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_release_all\n", 0, 0, 0 );
 
@@ -1220,7 +1260,7 @@ bdb_cache_release_all( Cache *cache )
        cache->c_dntree.bei_kids = NULL;
 
        /* free lru mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
+       ldap_pvt_thread_mutex_unlock( &cache->lru_tail_mutex );
        /* free cache write lock */
        ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 }
index d9f00f210f6caa59ed1669b340191133bf7f4d51..6445e5fca947186bbf55bf40078c6c6ca3598600 100644 (file)
@@ -55,6 +55,11 @@ static ConfigTable bdbcfg[] = {
                        "DESC 'Directory for database content' "
                        "EQUALITY caseIgnoreMatch "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "cachefree", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,
+               (void *)offsetof(struct bdb_info, bi_cache.c_minfree),
+               "( OLcfgDbAt:1.11 NAME 'olcDbCacheFree' "
+                       "DESC 'Number of extra entries to free when max is reached' "
+                       "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "cachesize", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,
                (void *)offsetof(struct bdb_info, bi_cache.c_maxsize),
                "( OLcfgDbAt:1.1 NAME 'olcDbCacheSize' "
@@ -134,7 +139,8 @@ static ConfigOCs bdbocs[] = {
                "MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ "
                "olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ "
                "olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ "
-               "olcDbMode $ olcDbSearchStack $ olcDbShmKey ) )",
+               "olcDbMode $ olcDbSearchStack $ olcDbShmKey $ "
+               " olcDbCacheFree ) )",
                        Cft_Database, bdbcfg },
        { NULL, 0, NULL }
 };
index a1bef6cccd343e35ffd38373300bc24af5a6468d..51ff92220f891b1ee06cabc6f555f311abb534e0 100644 (file)
@@ -369,34 +369,53 @@ retry:    /* transaction retry */
                goto return_results;
        }
 
-       /* delete from id2entry */
-       rs->sr_err = bdb_id2entry_delete( op->o_bd, lt2, e );
-       if ( rs->sr_err != 0 ) {
+       /* delete indices for old attributes */
+       rs->sr_err = bdb_index_entry_del( op, lt2, e );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug(LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_delete) ": id2entry failed: "
+                       "<=- " LDAP_XSTRING(bdb_delete) ": index failed: "
                        "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
                        goto retry;
                }
-               rs->sr_text = "entry delete failed";
+               rs->sr_text = "entry index delete failed";
                rs->sr_err = LDAP_OTHER;
                goto return_results;
        }
 
-       /* delete indices for old attributes */
-       rs->sr_err = bdb_index_entry_del( op, lt2, e );
+       /* fixup delete CSN */
+       if ( !SLAP_SHADOW( op->o_bd )) {
+               struct berval vals[2];
+               vals[0] = op->o_csn;
+               BER_BVZERO( vals+1 );
+               rs->sr_err = bdb_index_values( op, lt2, slap_schema.si_ad_entryCSN,
+                       vals, 0, SLAP_INDEX_ADD_OP );
        if ( rs->sr_err != LDAP_SUCCESS ) {
+                       switch( rs->sr_err ) {
+                       case DB_LOCK_DEADLOCK:
+                       case DB_LOCK_NOTGRANTED:
+                               goto retry;
+                       }
+                       rs->sr_text = "entryCSN index update failed";
+                       rs->sr_err = LDAP_OTHER;
+                       goto return_results;
+               }
+       }
+
+       /* delete from id2entry */
+       rs->sr_err = bdb_id2entry_delete( op->o_bd, lt2, e );
+       if ( rs->sr_err != 0 ) {
                Debug( LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_delete) ": index failed: "
+                       "<=- " LDAP_XSTRING(bdb_delete) ": id2entry failed: "
                        "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
                        goto retry;
                }
-               rs->sr_text = "entry index delete failed";
+               rs->sr_text = "entry delete failed";
                rs->sr_err = LDAP_OTHER;
                goto return_results;
        }
index 991bbc033f264c15bf214067cbfb27c73571b380..e9bbf375ace2d7f9854e31cd3534071e3c730aa1 100644 (file)
@@ -69,7 +69,8 @@ bdb_db_init( BackendDB *be )
 #ifdef BDB_HIER
        ldap_pvt_thread_mutex_init( &bdb->bi_modrdns_mutex );
 #endif
-       ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_mutex );
+       ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_head_mutex );
+       ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_tail_mutex );
        ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex );
        ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
        ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
@@ -564,13 +565,14 @@ bdb_db_close( BackendDB *be )
                bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL;
        }
 
-       if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_dbenv ) {
-               XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker);
-               bdb->bi_cache.c_locker = 0;
-       }
-
        /* close db environment */
        if( bdb->bi_dbenv ) {
+               /* Free cache locker if we enabled locking */
+               if ( !( slapMode & SLAP_TOOL_QUICK )) {
+                       XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker);
+                       bdb->bi_cache.c_locker = 0;
+               }
+
                /* force a checkpoint, but not if we were ReadOnly,
                 * and not in Quick mode since there are no transactions there.
                 */
@@ -614,7 +616,8 @@ bdb_db_destroy( BackendDB *be )
        bdb_attr_index_destroy( bdb );
 
        ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_mutex );
+       ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_head_mutex );
+       ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_tail_mutex );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex );
 #ifdef BDB_HIER
        ldap_pvt_thread_mutex_destroy( &bdb->bi_modrdns_mutex );
@@ -653,9 +656,7 @@ bdb_back_initialize(
 
        bi->bi_flags |=
                SLAP_BFLAG_INCREMENT |
-#ifdef BDB_SUBENTRIES
                SLAP_BFLAG_SUBENTRIES |
-#endif
                SLAP_BFLAG_ALIASES |
                SLAP_BFLAG_REFERRALS;
 
index a1aeb801fc30adf5117026fd3789562879af2f2a..eac99229296bb3e7b0e3c0d55dcb412f79e3a083 100644 (file)
@@ -91,7 +91,9 @@ int bdb_modify_internal(
 
                switch ( mod->sm_op ) {
                case LDAP_MOD_ADD:
-                       Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: add\n", 0, 0, 0);
+                       Debug(LDAP_DEBUG_ARGS,
+                               "bdb_modify_internal: add %s\n",
+                               mod->sm_desc->ad_cname.bv_val, 0, 0);
                        err = modify_add_values( e, mod, get_permissiveModify(op),
                                text, textbuf, textlen );
                        if( err != LDAP_SUCCESS ) {
@@ -106,7 +108,9 @@ int bdb_modify_internal(
                                break;
                        }
 
-                       Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: delete\n", 0, 0, 0);
+                       Debug(LDAP_DEBUG_ARGS,
+                               "bdb_modify_internal: delete %s\n",
+                               mod->sm_desc->ad_cname.bv_val, 0, 0);
                        err = modify_delete_values( e, mod, get_permissiveModify(op),
                                text, textbuf, textlen );
                        assert( err != LDAP_TYPE_OR_VALUE_EXISTS );
@@ -117,7 +121,9 @@ int bdb_modify_internal(
                        break;
 
                case LDAP_MOD_REPLACE:
-                       Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: replace\n", 0, 0, 0);
+                       Debug(LDAP_DEBUG_ARGS,
+                               "bdb_modify_internal: replace %s\n",
+                               mod->sm_desc->ad_cname.bv_val, 0, 0);
                        err = modify_replace_values( e, mod, get_permissiveModify(op),
                                text, textbuf, textlen );
                        if( err != LDAP_SUCCESS ) {
@@ -128,7 +134,8 @@ int bdb_modify_internal(
 
                case LDAP_MOD_INCREMENT:
                        Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: increment\n", 0, 0, 0);
+                               "bdb_modify_internal: increment %s\n",
+                               mod->sm_desc->ad_cname.bv_val, 0, 0);
                        err = modify_increment_values( e, mod, get_permissiveModify(op),
                                text, textbuf, textlen );
                        if( err != LDAP_SUCCESS ) {
@@ -139,7 +146,9 @@ int bdb_modify_internal(
                        break;
 
                case SLAP_MOD_SOFTADD:
-                       Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: softadd\n", 0, 0, 0);
+                       Debug(LDAP_DEBUG_ARGS,
+                               "bdb_modify_internal: softadd %s\n",
+                               mod->sm_desc->ad_cname.bv_val, 0, 0);
                        /* Avoid problems in index_add_mods()
                         * We need to add index if necessary.
                         */
index 422420dcafc84e0c2d582fe274b073b1fff3bf9b..6a25d2882d0d49ac1844bc5c8b812039fde36463 100644 (file)
@@ -796,22 +796,13 @@ done:
        if ( new_rdn != NULL ) {
                ldap_rdnfree_x( new_rdn, op->o_tmpmemctx );
        }
+
        if ( old_rdn != NULL ) {
                ldap_rdnfree_x( old_rdn, op->o_tmpmemctx );
        }
+
        if( mod != NULL ) {
-               Modifications *tmp;
-               for (; mod; mod=tmp ) {
-                       tmp = mod->sml_next;
-                       /* slap_modrdn2mods does things one way,
-                        * slap_mods_opattrs does it differently
-                        */
-                       if ( mod->sml_op != SLAP_MOD_SOFTADD &&
-                               mod->sml_op != LDAP_MOD_DELETE ) break;
-                       if ( mod->sml_nvalues ) free( mod->sml_nvalues[0].bv_val );
-                       free( mod );
-               }
-               slap_mods_free( mod, 1 );
+               slap_modrdn2mods_free( mod );
        }
 
        /* LDAP v3 Support */
index e39c23daf936a4b45e73340ca72e600f92e5fb5b..df70a4357a08c6d824d96f8f2d9c57072ae2be1d 100644 (file)
@@ -465,7 +465,7 @@ dn2entry_retry:
 #endif
                        rs->sr_ref = referral_rewrite( default_referral,
                                NULL, &op->o_req_dn, op->oq_search.rs_scope );
-                       rs->sr_err = LDAP_REFERRAL;
+                       rs->sr_err = rs->sr_ref != NULL ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;
                }
 
                send_ldap_result( op, rs );
@@ -726,28 +726,24 @@ fetch_entry_retry:
 
                rs->sr_entry = e;
 
-#ifdef BDB_SUBENTRIES
-               {
-                       if ( is_entry_subentry( e ) ) {
-                               if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) {
-                                       if(!get_subentries_visibility( op )) {
-                                               /* only subentries are visible */
-                                               goto loop_continue;
-                                       }
-
-                               } else if ( get_subentries( op ) &&
-                                       !get_subentries_visibility( op ))
-                               {
+               if ( is_entry_subentry( e ) ) {
+                       if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) {
+                               if(!get_subentries_visibility( op )) {
                                        /* only subentries are visible */
                                        goto loop_continue;
                                }
 
-                       } else if ( get_subentries_visibility( op )) {
+                       } else if ( get_subentries( op ) &&
+                               !get_subentries_visibility( op ))
+                       {
                                /* only subentries are visible */
                                goto loop_continue;
                        }
+
+               } else if ( get_subentries_visibility( op )) {
+                       /* only subentries are visible */
+                       goto loop_continue;
                }
-#endif /* BDB_SUBENTRIES */
 
                /* Does this candidate actually satisfy the search scope?
                 *
@@ -1051,13 +1047,11 @@ static int search_candidates(
 #else
        AttributeAssertion aa_ref = { NULL, BER_BVNULL };
 #endif
-#ifdef BDB_SUBENTRIES
        Filter  sf;
 #ifdef LDAP_COMP_MATCH
        AttributeAssertion aa_subentry = { NULL, BER_BVNULL, NULL };
 #else
        AttributeAssertion aa_subentry = { NULL, BER_BVNULL };
-#endif
 #endif
 
        /*
@@ -1104,7 +1098,6 @@ static int search_candidates(
        /* Filter depth increased again, adding dummy clause */
        depth++;
 
-#ifdef BDB_SUBENTRIES
        if( get_subentries_visibility( op ) ) {
                struct berval bv_subentry = BER_BVC( "subentry" );
                sf.f_choice = LDAP_FILTER_EQUALITY;
@@ -1114,7 +1107,6 @@ static int search_candidates(
                sf.f_next = nf.f_next;
                nf.f_next = &sf;
        }
-#endif
 
        /* Allocate IDL stack, plus 1 more for former tmp */
        if ( depth+1 > bdb->bi_search_stack_depth ) {
index 9c970484852598698839d547f65f08041d0d7f96..91b5226474ffd6a25b76b6c944dd66aec0171b3d 100644 (file)
@@ -483,11 +483,11 @@ ID bdb_tool_entry_put(
                goto done;
        }
 
-       /* id2entry index */
-       rc = bdb_id2entry_add( be, tid, e );
+       if ( !bdb->bi_linear_index )
+               rc = bdb_tool_index_add( &op, tid, e );
        if( rc != 0 ) {
                snprintf( text->bv_val, text->bv_len,
-                               "id2entry_add failed: %s (%d)",
+                               "index_entry_add failed: %s (%d)",
                                db_strerror(rc), rc );
                Debug( LDAP_DEBUG_ANY,
                        "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
@@ -495,11 +495,11 @@ ID bdb_tool_entry_put(
                goto done;
        }
 
-       if ( !bdb->bi_linear_index )
-               rc = bdb_tool_index_add( &op, tid, e );
+       /* id2entry index */
+       rc = bdb_id2entry_add( be, tid, e );
        if( rc != 0 ) {
                snprintf( text->bv_val, text->bv_len,
-                               "index_entry_add failed: %s (%d)",
+                               "id2entry_add failed: %s (%d)",
                                db_strerror(rc), rc );
                Debug( LDAP_DEBUG_ANY,
                        "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
@@ -688,33 +688,6 @@ ID bdb_tool_entry_modify(
                goto done;
        }
 
-#if 0
-       /* FIXME: this is bogus, we don't have the old values to delete
-        * from the index because the given entry has already been modified.
-        */
-       rc = bdb_index_entry_del( &op, tid, e );
-       if( rc != 0 ) {
-               snprintf( text->bv_val, text->bv_len,
-                               "index_entry_del failed: %s (%d)",
-                               db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
-                       text->bv_val, 0, 0 );
-               goto done;
-       }
-#endif
-
-       rc = bdb_index_entry_add( &op, tid, e );
-       if( rc != 0 ) {
-               snprintf( text->bv_val, text->bv_len,
-                               "index_entry_add failed: %s (%d)",
-                               db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
-                       text->bv_val, 0, 0 );
-               goto done;
-       }
-
 done:
        if( rc == 0 ) {
                if (! (slapMode & SLAP_TOOL_QUICK)) {
index e455d71a8a11f11b826d76f327379d1e4d393de8..39165a37b03c9d4fe3f1c24150918cecd750e3b8 100644 (file)
@@ -291,7 +291,7 @@ fe_op_modrdn( Operation *op, SlapReply *rs )
                int repl_user = be_isupdate( op );
 #ifndef SLAPD_MULTIMASTER
                if ( !SLAP_SHADOW(op->o_bd) || repl_user )
-#endif
+#endif /* ! SLAPD_MULTIMASTER */
                {
                        slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
 
@@ -299,7 +299,7 @@ fe_op_modrdn( Operation *op, SlapReply *rs )
 
 #ifdef SLAPD_MULTIMASTER
                        if ( !op->o_bd->be_update_ndn.bv_len || !repl_user )
-#endif
+#endif /* SLAPD_MULTIMASTER */
                        {
                                cb.sc_next = op->o_callback;
                                op->o_callback = &cb;
@@ -363,7 +363,7 @@ fe_op_modrdn( Operation *op, SlapReply *rs )
                                send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                                        "shadow context; no update referral" );
                        }
-#endif
+#endif /* ! SLAPD_MULTIMASTER */
                }
        } else {
                send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
@@ -519,3 +519,30 @@ done:
 
        return rs->sr_err;
 }
+
+void
+slap_modrdn2mods_free( Modifications *mod )
+{
+       Modifications *tmp;
+
+       for ( ; mod; mod = tmp ) {
+               tmp = mod->sml_next;
+               /* slap_modrdn2mods does things one way,
+                * slap_mods_opattrs does it differently
+                */
+               if ( mod->sml_op != SLAP_MOD_SOFTADD &&
+                       mod->sml_op != LDAP_MOD_DELETE )
+               {
+                       break;
+               }
+
+               if ( mod->sml_nvalues ) {
+                       free( mod->sml_nvalues[0].bv_val );
+               }
+
+               free( mod );
+       }
+
+       slap_mods_free( mod, 1 );
+}
+
index fee6bf45471e73a2921dab8a900ea1d2b06e05b3..80111489fef58d62408194a9d4b9205f543125d5 100644 (file)
@@ -1016,13 +1016,15 @@ LDAP_SLAPD_F (int) filter_matched_values(
 /*
  * modrdn.c
  */
-LDAP_SLAPD_F (int) slap_modrdn2mods(
+LDAP_SLAPD_F (int) slap_modrdn2mods LDAP_P((
        Operation       *op,
        SlapReply       *rs,
        Entry           *e,
        LDAPRDN         oldrdn,
        LDAPRDN         newrdn,
-       Modifications   **pmod );
+       Modifications   **pmod ));
+
+LDAP_SLAPD_F (void) slap_modrdn2mods_free LDAP_P(( Modifications *mod ));
 
 /*
  * modify.c