andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 57852e959b6f121eefb0c0c4ff2adc79b2125934 Mon Sep 17 00:00:00 2001
dc8c34
From: Mark Reynolds <mreynolds@redhat.com>
dc8c34
Date: Fri, 12 Sep 2014 11:14:24 -0400
dc8c34
Subject: [PATCH] Ticket 47750 - Fix incomplete backport to 1.3.1/1.2.11
dc8c34
dc8c34
Description:  An incomplete backport of 47750 to 1.3.1 and 1.2.11 caused
dc8c34
              a memory leak.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/47750
dc8c34
dc8c34
Reviewed by: rmeggins(Thanks!)
dc8c34
dc8c34
(cherry picked from commit 0b5f0d68233cec976d57597d1c810b79c62528a5)
dc8c34
(cherry picked from commit 649e726834820abc0ab6bdfb90806e2dec4391db)
dc8c34
---
dc8c34
 ldap/servers/slapd/back-ldbm/ldbm_delete.c | 74 +++++++++++-------------------
dc8c34
 1 file changed, 26 insertions(+), 48 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
dc8c34
index 23529dc..32c119c 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
dc8c34
@@ -673,54 +673,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
dc8c34
 				goto error_return;
dc8c34
 			}
dc8c34
 			if (tombstone_in_cache) {
dc8c34
-				retval = cache_replace(&inst->inst_cache, e, tombstone);
dc8c34
-				if (retval) {
dc8c34
-					LDAPDebug(LDAP_DEBUG_CACHE, "ldbm_back_delete: cache_replace failed (%d): %s --> %s\n",
dc8c34
-					          retval, slapi_entry_get_dn(e->ep_entry), slapi_entry_get_dn(tombstone->ep_entry));
dc8c34
-					retval= -1;
dc8c34
-					DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
dc8c34
-					goto error_return;
dc8c34
-				} else {
dc8c34
-					e_in_cache = 0;
dc8c34
-				}
dc8c34
-			} else {
dc8c34
-				struct backentry *imposter = NULL;
dc8c34
-				retval = CACHE_ADD(&inst->inst_cache, tombstone, &imposter);
dc8c34
-				if (retval > 0) {
dc8c34
-					if (imposter) {
dc8c34
-						/* 
dc8c34
-						 * The same tombstone entry (different Slapi_Entry) is already
dc8c34
-						 * generated and set to cache.  Back off. 
dc8c34
-						 */
dc8c34
-						CACHE_RETURN(&inst->inst_cache, &imposter);
dc8c34
-						LDAPDebug1Arg(LDAP_DEBUG_CACHE, 
dc8c34
-						              "ldbm_delete: cache add: same DN tombstone in cache: %s\n",
dc8c34
-						              slapi_entry_get_dn(tombstone->ep_entry));
dc8c34
-					} else {
dc8c34
-						/* 
dc8c34
-						 * The same tombstone entry (same Slapi_Entry) is being created.
dc8c34
-						 * Something is wrong.  We should clean it up from the cache,
dc8c34
-						 * and back off.
dc8c34
-						 */
dc8c34
-						tombstone_in_cache = 1;
dc8c34
-						LDAPDebug1Arg(LDAP_DEBUG_CACHE, 
dc8c34
-						              "ldbm_delete: cache add: same tombstone in cache: %s\n",
dc8c34
-						              slapi_entry_get_dn(tombstone->ep_entry));
dc8c34
-					}
dc8c34
-					retval= -1;
dc8c34
-					DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
dc8c34
-					goto error_return;
dc8c34
-				} else if (retval < 0) {
dc8c34
-					LDAPDebug1Arg(LDAP_DEBUG_CACHE, 
dc8c34
-					              "ldbm_delete: cache add: Add %s failed.\n",
dc8c34
-					              slapi_entry_get_dn(tombstone->ep_entry));
dc8c34
-					/* Complete add error */
dc8c34
-					retval= -1;
dc8c34
-					DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
dc8c34
-					goto error_return;
dc8c34
-				}
dc8c34
-			}
dc8c34
-			if (tombstone_in_cache) {
dc8c34
 				/* tombstone was already added to the cache via cache_add_tentative (to reserve its spot in the cache)
dc8c34
 				   and/or id2entry_add - so it already had one refcount - cache_replace adds another refcount -
dc8c34
 				   drop the extra ref added by cache_replace */
dc8c34
@@ -1130,6 +1082,16 @@ ldbm_back_delete( Slapi_PBlock *pb )
dc8c34
 		goto error_return;
dc8c34
 	}
dc8c34
 
dc8c34
+	if (create_tombstone_entry) {
dc8c34
+		retval = cache_replace(&inst->inst_cache, e, tombstone);
dc8c34
+		if (retval) {
dc8c34
+			LDAPDebug(LDAP_DEBUG_CACHE, "ldbm_back_delete: cache_replace failed (%d): %s --> %s\n",
dc8c34
+			        retval, slapi_entry_get_dn(e->ep_entry), slapi_entry_get_dn(tombstone->ep_entry));
dc8c34
+			retval= -1;
dc8c34
+			goto error_return;
dc8c34
+		}
dc8c34
+	}
dc8c34
+
dc8c34
 	/* call the transaction post delete plugins just before the commit */
dc8c34
 	if (plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN)) {
dc8c34
 		LDAPDebug0Args( LDAP_DEBUG_ANY, "SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN plugin "
dc8c34
@@ -1333,6 +1295,22 @@ common_return:
dc8c34
 		plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_DELETE_FN);
dc8c34
 	}
dc8c34
 
dc8c34
+	if (e) {
dc8c34
+		if (e_in_cache) {
dc8c34
+			if (remove_e_from_cache) {
dc8c34
+				/* The entry is already transformed to a tombstone. */
dc8c34
+				CACHE_REMOVE( &inst->inst_cache, e );
dc8c34
+			}
dc8c34
+		}
dc8c34
+		cache_unlock_entry( &inst->inst_cache, e );
dc8c34
+		CACHE_RETURN( &inst->inst_cache, &e );
dc8c34
+		/*
dc8c34
+		 * e is unlocked and no longer in cache.
dc8c34
+		 * It could be freed at any moment.
dc8c34
+		 */
dc8c34
+		e = NULL;
dc8c34
+	}
dc8c34
+
dc8c34
 	if (ruv_c_init) {
dc8c34
 		modify_term(&ruv_c, be);
dc8c34
 	}
dc8c34
-- 
dc8c34
1.9.3
dc8c34