summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristof Schmitt <cs@samba.org>2019-04-01 16:23:35 -0700
committerKarolin Seeger <kseeger@samba.org>2019-04-12 07:57:11 +0000
commita54038bf5f87189ebc46ae3da1335205efd03669 (patch)
treef61c8a79756c77cfb6249ff3d62740ba3394b9a1
parent116c874f1ff77d27a7ffb10c44a3cba8bad891a0 (diff)
downloadsamba-a54038bf5f87189ebc46ae3da1335205efd03669.tar.gz
memcache: Properly track the size of talloc objects
With memcache_add_talloc, the talloc object becomes part of the pool and the memcache_element stores a pointer to the talloc object. The size of the the talloc object was not used when tracking the used space, allowing the cache to grow larger than defined in the memcache_init call. Fix this by adding the size of the talloc object to the used space. Also record the initial size of the talloc object for proper adjustment of the used space in the cache later. This is in case the size of the talloc object is modified while being owned by the cache (e.g. allocating talloc child objects). This should never happen, but better be safe than ending up with a broken cache usage counter. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13865 Signed-off-by: Christof Schmitt <cs@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> (cherry picked from commit a04ca6f3438595ba7e1a110877f53d1cac0f0402)
-rw-r--r--lib/util/memcache.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/lib/util/memcache.c b/lib/util/memcache.c
index d0250c6b3ee..1e616bd0e9a 100644
--- a/lib/util/memcache.c
+++ b/lib/util/memcache.c
@@ -29,6 +29,7 @@ static struct memcache *global_cache;
struct memcache_talloc_value {
void *ptr;
+ size_t len;
};
struct memcache_element {
@@ -213,6 +214,7 @@ static void memcache_delete_element(struct memcache *cache,
memcache_element_parse(e, &cache_key, &cache_value);
SMB_ASSERT(cache_value.length == sizeof(mtv));
memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size -= mtv.len;
TALLOC_FREE(mtv.ptr);
}
@@ -283,6 +285,7 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
SMB_ASSERT(cache_value.length == sizeof(mtv));
memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size -= mtv.len;
TALLOC_FREE(mtv.ptr);
}
/*
@@ -290,6 +293,14 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
*/
memcpy(cache_value.data, value.data, value.length);
e->valuelength = value.length;
+
+ if (memcache_is_talloc(e->n)) {
+ struct memcache_talloc_value mtv;
+
+ SMB_ASSERT(cache_value.length == sizeof(mtv));
+ memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size += mtv.len;
+ }
return;
}
@@ -333,6 +344,13 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
DLIST_ADD(cache->mru, e);
cache->size += element_size;
+ if (memcache_is_talloc(e->n)) {
+ struct memcache_talloc_value mtv;
+
+ SMB_ASSERT(cache_value.length == sizeof(mtv));
+ memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size += mtv.len;
+ }
memcache_trim(cache);
}
@@ -349,6 +367,7 @@ void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
return;
}
+ mtv.len = talloc_total_size(*ptr);
mtv.ptr = talloc_move(cache, ptr);
memcache_add(cache, n, key, data_blob_const(&mtv, sizeof(mtv)));
}