[PATCH] lib: Fix gencache_del
Volker Lendecke
Volker.Lendecke at SerNet.DE
Thu Mar 3 15:57:53 UTC 2016
Hi!
Review appreciated!
Thanks, Volker
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 3a3de8d8bd568f6d1dedfce34e91fcd82e23c940 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 3 Mar 2016 15:59:05 +0100
Subject: [PATCH] lib: Fix gencache_del
"net cache flush" can give nasty error messages like
Couldn't delete entry! key = IDMAP/UID2SID/12345
These happen when there's an already deleted entry in
gencache_notrans.tdb, indicated by a 0 timeout. This happens if two
gencache_del function calls have happened right after the other and a
gencache_stabilize has not wiped them.
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/lib/gencache.c | 45 ++++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index c353aa6..f3a0e12 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -370,6 +370,15 @@ done:
return ret == 0;
}
+static void gencache_del_parser(time_t timeout, DATA_BLOB blob,
+ void *private_data)
+{
+ if (timeout != 0) {
+ bool *must_delete = private_data;
+ *must_delete = true;
+ }
+}
+
/**
* Delete one entry from the cache file.
*
@@ -381,9 +390,10 @@ done:
bool gencache_del(const char *keystr)
{
- bool exists, was_expired;
- bool ret = false;
- DATA_BLOB value;
+ TDB_DATA key = string_term_tdb_data(keystr);
+ bool must_delete = false;
+ bool result = true;
+ int ret;
if (keystr == NULL) {
return false;
@@ -395,28 +405,25 @@ bool gencache_del(const char *keystr)
DEBUG(10, ("Deleting cache entry (key=[%s])\n", keystr));
- /*
- * We delete an element by setting its timeout to 0. This way we don't
- * have to do a transaction on gencache.tdb every time we delete an
- * element.
- */
+ ret = tdb_chainlock(cache_notrans->tdb, key);
+ if (ret == -1) {
+ return false;
+ }
- exists = gencache_get_data_blob(keystr, NULL, &value, NULL,
- &was_expired);
+ gencache_parse(keystr, gencache_del_parser, &must_delete);
- if (!exists && was_expired) {
+ if (must_delete) {
/*
- * gencache_get_data_blob has implicitly deleted this
- * entry, so we have to return success here.
+ * We delete an element by setting its timeout to
+ * 0. This way we don't have to do a transaction on
+ * gencache.tdb every time we delete an element.
*/
- return true;
+ result = gencache_set(keystr, "", 0);
}
- if (exists) {
- data_blob_free(&value);
- ret = gencache_set(keystr, "", 0);
- }
- return ret;
+ tdb_chainunlock(cache_notrans->tdb, key);
+
+ return result;
}
static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr)
--
2.1.4
More information about the samba-technical
mailing list