]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Tweak bei_state so cache_lru_add doesn't ever try to free just-added
authorHoward Chu <hyc@openldap.org>
Fri, 1 Dec 2006 14:48:38 +0000 (14:48 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 1 Dec 2006 14:48:38 +0000 (14:48 +0000)
entries. This allows us to use the frontend's entry directly instead
of having to entry_dup it before adding to the cache.

servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/cache.c

index a705c4a9fdb00efc19f3d2d053358ac7079b0080..e5f8f5600d05520eaced9ddee5f9fd8a74b3cf4d 100644 (file)
@@ -26,7 +26,7 @@ bdb_add(Operation *op, SlapReply *rs )
 {
        struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
        struct berval   pdn;
-       Entry           *p = NULL;
+       Entry           *p = NULL, *oe = op->ora_e;
        EntryInfo       *ei;
        char textbuf[SLAP_TEXT_BUFLEN];
        size_t textlen = sizeof textbuf;
@@ -415,17 +415,16 @@ retry:    /* transaction retry */
 
        } else {
                struct berval nrdn;
-               Entry *e = entry_dup( op->ora_e );
 
                /* pick the RDN if not suffix; otherwise pick the entire DN */
                if (pdn.bv_len) {
-                       nrdn.bv_val = e->e_nname.bv_val;
+                       nrdn.bv_val = op->ora_e->e_nname.bv_val;
                        nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1;
                } else {
-                       nrdn = e->e_nname;
+                       nrdn = op->ora_e->e_nname;
                }
 
-               bdb_cache_add( bdb, ei, e, &nrdn, locker );
+               bdb_cache_add( bdb, ei, op->ora_e, &nrdn, locker );
 
                if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
                        rs->sr_text = "txn_commit failed";
@@ -467,9 +466,22 @@ return_results:
                slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
        }
 
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
-               TXN_CHECKPOINT( bdb->bi_dbenv,
-                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+       if( rs->sr_err == LDAP_SUCCESS ) {
+               EntryInfo *ei = op->ora_e->e_private;
+
+               /* We own the entry now, and it can be purged at will
+                * Check to make sure it's the same entry we entered with.
+                * Possibly a callback may have mucked with it, although
+                * in general callbacks should treat the entry as read-only.
+                */
+               if ( op->ora_e == oe )
+                       op->ora_e = NULL;
+               ei->bei_state ^= CACHE_ENTRY_NOT_LINKED;
+
+               if ( bdb->bi_txn_cp_kbyte ) {
+                       TXN_CHECKPOINT( bdb->bi_dbenv,
+                               bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+               }
        }
        return rs->sr_err;
 }
index ad0cd02cc0543fcd02caf9a205cd594211dd7fdb..0c78cd393581a1a8189305db2d7df5900c9e20e6 100644 (file)
@@ -931,7 +931,9 @@ bdb_cache_add(
        }
        new->bei_e = e;
        e->e_private = new;
-       new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
+       /* Set "Not linked" status so LRU purger ignores it */
+       new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS |
+               CACHE_ENTRY_NOT_LINKED;
        eip->bei_state &= ~CACHE_ENTRY_NO_KIDS;
        if (eip->bei_parent) {
                eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS;