From eb47d50da76a6a37ecbe6e4c8e78f7c3331efcba Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 1 Dec 2006 14:48:38 +0000 Subject: [PATCH] Tweak bei_state so cache_lru_add doesn't ever try to free just-added 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 | 28 ++++++++++++++++++++-------- servers/slapd/back-bdb/cache.c | 4 +++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index a705c4a9fd..e5f8f5600d 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -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; } diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index ad0cd02cc0..0c78cd3935 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -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; -- 2.47.2