The Samba-Bugzilla – Attachment 10838 Details for
Bug 11144
Memory leak in SMB2 notify handling.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches for v4-0-test
tmp40.diff.txt (text/plain), 158.62 KB, created by
Stefan Metzmacher
on 2015-03-10 10:53:31 UTC
(
hide
)
Description:
Patches for v4-0-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2015-03-10 10:53:31 UTC
Size:
158.62 KB
patch
obsolete
>From 37ebf499ec5804f456d48ea3a46770a91e9dac7c Mon Sep 17 00:00:00 2001 >From: Simo Sorce <idra@samba.org> >Date: Sat, 22 Sep 2012 16:15:47 -0400 >Subject: [PATCH 01/47] Add memory limiting capability to talloc > >By calling talloc_set_memlimit() we can now set a max memory limit >for a whole talloc hierarchy. >ANy attempt to allocate memory beyond the max allowed for the whole >hierarchy wil cause an allocation failure. > >Stealing memory correctly accounts for used memory in the old and the new >hierarchy but exceeding the memory limit in the new parent will not cause >a failure. > >(cherry picked from commit a33a78c302fde61fdb7a6e71669f19be2cf5c836) >--- > lib/talloc/ABI/pytalloc-util-2.0.8.sigs | 6 + > lib/talloc/ABI/talloc-2.0.8.sigs | 63 ++++++++ > lib/talloc/talloc.c | 277 +++++++++++++++++++++++++++----- > lib/talloc/talloc.h | 19 +++ > lib/talloc/wscript | 2 +- > 5 files changed, 327 insertions(+), 40 deletions(-) > create mode 100644 lib/talloc/ABI/pytalloc-util-2.0.8.sigs > create mode 100644 lib/talloc/ABI/talloc-2.0.8.sigs > >diff --git a/lib/talloc/ABI/pytalloc-util-2.0.8.sigs b/lib/talloc/ABI/pytalloc-util-2.0.8.sigs >new file mode 100644 >index 0000000..961c1a8 >--- /dev/null >+++ b/lib/talloc/ABI/pytalloc-util-2.0.8.sigs >@@ -0,0 +1,6 @@ >+pytalloc_CObject_FromTallocPtr: PyObject *(void *) >+pytalloc_Check: int (PyObject *) >+pytalloc_GetObjectType: PyTypeObject *(void) >+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >+pytalloc_steal: PyObject *(PyTypeObject *, void *) >+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >diff --git a/lib/talloc/ABI/talloc-2.0.8.sigs b/lib/talloc/ABI/talloc-2.0.8.sigs >new file mode 100644 >index 0000000..15a9e95 >--- /dev/null >+++ b/lib/talloc/ABI/talloc-2.0.8.sigs >@@ -0,0 +1,63 @@ >+_talloc: void *(const void *, size_t) >+_talloc_array: void *(const void *, size_t, unsigned int, const char *) >+_talloc_free: int (void *, const char *) >+_talloc_get_type_abort: void *(const void *, const char *, const char *) >+_talloc_memdup: void *(const void *, const void *, size_t, const char *) >+_talloc_move: void *(const void *, const void *) >+_talloc_realloc: void *(const void *, void *, size_t, const char *) >+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) >+_talloc_reference_loc: void *(const void *, const void *, const char *) >+_talloc_set_destructor: void (const void *, int (*)(void *)) >+_talloc_steal_loc: void *(const void *, const void *, const char *) >+_talloc_zero: void *(const void *, size_t, const char *) >+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) >+talloc_asprintf: char *(const void *, const char *, ...) >+talloc_asprintf_append: char *(char *, const char *, ...) >+talloc_asprintf_append_buffer: char *(char *, const char *, ...) >+talloc_autofree_context: void *(void) >+talloc_check_name: void *(const void *, const char *) >+talloc_disable_null_tracking: void (void) >+talloc_enable_leak_report: void (void) >+talloc_enable_leak_report_full: void (void) >+talloc_enable_null_tracking: void (void) >+talloc_enable_null_tracking_no_autofree: void (void) >+talloc_find_parent_byname: void *(const void *, const char *) >+talloc_free_children: void (void *) >+talloc_get_name: const char *(const void *) >+talloc_get_size: size_t (const void *) >+talloc_increase_ref_count: int (const void *) >+talloc_init: void *(const char *, ...) >+talloc_is_parent: int (const void *, const void *) >+talloc_named: void *(const void *, size_t, const char *, ...) >+talloc_named_const: void *(const void *, size_t, const char *) >+talloc_parent: void *(const void *) >+talloc_parent_name: const char *(const void *) >+talloc_pool: void *(const void *, size_t) >+talloc_realloc_fn: void *(const void *, void *, size_t) >+talloc_reference_count: size_t (const void *) >+talloc_reparent: void *(const void *, const void *, const void *) >+talloc_report: void (const void *, FILE *) >+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) >+talloc_report_depth_file: void (const void *, int, int, FILE *) >+talloc_report_full: void (const void *, FILE *) >+talloc_set_abort_fn: void (void (*)(const char *)) >+talloc_set_log_fn: void (void (*)(const char *)) >+talloc_set_log_stderr: void (void) >+talloc_set_memlimit: int (const void *, size_t) >+talloc_set_name: const char *(const void *, const char *, ...) >+talloc_set_name_const: void (const void *, const char *) >+talloc_show_parents: void (const void *, FILE *) >+talloc_strdup: char *(const void *, const char *) >+talloc_strdup_append: char *(char *, const char *) >+talloc_strdup_append_buffer: char *(char *, const char *) >+talloc_strndup: char *(const void *, const char *, size_t) >+talloc_strndup_append: char *(char *, const char *, size_t) >+talloc_strndup_append_buffer: char *(char *, const char *, size_t) >+talloc_total_blocks: size_t (const void *) >+talloc_total_size: size_t (const void *) >+talloc_unlink: int (const void *, void *) >+talloc_vasprintf: char *(const void *, const char *, va_list) >+talloc_vasprintf_append: char *(char *, const char *, va_list) >+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) >+talloc_version_major: int (void) >+talloc_version_minor: int (void) >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 18ee548..afc44b3 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -71,6 +71,7 @@ > #define TALLOC_FLAG_LOOP 0x02 > #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ > #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ >+ > #define TALLOC_MAGIC_REFERENCE ((const char *)1) > > /* by default we abort when given a bad pointer (such as when talloc_free() is called >@@ -221,12 +222,50 @@ static struct { > TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \ > } while (0) > >+#define TALLOC_MEMLIMIT_CHECK(limit, size) do { \ >+ struct talloc_memlimit *l; \ >+ for (l = limit; l != NULL; l = l->upper) { \ >+ if (l->max_size != 0 && \ >+ ((l->max_size <= l->cur_size) || \ >+ (l->max_size - l->cur_size < TC_HDR_SIZE+size))) { \ >+ errno = ENOMEM; \ >+ return NULL; \ >+ } \ >+ } \ >+} while(0) >+ >+#define TALLOC_MEMLIMIT_UPDATE(limit, o_size, n_size) do { \ >+ struct talloc_memlimit *l; \ >+ ssize_t d; \ >+ if (o_size == 0) { \ >+ d = n_size + TC_HDR_SIZE; \ >+ } else { \ >+ d = n_size - o_size; \ >+ } \ >+ for (l = limit; l != NULL; l = l->upper) { \ >+ ssize_t new_size = l->cur_size + d; \ >+ if (new_size < 0) { \ >+ talloc_abort("cur_size memlimit counter not correct!"); \ >+ errno = EINVAL; \ >+ return NULL; \ >+ } \ >+ l->cur_size = new_size; \ >+ } \ >+} while(0) >+ > struct talloc_reference_handle { > struct talloc_reference_handle *next, *prev; > void *ptr; > const char *location; > }; > >+struct talloc_memlimit { >+ struct talloc_chunk *parent; >+ struct talloc_memlimit *upper; >+ size_t max_size; >+ size_t cur_size; >+}; >+ > typedef int (*talloc_destructor_t)(void *); > > struct talloc_chunk { >@@ -239,6 +278,15 @@ struct talloc_chunk { > unsigned flags; > > /* >+ * limit semantics: >+ * if 'limit' is set it means all *new* children of the context will >+ * be limited to a total aggregate size ox max_size for memory >+ * allocations. >+ * cur_size is used to kep track of the current use >+ */ >+ struct talloc_memlimit *limit; >+ >+ /* > * "pool" has dual use: > * > * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" >@@ -543,6 +591,7 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > static inline void *__talloc(const void *context, size_t size) > { > struct talloc_chunk *tc = NULL; >+ struct talloc_memlimit *limit = NULL; > > if (unlikely(context == NULL)) { > context = null_context; >@@ -553,8 +602,15 @@ static inline void *__talloc(const void *context, size_t size) > } > > if (context != NULL) { >- tc = talloc_alloc_pool(talloc_chunk_from_ptr(context), >- TC_HDR_SIZE+size); >+ struct talloc_chunk *ptc = talloc_chunk_from_ptr(context); >+ >+ if (ptc->limit != NULL) { >+ limit = ptc->limit; >+ } >+ >+ TALLOC_MEMLIMIT_CHECK(limit, (TC_HDR_SIZE+size)); >+ >+ tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size); > } > > if (tc == NULL) { >@@ -564,6 +620,15 @@ static inline void *__talloc(const void *context, size_t size) > tc->pool = NULL; > } > >+ if (limit != NULL) { >+ struct talloc_memlimit *l; >+ >+ for (l = limit; l != NULL; l = l->upper) { >+ l->cur_size += TC_HDR_SIZE+size; >+ } >+ } >+ >+ tc->limit = limit; > tc->size = size; > tc->destructor = NULL; > tc->child = NULL; >@@ -852,6 +917,29 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > > tc->flags |= TALLOC_FLAG_FREE; > >+ /* >+ * If we are part of a memory limited context hierarchy >+ * we need to subtract the memory used from the counters >+ */ >+ if (tc->limit) { >+ struct talloc_memlimit *l; >+ >+ for (l = tc->limit; l != NULL; l = l->upper) { >+ if (l->cur_size >= tc->size+TC_HDR_SIZE) { >+ l->cur_size -= tc->size+TC_HDR_SIZE; >+ } else { >+ talloc_abort("cur_size memlimit counter not correct!"); >+ return 0; >+ } >+ } >+ >+ if (tc->limit->parent == tc) { >+ free(tc->limit); >+ } >+ >+ tc->limit = NULL; >+ } >+ > /* we mark the freed memory with where we called the free > * from. This means on a double free error we can report where > * the first free came from >@@ -880,6 +968,10 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > return 0; > } > >+static size_t _talloc_total_limit_size(const void *ptr, >+ struct talloc_memlimit *old_limit, >+ struct talloc_memlimit *new_limit); >+ > /* > move a lump of memory from one talloc context to another return the > ptr on success, or NULL if it could not be transferred. >@@ -888,6 +980,7 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > { > struct talloc_chunk *tc, *new_tc; >+ size_t ctx_size = 0; > > if (unlikely(!ptr)) { > return NULL; >@@ -899,6 +992,19 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > > tc = talloc_chunk_from_ptr(ptr); > >+ if (tc->limit != NULL) { >+ >+ ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); >+ >+ TALLOC_MEMLIMIT_UPDATE(tc->limit->upper, ctx_size, 0); >+ >+ if (tc->limit->parent == tc) { >+ tc->limit->upper = NULL; >+ } else { >+ tc->limit = NULL; >+ } >+ } >+ > if (unlikely(new_ctx == NULL)) { > if (tc->parent) { > _TLIST_REMOVE(tc->parent->child, tc); >@@ -909,7 +1015,7 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > if (tc->prev) tc->prev->next = tc->next; > if (tc->next) tc->next->prev = tc->prev; > } >- >+ > tc->parent = tc->next = tc->prev = NULL; > return discard_const_p(void, ptr); > } >@@ -935,6 +1041,19 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > if (new_tc->child) new_tc->child->parent = NULL; > _TLIST_ADD(new_tc->child, tc); > >+ if (tc->limit || new_tc->limit) { >+ ctx_size = _talloc_total_limit_size(ptr, tc->limit, >+ new_tc->limit); >+ } >+ >+ if (new_tc->limit) { >+ struct talloc_memlimit *l; >+ >+ for (l = new_tc->limit; l != NULL; l = l->upper) { >+ l->cur_size += ctx_size; >+ } >+ } >+ > return discard_const_p(void, ptr); > } > >@@ -1068,7 +1187,7 @@ _PUBLIC_ int talloc_unlink(const void *context, void *ptr) > if (tc_c != talloc_parent_chunk(ptr)) { > return -1; > } >- >+ > tc_p = talloc_chunk_from_ptr(ptr); > > if (tc_p->refs == NULL) { >@@ -1411,6 +1530,10 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > return NULL; > } > >+ if (tc->limit && (size - tc->size > 0)) { >+ TALLOC_MEMLIMIT_CHECK(tc->limit, (size - tc->size)); >+ } >+ > /* handle realloc inside a talloc_pool */ > if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { > pool_tc = (union talloc_pool_chunk *)tc->pool; >@@ -1418,7 +1541,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > > #if (ALWAYS_REALLOC == 0) > /* don't shrink if we have less than 1k to gain */ >- if (size < tc->size) { >+ if (size < tc->size && tc->limit == NULL) { > if (pool_tc) { > void *next_tc = tc_next_chunk(tc); > TC_INVALIDATE_SHRINK_CHUNK(tc, size); >@@ -1526,6 +1649,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (new_chunk_size == old_chunk_size) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; >+ TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size); > tc->size = size; > return ptr; > } >@@ -1541,6 +1665,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (space_left >= space_needed) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; >+ TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size); > tc->size = size; > pool_tc->hdr.c.pool = tc_next_chunk(tc); > return ptr; >@@ -1589,6 +1714,7 @@ got_new_ptr: > tc->next->prev = tc; > } > >+ TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size); > tc->size = size; > _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); > >@@ -1607,10 +1733,16 @@ _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr) > return ret; > } > >-/* >- return the total size of a talloc pool (subtree) >-*/ >-_PUBLIC_ size_t talloc_total_size(const void *ptr) >+enum talloc_mem_count_type { >+ TOTAL_MEM_SIZE, >+ TOTAL_MEM_BLOCKS, >+ TOTAL_MEM_LIMIT, >+}; >+ >+static size_t _talloc_total_mem_internal(const void *ptr, >+ enum talloc_mem_count_type type, >+ struct talloc_memlimit *old_limit, >+ struct talloc_memlimit *new_limit) > { > size_t total = 0; > struct talloc_chunk *c, *tc; >@@ -1624,17 +1756,50 @@ _PUBLIC_ size_t talloc_total_size(const void *ptr) > > tc = talloc_chunk_from_ptr(ptr); > >+ if (old_limit || new_limit) { >+ if (tc->limit && tc->limit->upper == old_limit) { >+ tc->limit->upper = new_limit; >+ } >+ } >+ >+ /* optimize in the memlimits case */ >+ if (type == TOTAL_MEM_LIMIT && >+ tc->limit != NULL && >+ tc->limit != old_limit && >+ tc->limit->parent == tc) { >+ return tc->limit->cur_size; >+ } >+ > if (tc->flags & TALLOC_FLAG_LOOP) { > return 0; > } > > tc->flags |= TALLOC_FLAG_LOOP; > >- if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { >- total = tc->size; >+ if (old_limit || new_limit) { >+ if (old_limit == tc->limit) { >+ tc->limit = new_limit; >+ } > } >- for (c=tc->child;c;c=c->next) { >- total += talloc_total_size(TC_PTR_FROM_CHUNK(c)); >+ >+ switch (type) { >+ case TOTAL_MEM_SIZE: >+ if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { >+ total = tc->size; >+ } >+ break; >+ case TOTAL_MEM_BLOCKS: >+ total++; >+ break; >+ case TOTAL_MEM_LIMIT: >+ if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { >+ total = tc->size + TC_HDR_SIZE; >+ } >+ break; >+ } >+ for (c = tc->child; c; c = c->next) { >+ total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type, >+ old_limit, new_limit); > } > > tc->flags &= ~TALLOC_FLAG_LOOP; >@@ -1643,36 +1808,19 @@ _PUBLIC_ size_t talloc_total_size(const void *ptr) > } > > /* >+ return the total size of a talloc pool (subtree) >+*/ >+_PUBLIC_ size_t talloc_total_size(const void *ptr) >+{ >+ return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL); >+} >+ >+/* > return the total number of blocks in a talloc pool (subtree) > */ > _PUBLIC_ size_t talloc_total_blocks(const void *ptr) > { >- size_t total = 0; >- struct talloc_chunk *c, *tc; >- >- if (ptr == NULL) { >- ptr = null_context; >- } >- if (ptr == NULL) { >- return 0; >- } >- >- tc = talloc_chunk_from_ptr(ptr); >- >- if (tc->flags & TALLOC_FLAG_LOOP) { >- return 0; >- } >- >- tc->flags |= TALLOC_FLAG_LOOP; >- >- total++; >- for (c=tc->child;c;c=c->next) { >- total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); >- } >- >- tc->flags &= ~TALLOC_FLAG_LOOP; >- >- return total; >+ return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL); > } > > /* >@@ -1734,6 +1882,7 @@ _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, > static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) > { > const char *name = talloc_get_name(ptr); >+ struct talloc_chunk *tc; > FILE *f = (FILE *)_f; > > if (is_ref) { >@@ -1741,6 +1890,16 @@ static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_ > return; > } > >+ tc = talloc_chunk_from_ptr(ptr); >+ if (tc->limit && tc->limit->parent == tc) { >+ fprintf(f, "%*s%-30s is a memlimit context" >+ " (max_size = %lu bytes, cur_size = %lu bytes)\n", >+ depth*4, "", >+ name, >+ (unsigned long)tc->limit->max_size, >+ (unsigned long)tc->limit->cur_size); >+ } >+ > if (depth == 0) { > fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", > (max_depth < 0 ? "full " :""), name, >@@ -2359,3 +2518,43 @@ _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr) > { > return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH); > } >+ >+/* >+ return the total size of memory used by this context and all children >+*/ >+static size_t _talloc_total_limit_size(const void *ptr, >+ struct talloc_memlimit *old_limit, >+ struct talloc_memlimit *new_limit) >+{ >+ return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT, >+ old_limit, new_limit); >+} >+ >+_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) >+{ >+ struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx); >+ struct talloc_memlimit *orig_limit; >+ struct talloc_memlimit *limit = NULL; >+ >+ if (tc->limit && tc->limit->parent == tc) { >+ tc->limit->max_size = max_size; >+ return 0; >+ } >+ orig_limit = tc->limit; >+ >+ limit = malloc(sizeof(struct talloc_memlimit)); >+ if (limit == NULL) { >+ return 1; >+ } >+ limit->parent = tc; >+ limit->max_size = max_size; >+ limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit); >+ >+ if (orig_limit) { >+ limit->upper = orig_limit; >+ } else { >+ limit->upper = NULL; >+ } >+ >+ return 0; >+} >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index e48dc09..f3cbcd0 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -1842,6 +1842,25 @@ void talloc_set_log_fn(void (*log_fn)(const char *message)); > */ > void talloc_set_log_stderr(void); > >+/** >+ * @brief Set a max memory limit for the current context hierarchy >+ * This affects all children of this context and constrain any >+ * allocation in the hierarchy to never exceed the limit set. >+ * The limit can be removed by setting 0 (unlimited) as the >+ * max_size by calling the funciton again on the sam context. >+ * Memory limits can also be nested, meaning a hild can have >+ * a stricter memory limit than a parent. >+ * Memory limits are enforced only at memory allocation time. >+ * Stealing a context into a 'limited' hierarchy properly >+ * updates memory usage but does *not* cause failure if the >+ * move causes the new parent to exceed its limits. However >+ * any further allocation on that hierarchy will then fail. >+ * >+ * @param[in] ctx The talloc context to set the limit on >+ * @param[in] max_size The (new) max_size >+ */ >+int talloc_set_memlimit(const void *ctx, size_t max_size); >+ > /* @} ******************************************************************/ > > #if TALLOC_DEPRECATED >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index a97b5d0b..bd7708e 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'talloc' >-VERSION = '2.0.7' >+VERSION = '2.0.8' > > > blddir = 'bin' >-- >1.9.1 > > >From 2565208ae14599e7738d4c164f557ff25e18ebfd Mon Sep 17 00:00:00 2001 >From: Simo Sorce <idra@samba.org> >Date: Sat, 22 Sep 2012 16:35:21 -0400 >Subject: [PATCH 02/47] Add tests for talloc_memlimit > >Autobuild-User(master): Simo Sorce <idra@samba.org> >Autobuild-Date(master): Fri Oct 5 07:36:38 CEST 2012 on sn-devel-104 > >(cherry picked from commit 7d7e33c624875a9694fcebdde942147ac3bf5f74) >--- > lib/talloc/testsuite.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 172 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index eaab9d7..d456cbb 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -1355,6 +1355,175 @@ static bool test_free_children(void) > return true; > } > >+static bool test_memlimit(void) >+{ >+ void *root; >+ char *l1, *l2, *l3, *l4, *l5, *t; >+ >+ printf("test: memlimit\n# MEMORY LIMITS\n"); >+ >+ printf("==== talloc_new(NULL)\n"); >+ root = talloc_new(NULL); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_size(root, 2048)\n"); >+ l1 = talloc_size(root, 2048); >+ torture_assert("memlimit", l1 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_free(l1)\n"); >+ talloc_free(l1); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(root, level 1)\n"); >+ l1 = talloc_strdup(root, "level 1"); >+ torture_assert("memlimit", l1 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_set_memlimit(l1, 2048)\n"); >+ torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0, >+ "failed: setting memlimit should never fail\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_size(root, 2048)\n"); >+ l2 = talloc_size(l1, 2048); >+ torture_assert("memlimit", l2 == NULL, >+ "failed: alloc should fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(l1, level 2)\n"); >+ l2 = talloc_strdup(l1, "level 2"); >+ torture_assert("memlimit", l2 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_free(l2)\n"); >+ talloc_free(l2); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_size(NULL, 2048)\n"); >+ l2 = talloc_size(NULL, 2048); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_steal(l1, l2)\n"); >+ talloc_steal(l1, l2); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(l2, level 3)\n"); >+ l3 = talloc_strdup(l2, "level 3"); >+ torture_assert("memlimit", l3 == NULL, >+ "failed: alloc should fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_free(l2)\n"); >+ talloc_free(l2); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(NULL, level 2)\n"); >+ l2 = talloc_strdup(NULL, "level 2"); >+ talloc_steal(l1, l2); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(l2, level 3)\n"); >+ l3 = talloc_strdup(l2, "level 3"); >+ torture_assert("memlimit", l3 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_set_memlimit(l3, 1024)\n"); >+ torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0, >+ "failed: setting memlimit should never fail\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(l3, level 4)\n"); >+ l4 = talloc_strdup(l3, "level 4"); >+ torture_assert("memlimit", l4 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_set_memlimit(l4, 512)\n"); >+ torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, >+ "failed: setting memlimit should never fail\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(l4, level 5)\n"); >+ l5 = talloc_strdup(l4, "level 5"); >+ torture_assert("memlimit", l5 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_realloc(NULL, l5, char, 600)\n"); >+ t = talloc_realloc(NULL, l5, char, 600); >+ torture_assert("memlimit", t == NULL, >+ "failed: alloc should fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_realloc(NULL, l5, char, 5)\n"); >+ l5 = talloc_realloc(NULL, l5, char, 5); >+ torture_assert("memlimit", l5 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(l3, level 4)\n"); >+ l4 = talloc_strdup(l3, "level 4"); >+ torture_assert("memlimit", l4 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_set_memlimit(l4, 512)\n"); >+ torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, >+ "failed: setting memlimit should never fail\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_strdup(l4, level 5)\n"); >+ l5 = talloc_strdup(l4, "level 5"); >+ torture_assert("memlimit", l5 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== Make new temp context and steal l5\n"); >+ t = talloc_new(root); >+ talloc_steal(t, l5); >+ >+ talloc_report_full(root, stdout); >+ >+ printf("==== talloc_size(t, 2048)\n"); >+ l1 = talloc_size(t, 2048); >+ torture_assert("memlimit", l1 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ >+ talloc_report_full(root, stdout); >+ talloc_free(root); >+ >+ printf("success: memlimit\n"); >+ >+ return true; >+} > > static void test_reset(void) > { >@@ -1416,6 +1585,9 @@ bool torture_local_talloc(struct torture_context *tctx) > ret &= test_rusty(); > test_reset(); > ret &= test_free_children(); >+ test_reset(); >+ ret &= test_memlimit(); >+ > > if (ret) { > test_reset(); >-- >1.9.1 > > >From fb8725acffc717b4aff749143de8653899454765 Mon Sep 17 00:00:00 2001 >From: Simo Sorce <idra@samba.org> >Date: Fri, 5 Oct 2012 10:32:32 -0400 >Subject: [PATCH 03/47] talloc: Convert error cecking macros into fns > >This will avoid 'surprise returns' and makes the code cleare to readers. >These macros were complex enough to warrant a full function anyway not >just for readability but also for debuggability. > >Thanks David for pointing out this issue. > >Autobuild-User(master): Simo Sorce <idra@samba.org> >Autobuild-Date(master): Fri Oct 5 23:24:17 CEST 2012 on sn-devel-104 > >(cherry picked from commit 36ea39edf8dd9ede756debaf9632f3ded2a51abb) >--- > lib/talloc/talloc.c | 111 ++++++++++++++++++++++++++++++++++------------------ > 1 file changed, 74 insertions(+), 37 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index afc44b3..3e33fc0 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -222,37 +222,6 @@ static struct { > TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \ > } while (0) > >-#define TALLOC_MEMLIMIT_CHECK(limit, size) do { \ >- struct talloc_memlimit *l; \ >- for (l = limit; l != NULL; l = l->upper) { \ >- if (l->max_size != 0 && \ >- ((l->max_size <= l->cur_size) || \ >- (l->max_size - l->cur_size < TC_HDR_SIZE+size))) { \ >- errno = ENOMEM; \ >- return NULL; \ >- } \ >- } \ >-} while(0) >- >-#define TALLOC_MEMLIMIT_UPDATE(limit, o_size, n_size) do { \ >- struct talloc_memlimit *l; \ >- ssize_t d; \ >- if (o_size == 0) { \ >- d = n_size + TC_HDR_SIZE; \ >- } else { \ >- d = n_size - o_size; \ >- } \ >- for (l = limit; l != NULL; l = l->upper) { \ >- ssize_t new_size = l->cur_size + d; \ >- if (new_size < 0) { \ >- talloc_abort("cur_size memlimit counter not correct!"); \ >- errno = EINVAL; \ >- return NULL; \ >- } \ >- l->cur_size = new_size; \ >- } \ >-} while(0) >- > struct talloc_reference_handle { > struct talloc_reference_handle *next, *prev; > void *ptr; >@@ -266,6 +235,10 @@ struct talloc_memlimit { > size_t cur_size; > }; > >+static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); >+static bool talloc_memlimit_update(struct talloc_memlimit *limit, >+ size_t old_size, size_t new_size); >+ > typedef int (*talloc_destructor_t)(void *); > > struct talloc_chunk { >@@ -608,7 +581,10 @@ static inline void *__talloc(const void *context, size_t size) > limit = ptc->limit; > } > >- TALLOC_MEMLIMIT_CHECK(limit, (TC_HDR_SIZE+size)); >+ if (!talloc_memlimit_check(limit, (TC_HDR_SIZE+size))) { >+ errno = ENOMEM; >+ return NULL; >+ } > > tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size); > } >@@ -996,7 +972,11 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > > ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); > >- TALLOC_MEMLIMIT_UPDATE(tc->limit->upper, ctx_size, 0); >+ if (!talloc_memlimit_update(tc->limit->upper, ctx_size, 0)) { >+ talloc_abort("cur_size memlimit counter not correct!"); >+ errno = EINVAL; >+ return NULL; >+ } > > if (tc->limit->parent == tc) { > tc->limit->upper = NULL; >@@ -1531,7 +1511,10 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > > if (tc->limit && (size - tc->size > 0)) { >- TALLOC_MEMLIMIT_CHECK(tc->limit, (size - tc->size)); >+ if (!talloc_memlimit_check(tc->limit, (size - tc->size))) { >+ errno = ENOMEM; >+ return NULL; >+ } > } > > /* handle realloc inside a talloc_pool */ >@@ -1649,7 +1632,14 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (new_chunk_size == old_chunk_size) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; >- TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size); >+ if (!talloc_memlimit_update(tc->limit, >+ tc->size, size)) { >+ talloc_abort("cur_size memlimit counter not" >+ " correct!"); >+ errno = EINVAL; >+ return NULL; >+ } >+ > tc->size = size; > return ptr; > } >@@ -1665,7 +1655,13 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (space_left >= space_needed) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; >- TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size); >+ if (!talloc_memlimit_update(tc->limit, >+ tc->size, size)) { >+ talloc_abort("cur_size memlimit " >+ "counter not correct!"); >+ errno = EINVAL; >+ return NULL; >+ } > tc->size = size; > pool_tc->hdr.c.pool = tc_next_chunk(tc); > return ptr; >@@ -1714,7 +1710,11 @@ got_new_ptr: > tc->next->prev = tc; > } > >- TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size); >+ if (!talloc_memlimit_update(tc->limit, tc->size, size)) { >+ talloc_abort("cur_size memlimit counter not correct!"); >+ errno = EINVAL; >+ return NULL; >+ } > tc->size = size; > _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); > >@@ -2530,6 +2530,43 @@ static size_t _talloc_total_limit_size(const void *ptr, > old_limit, new_limit); > } > >+static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) >+{ >+ struct talloc_memlimit *l; >+ >+ for (l = limit; l != NULL; l = l->upper) { >+ if (l->max_size != 0 && >+ ((l->max_size <= l->cur_size) || >+ (l->max_size - l->cur_size < TC_HDR_SIZE+size))) { >+ return false; >+ } >+ } >+ >+ return true; >+} >+ >+static bool talloc_memlimit_update(struct talloc_memlimit *limit, >+ size_t old_size, size_t new_size) >+{ >+ struct talloc_memlimit *l; >+ ssize_t d; >+ >+ if (old_size == 0) { >+ d = new_size + TC_HDR_SIZE; >+ } else { >+ d = new_size - old_size; >+ } >+ for (l = limit; l != NULL; l = l->upper) { >+ ssize_t new_cur_size = l->cur_size + d; >+ if (new_cur_size < 0) { >+ return false; >+ } >+ l->cur_size = new_cur_size; >+ } >+ >+ return true; >+} >+ > _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) > { > struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx); >-- >1.9.1 > > >From 3d2b6ff0f345318f2ab5ae4c263c2e72016c77c6 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 15 Apr 2013 21:44:38 +0200 >Subject: [PATCH 04/47] talloc: Fix nonblank line endings > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit d3928b0c8af01f7751191b81a72590ca35751a8c) >--- > lib/talloc/talloc.c | 68 ++++++++++++++++++++++++++--------------------------- > 1 file changed, 34 insertions(+), 34 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 3e33fc0..d0c81d3 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1,4 +1,4 @@ >-/* >+/* > Samba Unix SMB/CIFS implementation. > > Samba trivial allocation library - new interface >@@ -7,11 +7,11 @@ > > Copyright (C) Andrew Tridgell 2004 > Copyright (C) Stefan Metzmacher 2006 >- >+ > ** NOTE! The following LGPL license applies to the talloc > ** library. This does NOT imply that all of Samba is released > ** under the LGPL >- >+ > This library is free software; you can redistribute it and/or > modify it under the terms of the GNU Lesser General Public > License as published by the Free Software Foundation; either >@@ -74,7 +74,7 @@ > > #define TALLOC_MAGIC_REFERENCE ((const char *)1) > >-/* by default we abort when given a bad pointer (such as when talloc_free() is called >+/* by default we abort when given a bad pointer (such as when talloc_free() is called > on a pointer that came from malloc() */ > #ifndef TALLOC_ABORT > #define TALLOC_ABORT(reason) abort() >@@ -367,7 +367,7 @@ static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) > { > const char *pp = (const char *)ptr; > struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); >- if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { >+ if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { > if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) { > talloc_abort_magic(tc->flags & (~0xF)); > return NULL; >@@ -558,7 +558,7 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > return result; > } > >-/* >+/* > Allocate a bit of memory as a child of an existing pointer > */ > static inline void *__talloc(const void *context, size_t size) >@@ -675,7 +675,7 @@ _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) > } > > /* >- increase the reference count on a piece of memory. >+ increase the reference count on a piece of memory. > */ > _PUBLIC_ int talloc_increase_ref_count(const void *ptr) > { >@@ -698,7 +698,7 @@ static int talloc_reference_destructor(struct talloc_reference_handle *handle) > } > > /* >- more efficient way to add a name to a pointer - the name must point to a >+ more efficient way to add a name to a pointer - the name must point to a > true string constant > */ > static inline void _talloc_set_name_const(const void *ptr, const char *name) >@@ -728,8 +728,8 @@ static inline void *_talloc_named_const(const void *context, size_t size, const > make a secondary reference to a pointer, hanging off the given context. > the pointer remains valid until both the original caller and this given > context are freed. >- >- the major use for this is when two different structures need to reference the >+ >+ the major use for this is when two different structures need to reference the > same underlying data, and you want to be able to free the two instances separately, > and in either order > */ >@@ -818,7 +818,7 @@ static inline void _talloc_free_children_internal(struct talloc_chunk *tc, > void *ptr, > const char *location); > >-/* >+/* > internal talloc_free call > */ > static inline int _talloc_free_internal(void *ptr, const char *location) >@@ -918,8 +918,8 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > > /* we mark the freed memory with where we called the free > * from. This means on a double free error we can report where >- * the first free came from >- */ >+ * the first free came from >+ */ > tc->name = location; > > if (tc->flags & TALLOC_FLAG_POOL) { >@@ -948,7 +948,7 @@ static size_t _talloc_total_limit_size(const void *ptr, > struct talloc_memlimit *old_limit, > struct talloc_memlimit *new_limit); > >-/* >+/* > move a lump of memory from one talloc context to another return the > ptr on success, or NULL if it could not be transferred. > passing NULL as ptr will always return NULL with no side effects. >@@ -1037,7 +1037,7 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > return discard_const_p(void, ptr); > } > >-/* >+/* > move a lump of memory from one talloc context to another return the > ptr on success, or NULL if it could not be transferred. > passing NULL as ptr will always return NULL with no side effects. >@@ -1049,9 +1049,9 @@ _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const cha > if (unlikely(ptr == NULL)) { > return NULL; > } >- >+ > tc = talloc_chunk_from_ptr(ptr); >- >+ > if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) { > struct talloc_reference_handle *h; > >@@ -1071,11 +1071,11 @@ _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const cha > talloc_log("WARNING: stealing into talloc child at %s\n", location); > } > #endif >- >+ > return _talloc_steal_internal(new_ctx, ptr); > } > >-/* >+/* > this is like a talloc_steal(), but you must supply the old > parent. This resolves the ambiguity in a talloc_steal() which is > called on a context that has more than one parent (via references) >@@ -1103,7 +1103,7 @@ _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, c > } > return discard_const_p(void, ptr); > } >- } >+ } > > /* it wasn't a parent */ > return NULL; >@@ -1403,7 +1403,7 @@ _PUBLIC_ void talloc_free_children(void *ptr) > } > } > >-/* >+/* > Allocate a bit of memory as a child of an existing pointer > */ > _PUBLIC_ void *_talloc(const void *context, size_t size) >@@ -1429,8 +1429,8 @@ _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char * > return _talloc_named_const(context, size, name); > } > >-/* >- free a talloc pointer. This also frees all child pointers of this >+/* >+ free a talloc pointer. This also frees all child pointers of this > pointer recursively > > return 0 if the memory is actually freed, otherwise -1. The memory >@@ -1444,9 +1444,9 @@ _PUBLIC_ int _talloc_free(void *ptr, const char *location) > if (unlikely(ptr == NULL)) { > return -1; > } >- >+ > tc = talloc_chunk_from_ptr(ptr); >- >+ > if (unlikely(tc->refs != NULL)) { > struct talloc_reference_handle *h; > >@@ -1466,7 +1466,7 @@ _PUBLIC_ int _talloc_free(void *ptr, const char *location) > } > return -1; > } >- >+ > return _talloc_free_internal(ptr, location); > } > >@@ -1686,9 +1686,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > got_new_ptr: > #endif >- if (unlikely(!new_ptr)) { >- tc->flags &= ~TALLOC_FLAG_FREE; >- return NULL; >+ if (unlikely(!new_ptr)) { >+ tc->flags &= ~TALLOC_FLAG_FREE; >+ return NULL; > } > > tc = (struct talloc_chunk *)new_ptr; >@@ -1901,14 +1901,14 @@ static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_ > } > > if (depth == 0) { >- fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", >+ fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", > (max_depth < 0 ? "full " :""), name, > (unsigned long)talloc_total_size(ptr), > (unsigned long)talloc_total_blocks(ptr)); > return; > } > >- fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", >+ fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", > depth*4, "", > name, > (unsigned long)talloc_total_size(ptr), >@@ -2047,8 +2047,8 @@ _PUBLIC_ void talloc_enable_leak_report_full(void) > atexit(talloc_report_null_full); > } > >-/* >- talloc and zero memory. >+/* >+ talloc and zero memory. > */ > _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name) > { >@@ -2062,7 +2062,7 @@ _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name) > } > > /* >- memdup with a talloc. >+ memdup with a talloc. > */ > _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) > { >-- >1.9.1 > > >From 98903cfc0d5a40bb82e2983649198693ea83ccd7 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 15 Apr 2013 22:11:44 +0200 >Subject: [PATCH 05/47] talloc: Avoid some "else" by doing early returns > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit ccf33dd0547f32104041c8611626f3e02e22cbe9) >--- > lib/talloc/talloc.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index d0c81d3..011e8f3 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -935,12 +935,16 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > TC_INVALIDATE_FULL_CHUNK(tc); > free(tc); > } >- } else if (tc->flags & TALLOC_FLAG_POOLMEM) { >+ return 0; >+ } >+ >+ if (tc->flags & TALLOC_FLAG_POOLMEM) { > _talloc_free_poolmem(tc, location); >- } else { >- TC_INVALIDATE_FULL_CHUNK(tc); >- free(tc); >+ return 0; > } >+ >+ TC_INVALIDATE_FULL_CHUNK(tc); >+ free(tc); > return 0; > } > >-- >1.9.1 > > >From 08c6caffb10eea50d4dc55e41ffc94e6289c4d03 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 15 Apr 2013 22:12:50 +0200 >Subject: [PATCH 06/47] talloc: Do an early return > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit a796e48b1dfe96b194f3a3a0d70e25c3ab92690d) >--- > lib/talloc/talloc.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 011e8f3..0078b07 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -931,10 +931,13 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > } > > pool->hdr.object_count--; >- if (unlikely(pool->hdr.object_count == 0)) { >- TC_INVALIDATE_FULL_CHUNK(tc); >- free(tc); >+ >+ if (likely(pool->hdr.object_count != 0)) { >+ return 0; > } >+ >+ TC_INVALIDATE_FULL_CHUNK(tc); >+ free(tc); > return 0; > } > >-- >1.9.1 > > >From aaa56eda40f31106443b86095365a1343d8659ba Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 15 Apr 2013 22:19:25 +0200 >Subject: [PATCH 07/47] talloc: Simplify _talloc_free_poolmem a bit > >Early returns are easier to understand than "else if" > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Thu Apr 18 22:50:42 CEST 2013 on sn-devel-104 > >(cherry picked from commit 79fe1381a3a78ad2316343fc8c1c27360b46ebbf) >--- > lib/talloc/talloc.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 0078b07..885d700 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -794,7 +794,10 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > */ > pool->hdr.c.pool = tc_pool_first_chunk(pool); > tc_invalidate_pool(pool); >- } else if (unlikely(pool->hdr.object_count == 0)) { >+ return; >+ } >+ >+ if (unlikely(pool->hdr.object_count == 0)) { > /* > * we mark the freed memory with where we called the free > * from. This means on a double free error we can report where >@@ -804,14 +807,23 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > > TC_INVALIDATE_FULL_CHUNK(&pool->hdr.c); > free(pool); >- } else if (pool->hdr.c.pool == next_tc) { >+ return; >+ } >+ >+ if (pool->hdr.c.pool == next_tc) { > /* > * if pool->pool still points to end of > * 'tc' (which is stored in the 'next_tc' variable), > * we can reclaim the memory of 'tc'. > */ > pool->hdr.c.pool = tc; >+ return; > } >+ >+ /* >+ * Do nothing. The memory is just "wasted", waiting for the pool >+ * itself to be freed. >+ */ > } > > static inline void _talloc_free_children_internal(struct talloc_chunk *tc, >-- >1.9.1 > > >From f17aa94645dba9e3b1446cd91ecbd805cd35524e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 7 May 2013 14:15:35 +0200 >Subject: [PATCH 08/47] talloc: only provide the --enable-talloc-compat1 in > standalone build > >The compat library is already only built in standalone build, >so we need the configure option also only in the standalone build. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit 8a878ec74bd24180aa73cfb39ff4a6c3e72d9d0b) >--- > lib/talloc/wscript | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index bd7708e..ecc5e24 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -27,10 +27,10 @@ def set_options(opt): > opt.BUILTIN_DEFAULT('replace') > opt.PRIVATE_EXTENSION_DEFAULT('talloc', noextension='talloc') > opt.RECURSE('lib/replace') >- opt.add_option('--enable-talloc-compat1', >- help=("Build talloc 1.x.x compat library [False]"), >- action="store_true", dest='TALLOC_COMPAT1', default=False) > if opt.IN_LAUNCH_DIR(): >+ opt.add_option('--enable-talloc-compat1', >+ help=("Build talloc 1.x.x compat library [False]"), >+ action="store_true", dest='TALLOC_COMPAT1', default=False) > opt.add_option('--disable-python', > help=("disable the pytalloc module"), > action="store_true", dest='disable_python', default=False) >@@ -51,7 +51,9 @@ def configure(conf): > implied_deps='talloc replace'): > conf.define('USING_SYSTEM_PYTALLOC_UTIL', 1) > >- conf.env.TALLOC_COMPAT1 = Options.options.TALLOC_COMPAT1 >+ conf.env.TALLOC_COMPAT1 = False >+ if conf.env.standalone_talloc: >+ conf.env.TALLOC_COMPAT1 = Options.options.TALLOC_COMPAT1 > > conf.CHECK_XSLTPROC_MANPAGES() > >-- >1.9.1 > > >From 62d6944515c19e99d6b4e8a956d4db1aea85d67a Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 20 May 2013 14:26:08 +0200 >Subject: [PATCH 09/47] talloc: Fix a typo > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Kai Blin <kai@samba.org> > >Autobuild-User(master): Kai Blin <kai@samba.org> >Autobuild-Date(master): Mon May 20 18:48:49 CEST 2013 on sn-devel-104 > >(cherry picked from commit d7708fd360c1fa1e3111fd4df266b52c96cca196) >--- > lib/talloc/talloc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 885d700..76f0aee 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -255,7 +255,7 @@ struct talloc_chunk { > * if 'limit' is set it means all *new* children of the context will > * be limited to a total aggregate size ox max_size for memory > * allocations. >- * cur_size is used to kep track of the current use >+ * cur_size is used to keep track of the current use > */ > struct talloc_memlimit *limit; > >-- >1.9.1 > > >From 3bf9b642a72c2a271db96f51ee1a1139a2b1273a Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:36:23 -0700 >Subject: [PATCH 10/47] Start to fix talloc memlimits with talloc pools. > >Add the functions: > >talloc_memlimit_grow(), talloc_memlimit_shrink(), >talloc_memlimit_update_on_free(). > >as replacements for talloc_memlimit_update(). >The interface to talloc_memlimit_update() is very >hard to understand and use. The above functions >are (to me) much clearer. > >The goal of these changes is to only update >the memlimits on malloc/free/realloc, not >on every pool allocation. That way we only >count pool creation as allocation from any >imposed limits, not allocation from an already >created pool. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit fe790f6cbc9b888a8d613cfb515f0d0c76daad47) >--- > lib/talloc/talloc.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 72 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 76f0aee..067d46f 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -238,6 +238,11 @@ struct talloc_memlimit { > static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); > static bool talloc_memlimit_update(struct talloc_memlimit *limit, > size_t old_size, size_t new_size); >+static void talloc_memlimit_grow(struct talloc_memlimit *limit, >+ size_t size); >+static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >+ size_t size); >+static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); > > typedef int (*talloc_destructor_t)(void *); > >@@ -2564,6 +2569,73 @@ static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > return true; > } > >+/* >+ Update memory limits when freeing a talloc_chunk. >+*/ >+static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) >+{ >+ if (!tc->limit) { >+ return; >+ } >+ >+ /* >+ * Pool entries don't count. Only the pools >+ * themselves are counted as part of the memory >+ * limits. >+ */ >+ if (tc->flags & TALLOC_FLAG_POOLMEM) { >+ return; >+ } >+ >+ /* >+ * If we are part of a memory limited context hierarchy >+ * we need to subtract the memory used from the counters >+ */ >+ >+ talloc_memlimit_shrink(tc->limit, tc->size+TC_HDR_SIZE); >+ >+ if (tc->limit->parent == tc) { >+ free(tc->limit); >+ } >+ >+ tc->limit = NULL; >+} >+ >+/* >+ Increase memory limit accounting after a malloc/realloc. >+*/ >+static void talloc_memlimit_grow(struct talloc_memlimit *limit, >+ size_t size) >+{ >+ struct talloc_memlimit *l; >+ >+ for (l = limit; l != NULL; l = l->upper) { >+ size_t new_cur_size = l->cur_size + size; >+ if (new_cur_size < l->cur_size) { >+ talloc_abort("logic error in talloc_memlimit_grow\n"); >+ return; >+ } >+ l->cur_size = new_cur_size; >+ } >+} >+ >+/* >+ Decrease memory limit accounting after a free/realloc. >+*/ >+static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >+ size_t size) >+{ >+ struct talloc_memlimit *l; >+ >+ for (l = limit; l != NULL; l = l->upper) { >+ if (l->cur_size < size) { >+ talloc_abort("logic error in talloc_memlimit_shrink\n"); >+ return; >+ } >+ l->cur_size = l->cur_size - size; >+ } >+} >+ > static bool talloc_memlimit_update(struct talloc_memlimit *limit, > size_t old_size, size_t new_size) > { >-- >1.9.1 > > >From 0a0314d160ae8e316e8a64975b6b9f12ec07a60f Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:43:50 -0700 >Subject: [PATCH 11/47] Remove magic TC_HDR_SIZE handling inside > talloc_memlimit_check(). > >Callers already account for TC_HDR_SIZE, do not add it twice. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 7a6beae68ee3f9a97e9e56f4e24a437839fb3e19) >--- > lib/talloc/talloc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 067d46f..7b827ca 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -2561,7 +2561,7 @@ static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > for (l = limit; l != NULL; l = l->upper) { > if (l->max_size != 0 && > ((l->max_size <= l->cur_size) || >- (l->max_size - l->cur_size < TC_HDR_SIZE+size))) { >+ (l->max_size - l->cur_size < size))) { > return false; > } > } >-- >1.9.1 > > >From 33d24f26485721190f20d7e1ec759107dc9c9340 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:46:09 -0700 >Subject: [PATCH 12/47] Change _talloc_total_mem_internal() to ignore memory > allocated from a pool when calculating limit size. > >We must only count normal tallocs, or a talloc pool itself. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 4159a78ed7eda340758e22286f16186987a20f2f) >--- > lib/talloc/talloc.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 7b827ca..1e25dfd 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1817,7 +1817,14 @@ static size_t _talloc_total_mem_internal(const void *ptr, > break; > case TOTAL_MEM_LIMIT: > if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { >- total = tc->size + TC_HDR_SIZE; >+ /* >+ * Don't count memory allocated from a pool >+ * when calculating limits. Only count the >+ * pool itself. >+ */ >+ if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { >+ total = tc->size + TC_HDR_SIZE; >+ } > } > break; > } >-- >1.9.1 > > >From 79e04be1716149e8c1a907eac0ddec2d16dbaca5 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:49:00 -0700 >Subject: [PATCH 13/47] Change __talloc() to only call > talloc_memlimit_check()/talloc_memlimit_grow() on actual malloc allocation. > >Don't check the memlimit if the allocation was successful from a pool. We already >checked the memory limit when we created the pool. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit a4ebbe73b4b8dcab4d344e693ad9796ec8997f87) >--- > lib/talloc/talloc.c | 21 +++++++++------------ > 1 file changed, 9 insertions(+), 12 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 1e25dfd..cee7d23 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -586,27 +586,24 @@ static inline void *__talloc(const void *context, size_t size) > limit = ptc->limit; > } > >- if (!talloc_memlimit_check(limit, (TC_HDR_SIZE+size))) { >- errno = ENOMEM; >- return NULL; >- } >- > tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size); > } > > if (tc == NULL) { >+ /* >+ * Only do the memlimit check/update on actual allocation. >+ */ >+ if (!talloc_memlimit_check(limit, TC_HDR_SIZE + size)) { >+ errno = ENOMEM; >+ return NULL; >+ } >+ > tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); > if (unlikely(tc == NULL)) return NULL; > tc->flags = TALLOC_MAGIC; > tc->pool = NULL; >- } > >- if (limit != NULL) { >- struct talloc_memlimit *l; >- >- for (l = limit; l != NULL; l = l->upper) { >- l->cur_size += TC_HDR_SIZE+size; >- } >+ talloc_memlimit_grow(limit, TC_HDR_SIZE + size); > } > > tc->limit = limit; >-- >1.9.1 > > >From 5dad0a88c76b652fe1e7136ae2f6e557a28e4a29 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:51:20 -0700 >Subject: [PATCH 14/47] Update memory limits when we call free() on a pool. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 4dfde7d33e7ac6c94833ecc758baff487ab67e4e) >--- > lib/talloc/talloc.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index cee7d23..c45ac93 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -807,6 +807,8 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > */ > pool->hdr.c.name = location; > >+ talloc_memlimit_update_on_free(&pool->hdr.c); >+ > TC_INVALIDATE_FULL_CHUNK(&pool->hdr.c); > free(pool); > return; >-- >1.9.1 > > >From 31f60a973966da13cedf43878947e7489f3d6b5b Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:54:38 -0700 >Subject: [PATCH 15/47] Inside _talloc_free_internal(), always call > talloc_memlimit_update_on_free() before we free the real memory. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 6bc190d6dd7fd0ab028c39c1463477a863f6943a) >--- > lib/talloc/talloc.c | 27 ++++----------------------- > 1 file changed, 4 insertions(+), 23 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index c45ac93..74eca3f 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -909,29 +909,6 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > > tc->flags |= TALLOC_FLAG_FREE; > >- /* >- * If we are part of a memory limited context hierarchy >- * we need to subtract the memory used from the counters >- */ >- if (tc->limit) { >- struct talloc_memlimit *l; >- >- for (l = tc->limit; l != NULL; l = l->upper) { >- if (l->cur_size >= tc->size+TC_HDR_SIZE) { >- l->cur_size -= tc->size+TC_HDR_SIZE; >- } else { >- talloc_abort("cur_size memlimit counter not correct!"); >- return 0; >- } >- } >- >- if (tc->limit->parent == tc) { >- free(tc->limit); >- } >- >- tc->limit = NULL; >- } >- > /* we mark the freed memory with where we called the free > * from. This means on a double free error we can report where > * the first free came from >@@ -952,6 +929,8 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > return 0; > } > >+ talloc_memlimit_update_on_free(tc); >+ > TC_INVALIDATE_FULL_CHUNK(tc); > free(tc); > return 0; >@@ -962,6 +941,8 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > return 0; > } > >+ talloc_memlimit_update_on_free(tc); >+ > TC_INVALIDATE_FULL_CHUNK(tc); > free(tc); > return 0; >-- >1.9.1 > > >From adf164fb1ccf24511654577f94f90531a1fa9e01 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:57:43 -0700 >Subject: [PATCH 16/47] In _talloc_steal_internal(), correctly decrement the > memory limit in the source, and increment in the destination. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 43860293225d14ca2c339277b42f8705322463ab) >--- > lib/talloc/talloc.c | 17 +++++------------ > 1 file changed, 5 insertions(+), 12 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 74eca3f..54f3c0a 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -976,11 +976,8 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > > ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); > >- if (!talloc_memlimit_update(tc->limit->upper, ctx_size, 0)) { >- talloc_abort("cur_size memlimit counter not correct!"); >- errno = EINVAL; >- return NULL; >- } >+ /* Decrement the memory limit from the source .. */ >+ talloc_memlimit_shrink(tc->limit->upper, ctx_size); > > if (tc->limit->parent == tc) { > tc->limit->upper = NULL; >@@ -1028,13 +1025,9 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > if (tc->limit || new_tc->limit) { > ctx_size = _talloc_total_limit_size(ptr, tc->limit, > new_tc->limit); >- } >- >- if (new_tc->limit) { >- struct talloc_memlimit *l; >- >- for (l = new_tc->limit; l != NULL; l = l->upper) { >- l->cur_size += ctx_size; >+ /* .. and increment it in the destination. */ >+ if (new_tc->limit) { >+ talloc_memlimit_grow(new_tc->limit, ctx_size); > } > } > >-- >1.9.1 > > >From 1001970327a1dd2c1fb452557041fe525308f3be Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:59:04 -0700 >Subject: [PATCH 17/47] Fix a conditional check. (size - tc->size > 0) is > always true if size and tc->size are unsigned. > >Replace with (size > tc->size). > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 0fbcfcc824e474874c15d7c0b2ea0df408448906) >--- > lib/talloc/talloc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 54f3c0a..2683ff0 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1507,7 +1507,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > return NULL; > } > >- if (tc->limit && (size - tc->size > 0)) { >+ if (tc->limit && (size > tc->size)) { > if (!talloc_memlimit_check(tc->limit, (size - tc->size))) { > errno = ENOMEM; > return NULL; >-- >1.9.1 > > >From 872ab4445e4c805a3d7b0ec585a0d40dadbbdd99 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:03:27 -0700 >Subject: [PATCH 18/47] Don't call talloc_memlimit_update() inside > _talloc_realloc() when we're just manipulating pool members. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 314508dd73105138d756f4ca3dfb65f1d368a9f7) >--- > lib/talloc/talloc.c | 15 --------------- > 1 file changed, 15 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 2683ff0..aabd2fb 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1629,14 +1629,6 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (new_chunk_size == old_chunk_size) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; >- if (!talloc_memlimit_update(tc->limit, >- tc->size, size)) { >- talloc_abort("cur_size memlimit counter not" >- " correct!"); >- errno = EINVAL; >- return NULL; >- } >- > tc->size = size; > return ptr; > } >@@ -1652,13 +1644,6 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (space_left >= space_needed) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; >- if (!talloc_memlimit_update(tc->limit, >- tc->size, size)) { >- talloc_abort("cur_size memlimit " >- "counter not correct!"); >- errno = EINVAL; >- return NULL; >- } > tc->size = size; > pool_tc->hdr.c.pool = tc_next_chunk(tc); > return ptr; >-- >1.9.1 > > >From edc3211b85b45a7fc4ab62e4e3b9927d39b89026 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:07:04 -0700 >Subject: [PATCH 19/47] Inside _talloc_realloc(), keep track of size changes > over malloc/realloc/free. > >Replace the last use of talloc_memlimit_update() with talloc_memlimit_grow()/ >talloc_memlimit_shrink(). > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 8e2a543e088cac36a5b6bbab1a6be961fa00cc4d) >--- > lib/talloc/talloc.c | 19 +++++++++++++++---- > 1 file changed, 15 insertions(+), 4 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index aabd2fb..66ac110 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1479,6 +1479,8 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > void *new_ptr; > bool malloced = false; > union talloc_pool_chunk *pool_tc = NULL; >+ size_t old_size = 0; >+ size_t new_size = 0; > > /* size zero is equivalent to free() */ > if (unlikely(size == 0)) { >@@ -1566,6 +1568,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); > malloced = true; >+ new_size = size; > } > > if (new_ptr) { >@@ -1573,6 +1576,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > TC_INVALIDATE_FULL_CHUNK(tc); > } > } else { >+ /* We're doing malloc then free here, so record the difference. */ >+ old_size = tc->size; >+ new_size = size; > new_ptr = malloc(size + TC_HDR_SIZE); > if (new_ptr) { > memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE); >@@ -1655,6 +1661,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); > malloced = true; >+ new_size = size; > } > > if (new_ptr) { >@@ -1664,6 +1671,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > } > else { >+ /* We're doing realloc here, so record the difference. */ >+ old_size = tc->size; >+ new_size = size; > new_ptr = realloc(tc, size + TC_HDR_SIZE); > } > got_new_ptr: >@@ -1692,11 +1702,12 @@ got_new_ptr: > tc->next->prev = tc; > } > >- if (!talloc_memlimit_update(tc->limit, tc->size, size)) { >- talloc_abort("cur_size memlimit counter not correct!"); >- errno = EINVAL; >- return NULL; >+ if (new_size > old_size) { >+ talloc_memlimit_grow(tc->limit, new_size - old_size); >+ } else if (new_size < old_size) { >+ talloc_memlimit_shrink(tc->limit, old_size - new_size); > } >+ > tc->size = size; > _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); > >-- >1.9.1 > > >From 91941ada18899cd5b85a9d47e614a609b1ddf9d3 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:08:33 -0700 >Subject: [PATCH 20/47] Remove talloc_memlimit_update(). No longer used. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 3d0f717d437bb24f430fad788b9eb35e8fe8e0e8) >--- > lib/talloc/talloc.c | 24 ------------------------ > 1 file changed, 24 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 66ac110..677ec0f 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -236,8 +236,6 @@ struct talloc_memlimit { > }; > > static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); >-static bool talloc_memlimit_update(struct talloc_memlimit *limit, >- size_t old_size, size_t new_size); > static void talloc_memlimit_grow(struct talloc_memlimit *limit, > size_t size); > static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >@@ -2612,28 +2610,6 @@ static void talloc_memlimit_shrink(struct talloc_memlimit *limit, > } > } > >-static bool talloc_memlimit_update(struct talloc_memlimit *limit, >- size_t old_size, size_t new_size) >-{ >- struct talloc_memlimit *l; >- ssize_t d; >- >- if (old_size == 0) { >- d = new_size + TC_HDR_SIZE; >- } else { >- d = new_size - old_size; >- } >- for (l = limit; l != NULL; l = l->upper) { >- ssize_t new_cur_size = l->cur_size + d; >- if (new_cur_size < 0) { >- return false; >- } >- l->cur_size = new_cur_size; >- } >- >- return true; >-} >- > _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) > { > struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx); >-- >1.9.1 > > >From 7289550d04ad65f39bd6bfd8d6b7051b3271db70 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:09:03 -0700 >Subject: [PATCH 21/47] Add simple limited pool tests to test_memlimit(). > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit cbfc3efbfd4a3a6f3b031ce8ef375d37f2c545f3) >--- > lib/talloc/testsuite.c | 27 +++++++++++++++++++++++++++ > 1 file changed, 27 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index d456cbb..426c31a 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -1359,6 +1359,8 @@ static bool test_memlimit(void) > { > void *root; > char *l1, *l2, *l3, *l4, *l5, *t; >+ char *pool; >+ int i; > > printf("test: memlimit\n# MEMORY LIMITS\n"); > >@@ -1520,6 +1522,31 @@ static bool test_memlimit(void) > talloc_report_full(root, stdout); > talloc_free(root); > >+ /* Test memlimits with pools. */ >+ pool = talloc_pool(NULL, 10*1024); >+ torture_assert("memlimit", pool != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ talloc_set_memlimit(pool, 10*1024); >+ for (i = 0; i < 9; i++) { >+ l1 = talloc_size(pool, 1024); >+ torture_assert("memlimit", l1 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ } >+ /* The next alloc should fail. */ >+ l2 = talloc_size(pool, 1024); >+ torture_assert("memlimit", l2 == NULL, >+ "failed: alloc should fail due to memory limit\n"); >+ >+ /* Moving one of the children shouldn't change the limit, >+ as it's still inside the pool. */ >+ root = talloc_new(NULL); >+ talloc_steal(root, l1); >+ l2 = talloc_size(pool, 1024); >+ torture_assert("memlimit", l2 == NULL, >+ "failed: alloc should fail due to memory limit\n"); >+ >+ talloc_free(pool); >+ talloc_free(root); > printf("success: memlimit\n"); > > return true; >-- >1.9.1 > > >From 743f08d2aa37151cc177855764ee209630b6cd98 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:20:43 -0700 >Subject: [PATCH 22/47] Fix valgrind errors with memmove and talloc pools. > >bin/smbtorture //127.0.0.1 local.talloc now runs with no valgrind errors. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: "Stefan (metze) Metzmacher" <metze@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Wed Aug 28 02:44:17 CEST 2013 on sn-devel-104 > >(cherry picked from commit 617c647b8ef562ace589a11a15eb460e6db71f2a) >--- > lib/talloc/talloc.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 677ec0f..69d5a16 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1609,6 +1609,27 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > size_t old_used = TC_HDR_SIZE + tc->size; > size_t new_used = TC_HDR_SIZE + size; > new_ptr = start; >+ >+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) >+ { >+ /* >+ * The area from >+ * start -> tc may have >+ * been freed and thus been marked as >+ * VALGRIND_MEM_NOACCESS. Set it to >+ * VALGRIND_MEM_UNDEFINED so we can >+ * copy into it without valgrind errors. >+ * We can't just mark >+ * new_ptr -> new_ptr + old_used >+ * as this may overlap on top of tc, >+ * (which is why we use memmove, not >+ * memcpy below) hence the MIN. >+ */ >+ size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used); >+ VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len); >+ } >+#endif >+ > memmove(new_ptr, tc, old_used); > > tc = (struct talloc_chunk *)new_ptr; >-- >1.9.1 > > >From 14ab26ebe6163ca67bfcecd74de9ab9a4a5f5e5f Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 10:54:43 -0700 >Subject: [PATCH 23/47] talloc: Decouple the dual use of chunk->pool > >If we want nested pools, we will have pools that are pool members. So >we will have to have a separate "next object" pointer for pools. As >we have struct talloc_pool_chunk now, this additional pointer does not >affect normal talloc objects. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 1334c745e1f2157b66e14f9d8b4f6f7750238717) >--- > lib/talloc/talloc.c | 48 +++++++++++++++++++++++------------------------- > 1 file changed, 23 insertions(+), 25 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 69d5a16..74db284 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -244,6 +244,8 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); > > typedef int (*talloc_destructor_t)(void *); > >+union talloc_pool_chunk; >+ > struct talloc_chunk { > struct talloc_chunk *next, *prev; > struct talloc_chunk *parent, *child; >@@ -263,17 +265,12 @@ struct talloc_chunk { > struct talloc_memlimit *limit; > > /* >- * "pool" has dual use: >- * >- * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" >- * marks the end of the currently allocated area. >- * >- * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" >+ * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" > * is a pointer to the struct talloc_chunk of the pool that it was > * allocated from. This way children can quickly find the pool to chew > * from. > */ >- void *pool; >+ union talloc_pool_chunk *pool; > }; > > /* 16 byte alignment seems to keep everyone happy */ >@@ -466,6 +463,7 @@ union talloc_pool_chunk { > * on 32-bit platforms. */ > struct tc_pool_hdr { > struct talloc_chunk c; >+ void *next; > unsigned int object_count; > } hdr; > /* This makes it always 16 byte aligned. */ >@@ -479,7 +477,7 @@ static void *tc_pool_end(union talloc_pool_chunk *pool_tc) > > static size_t tc_pool_space_left(union talloc_pool_chunk *pool_tc) > { >- return (char *)tc_pool_end(pool_tc) - (char *)pool_tc->hdr.c.pool; >+ return (char *)tc_pool_end(pool_tc) - (char *)pool_tc->hdr.next; > } > > static void *tc_pool_first_chunk(union talloc_pool_chunk *pool_tc) >@@ -499,11 +497,11 @@ static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) > size_t flen = tc_pool_space_left(pool_tc); > > if (unlikely(talloc_fill.enabled)) { >- memset(pool_tc->hdr.c.pool, talloc_fill.fill_value, flen); >+ memset(pool_tc->hdr.next, talloc_fill.fill_value, flen); > } > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) >- VALGRIND_MAKE_MEM_NOACCESS(pool_tc->hdr.c.pool, flen); >+ VALGRIND_MAKE_MEM_NOACCESS(pool_tc->hdr.next, flen); > #endif > } > >@@ -527,7 +525,7 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > pool_ctx = (union talloc_pool_chunk *)parent; > } > else if (parent->flags & TALLOC_FLAG_POOLMEM) { >- pool_ctx = (union talloc_pool_chunk *)parent->pool; >+ pool_ctx = parent->pool; > } > > if (pool_ctx == NULL) { >@@ -545,13 +543,13 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > return NULL; > } > >- result = (struct talloc_chunk *)pool_ctx->hdr.c.pool; >+ result = (struct talloc_chunk *)pool_ctx->hdr.next; > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) > VALGRIND_MAKE_MEM_UNDEFINED(result, size); > #endif > >- pool_ctx->hdr.c.pool = (void *)((char *)result + chunk_size); >+ pool_ctx->hdr.next = (void *)((char *)result + chunk_size); > > result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; > result->pool = pool_ctx; >@@ -653,7 +651,7 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > return NULL; > } > pool_tc->hdr.c.flags |= TALLOC_FLAG_POOL; >- pool_tc->hdr.c.pool = tc_pool_first_chunk(pool_tc); >+ pool_tc->hdr.next = tc_pool_first_chunk(pool_tc); > > pool_tc->hdr.object_count = 1; > >@@ -763,7 +761,7 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > union talloc_pool_chunk *pool; > void *next_tc; > >- pool = (union talloc_pool_chunk *)tc->pool; >+ pool = tc->pool; > next_tc = tc_next_chunk(tc); > > tc->flags |= TALLOC_FLAG_FREE; >@@ -792,7 +790,7 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > * the rest is available for new objects > * again. > */ >- pool->hdr.c.pool = tc_pool_first_chunk(pool); >+ pool->hdr.next = tc_pool_first_chunk(pool); > tc_invalidate_pool(pool); > return; > } >@@ -812,13 +810,13 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > return; > } > >- if (pool->hdr.c.pool == next_tc) { >+ if (pool->hdr.next == next_tc) { > /* > * if pool->pool still points to end of > * 'tc' (which is stored in the 'next_tc' variable), > * we can reclaim the memory of 'tc'. > */ >- pool->hdr.c.pool = tc; >+ pool->hdr.next = tc; > return; > } > >@@ -1516,7 +1514,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > > /* handle realloc inside a talloc_pool */ > if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { >- pool_tc = (union talloc_pool_chunk *)tc->pool; >+ pool_tc = tc->pool; > } > > #if (ALWAYS_REALLOC == 0) >@@ -1526,9 +1524,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > void *next_tc = tc_next_chunk(tc); > TC_INVALIDATE_SHRINK_CHUNK(tc, size); > tc->size = size; >- if (next_tc == pool_tc->hdr.c.pool) { >+ if (next_tc == pool_tc->hdr.next) { > /* note: tc->size has changed, so this works */ >- pool_tc->hdr.c.pool = tc_next_chunk(tc); >+ pool_tc->hdr.next = tc_next_chunk(tc); > } > return ptr; > } else if ((tc->size - size) < 1024) { >@@ -1640,11 +1638,11 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > * because we want to invalidate the padding > * too. > */ >- pool_tc->hdr.c.pool = new_used + (char *)new_ptr; >+ pool_tc->hdr.next = new_used + (char *)new_ptr; > tc_invalidate_pool(pool_tc); > > /* now the aligned pointer */ >- pool_tc->hdr.c.pool = new_chunk_size + (char *)new_ptr; >+ pool_tc->hdr.next = new_chunk_size + (char *)new_ptr; > goto got_new_ptr; > } > >@@ -1658,7 +1656,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > return ptr; > } > >- if (next_tc == pool_tc->hdr.c.pool) { >+ if (next_tc == pool_tc->hdr.next) { > /* > * optimize for the case where 'tc' is the last > * chunk in the pool. >@@ -1670,7 +1668,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; > tc->size = size; >- pool_tc->hdr.c.pool = tc_next_chunk(tc); >+ pool_tc->hdr.next = tc_next_chunk(tc); > return ptr; > } > } >-- >1.9.1 > > >From c8473289ab5728a760bcdaecbf9b19f4da9c99f7 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 12:18:26 -0700 >Subject: [PATCH 24/47] talloc: Introduce __talloc_with_prefix > >This will allow to exchange the extra talloc pool header with the >talloc_chunk structure > >Signed-off-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 9887f387a10e94f71790c0c3c7dc5f8cde7e4eb2) >--- > lib/talloc/talloc.c | 32 ++++++++++++++++++++++---------- > 1 file changed, 22 insertions(+), 10 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 74db284..21d675d 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -510,7 +510,7 @@ static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) > */ > > static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, >- size_t size) >+ size_t size, size_t prefix_len) > { > union talloc_pool_chunk *pool_ctx = NULL; > size_t space_left; >@@ -537,13 +537,14 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > /* > * Align size to 16 bytes > */ >- chunk_size = TC_ALIGN16(size); >+ chunk_size = TC_ALIGN16(size + prefix_len); > > if (space_left < chunk_size) { > return NULL; > } > >- result = (struct talloc_chunk *)pool_ctx->hdr.next; >+ result = (struct talloc_chunk *) >+ ((char *)pool_ctx->hdr.next + prefix_len); > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) > VALGRIND_MAKE_MEM_UNDEFINED(result, size); >@@ -562,10 +563,12 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > /* > Allocate a bit of memory as a child of an existing pointer > */ >-static inline void *__talloc(const void *context, size_t size) >+static inline void *__talloc_with_prefix(const void *context, size_t size, >+ size_t prefix_len) > { > struct talloc_chunk *tc = NULL; > struct talloc_memlimit *limit = NULL; >+ size_t total_len = TC_HDR_SIZE + size + prefix_len; > > if (unlikely(context == NULL)) { > context = null_context; >@@ -575,6 +578,10 @@ static inline void *__talloc(const void *context, size_t size) > return NULL; > } > >+ if (unlikely(total_len < TC_HDR_SIZE)) { >+ return NULL; >+ } >+ > if (context != NULL) { > struct talloc_chunk *ptc = talloc_chunk_from_ptr(context); > >@@ -582,24 +589,24 @@ static inline void *__talloc(const void *context, size_t size) > limit = ptc->limit; > } > >- tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size); >+ tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len); > } > > if (tc == NULL) { > /* > * Only do the memlimit check/update on actual allocation. > */ >- if (!talloc_memlimit_check(limit, TC_HDR_SIZE + size)) { >+ if (!talloc_memlimit_check(limit, total_len)) { > errno = ENOMEM; > return NULL; > } > >- tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); >+ tc = (struct talloc_chunk *)malloc(total_len); > if (unlikely(tc == NULL)) return NULL; > tc->flags = TALLOC_MAGIC; > tc->pool = NULL; > >- talloc_memlimit_grow(limit, TC_HDR_SIZE + size); >+ talloc_memlimit_grow(limit, total_len); > } > > tc->limit = limit; >@@ -629,6 +636,11 @@ static inline void *__talloc(const void *context, size_t size) > return TC_PTR_FROM_CHUNK(tc); > } > >+static inline void *__talloc(const void *context, size_t size) >+{ >+ return __talloc_with_prefix(context, size, 0); >+} >+ > /* > * Create a talloc pool > */ >@@ -1558,7 +1570,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > > #if ALWAYS_REALLOC > if (pool_tc) { >- new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); >+ new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0); > pool_tc->hdr.object_count--; > > if (new_ptr == NULL) { >@@ -1673,7 +1685,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > } > >- new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); >+ new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0); > > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); >-- >1.9.1 > > >From e452a83b73056f64001d757f98ac1fc88627c5bc Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 14:08:43 -0700 >Subject: [PATCH 25/47] talloc: Put pool-specific data before the chunk > >This is a preparation to make talloc pool real objects themselves. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit b87c8fd435d1863d6efcec03830ecd85ddfcd7fb) >--- > lib/talloc/talloc.c | 204 ++++++++++++++++++++++++++++++++-------------------- > 1 file changed, 125 insertions(+), 79 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 21d675d..a553050 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -244,7 +244,7 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); > > typedef int (*talloc_destructor_t)(void *); > >-union talloc_pool_chunk; >+struct talloc_pool_hdr; > > struct talloc_chunk { > struct talloc_chunk *next, *prev; >@@ -270,7 +270,7 @@ struct talloc_chunk { > * allocated from. This way children can quickly find the pool to chew > * from. > */ >- union talloc_pool_chunk *pool; >+ struct talloc_pool_hdr *pool; > }; > > /* 16 byte alignment seems to keep everyone happy */ >@@ -458,31 +458,37 @@ _PUBLIC_ const char *talloc_parent_name(const void *ptr) > memory footprint of each talloc chunk by those 16 bytes. > */ > >-union talloc_pool_chunk { >- /* This lets object_count nestle into 16-byte padding of talloc_chunk, >- * on 32-bit platforms. */ >- struct tc_pool_hdr { >- struct talloc_chunk c; >- void *next; >- unsigned int object_count; >- } hdr; >- /* This makes it always 16 byte aligned. */ >- char pad[TC_ALIGN16(sizeof(struct tc_pool_hdr))]; >+struct talloc_pool_hdr { >+ void *end; >+ unsigned int object_count; > }; > >-static void *tc_pool_end(union talloc_pool_chunk *pool_tc) >+#define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) >+ >+static struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) >+{ >+ return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE); >+} >+ >+static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) > { >- return (char *)pool_tc + TC_HDR_SIZE + pool_tc->hdr.c.size; >+ return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE); > } > >-static size_t tc_pool_space_left(union talloc_pool_chunk *pool_tc) >+static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) > { >- return (char *)tc_pool_end(pool_tc) - (char *)pool_tc->hdr.next; >+ struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); >+ return (char *)tc + TC_HDR_SIZE + tc->size; > } > >-static void *tc_pool_first_chunk(union talloc_pool_chunk *pool_tc) >+static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) > { >- return pool_tc + 1; >+ return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; >+} >+ >+static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >+{ >+ return TC_PTR_FROM_CHUNK(talloc_chunk_from_pool(pool_hdr)); > } > > /* If tc is inside a pool, this gives the next neighbour. */ >@@ -492,16 +498,16 @@ static void *tc_next_chunk(struct talloc_chunk *tc) > } > > /* Mark the whole remaining pool as not accessable */ >-static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) >+static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > { >- size_t flen = tc_pool_space_left(pool_tc); >+ size_t flen = tc_pool_space_left(pool_hdr); > > if (unlikely(talloc_fill.enabled)) { >- memset(pool_tc->hdr.next, talloc_fill.fill_value, flen); >+ memset(pool_hdr->end, talloc_fill.fill_value, flen); > } > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) >- VALGRIND_MAKE_MEM_NOACCESS(pool_tc->hdr.next, flen); >+ VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen); > #endif > } > >@@ -512,7 +518,7 @@ static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) > static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > size_t size, size_t prefix_len) > { >- union talloc_pool_chunk *pool_ctx = NULL; >+ struct talloc_pool_hdr *pool_hdr = NULL; > size_t space_left; > struct talloc_chunk *result; > size_t chunk_size; >@@ -522,17 +528,17 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > } > > if (parent->flags & TALLOC_FLAG_POOL) { >- pool_ctx = (union talloc_pool_chunk *)parent; >+ pool_hdr = talloc_pool_from_chunk(parent); > } > else if (parent->flags & TALLOC_FLAG_POOLMEM) { >- pool_ctx = parent->pool; >+ pool_hdr = parent->pool; > } > >- if (pool_ctx == NULL) { >+ if (pool_hdr == NULL) { > return NULL; > } > >- space_left = tc_pool_space_left(pool_ctx); >+ space_left = tc_pool_space_left(pool_hdr); > > /* > * Align size to 16 bytes >@@ -543,19 +549,18 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > return NULL; > } > >- result = (struct talloc_chunk *) >- ((char *)pool_ctx->hdr.next + prefix_len); >+ result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len); > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) >- VALGRIND_MAKE_MEM_UNDEFINED(result, size); >+ VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size); > #endif > >- pool_ctx->hdr.next = (void *)((char *)result + chunk_size); >+ pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size); > > result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; >- result->pool = pool_ctx; >+ result->pool = pool_hdr; > >- pool_ctx->hdr.object_count++; >+ pool_hdr->object_count++; > > return result; > } >@@ -593,6 +598,8 @@ static inline void *__talloc_with_prefix(const void *context, size_t size, > } > > if (tc == NULL) { >+ char *ptr; >+ > /* > * Only do the memlimit check/update on actual allocation. > */ >@@ -601,8 +608,11 @@ static inline void *__talloc_with_prefix(const void *context, size_t size, > return NULL; > } > >- tc = (struct talloc_chunk *)malloc(total_len); >- if (unlikely(tc == NULL)) return NULL; >+ ptr = malloc(total_len); >+ if (unlikely(ptr == NULL)) { >+ return NULL; >+ } >+ tc = (struct talloc_chunk *)(ptr + prefix_len); > tc->flags = TALLOC_MAGIC; > tc->pool = NULL; > >@@ -647,27 +657,32 @@ static inline void *__talloc(const void *context, size_t size) > > _PUBLIC_ void *talloc_pool(const void *context, size_t size) > { >- union talloc_pool_chunk *pool_tc; >- void *result = __talloc(context, sizeof(*pool_tc) - TC_HDR_SIZE + size); >+ struct talloc_chunk *tc; >+ struct talloc_pool_hdr *pool_hdr; >+ void *result; >+ >+ result = __talloc_with_prefix(context, size, TP_HDR_SIZE); > > if (unlikely(result == NULL)) { > return NULL; > } > >- pool_tc = (union talloc_pool_chunk *)talloc_chunk_from_ptr(result); >- if (unlikely(pool_tc->hdr.c.flags & TALLOC_FLAG_POOLMEM)) { >+ tc = talloc_chunk_from_ptr(result); >+ pool_hdr = talloc_pool_from_chunk(tc); >+ >+ if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { > /* We don't handle this correctly, so fail. */ > talloc_log("talloc: cannot allocate pool off another pool %s\n", > talloc_get_name(context)); > talloc_free(result); > return NULL; > } >- pool_tc->hdr.c.flags |= TALLOC_FLAG_POOL; >- pool_tc->hdr.next = tc_pool_first_chunk(pool_tc); >+ tc->flags |= TALLOC_FLAG_POOL; > >- pool_tc->hdr.object_count = 1; >+ pool_hdr->object_count = 1; >+ pool_hdr->end = result; > >- tc_invalidate_pool(pool_tc); >+ tc_invalidate_pool(pool_hdr); > > return result; > } >@@ -770,10 +785,12 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr); > static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > const char *location) > { >- union talloc_pool_chunk *pool; >+ struct talloc_pool_hdr *pool; >+ struct talloc_chunk *pool_tc; > void *next_tc; > > pool = tc->pool; >+ pool_tc = talloc_chunk_from_pool(pool); > next_tc = tc_next_chunk(tc); > > tc->flags |= TALLOC_FLAG_FREE; >@@ -786,15 +803,15 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > > TC_INVALIDATE_FULL_CHUNK(tc); > >- if (unlikely(pool->hdr.object_count == 0)) { >+ if (unlikely(pool->object_count == 0)) { > talloc_abort("Pool object count zero!"); > return; > } > >- pool->hdr.object_count--; >+ pool->object_count--; > >- if (unlikely(pool->hdr.object_count == 1 >- && !(pool->hdr.c.flags & TALLOC_FLAG_FREE))) { >+ if (unlikely(pool->object_count == 1 >+ && !(pool_tc->flags & TALLOC_FLAG_FREE))) { > /* > * if there is just one object left in the pool > * and pool->flags does not have TALLOC_FLAG_FREE, >@@ -802,33 +819,33 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > * the rest is available for new objects > * again. > */ >- pool->hdr.next = tc_pool_first_chunk(pool); >+ pool->end = tc_pool_first_chunk(pool); > tc_invalidate_pool(pool); > return; > } > >- if (unlikely(pool->hdr.object_count == 0)) { >+ if (unlikely(pool->object_count == 0)) { > /* > * we mark the freed memory with where we called the free > * from. This means on a double free error we can report where > * the first free came from > */ >- pool->hdr.c.name = location; >+ pool_tc->name = location; > >- talloc_memlimit_update_on_free(&pool->hdr.c); >+ talloc_memlimit_update_on_free(pool_tc); > >- TC_INVALIDATE_FULL_CHUNK(&pool->hdr.c); >+ TC_INVALIDATE_FULL_CHUNK(pool_tc); > free(pool); > return; > } > >- if (pool->hdr.next == next_tc) { >+ if (pool->end == next_tc) { > /* > * if pool->pool still points to end of > * 'tc' (which is stored in the 'next_tc' variable), > * we can reclaim the memory of 'tc'. > */ >- pool->hdr.next = tc; >+ pool->end = tc; > return; > } > >@@ -924,23 +941,30 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > tc->name = location; > > if (tc->flags & TALLOC_FLAG_POOL) { >- union talloc_pool_chunk *pool = (union talloc_pool_chunk *)tc; >+ struct talloc_pool_hdr *pool; >+ >+ pool = talloc_pool_from_chunk(tc); > >- if (unlikely(pool->hdr.object_count == 0)) { >+ if (unlikely(pool->object_count == 0)) { > talloc_abort("Pool object count zero!"); > return 0; > } > >- pool->hdr.object_count--; >+ pool->object_count--; > >- if (likely(pool->hdr.object_count != 0)) { >+ if (likely(pool->object_count != 0)) { > return 0; > } > >+ /* >+ * This call takes into account the >+ * prefix TP_HDR_SIZE allocated before >+ * the pool talloc_chunk. >+ */ > talloc_memlimit_update_on_free(tc); > > TC_INVALIDATE_FULL_CHUNK(tc); >- free(tc); >+ free(pool); > return 0; > } > >@@ -1486,7 +1510,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > struct talloc_chunk *tc; > void *new_ptr; > bool malloced = false; >- union talloc_pool_chunk *pool_tc = NULL; >+ struct talloc_pool_hdr *pool_hdr = NULL; > size_t old_size = 0; > size_t new_size = 0; > >@@ -1526,19 +1550,19 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > > /* handle realloc inside a talloc_pool */ > if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { >- pool_tc = tc->pool; >+ pool_hdr = tc->pool; > } > > #if (ALWAYS_REALLOC == 0) > /* don't shrink if we have less than 1k to gain */ > if (size < tc->size && tc->limit == NULL) { >- if (pool_tc) { >+ if (pool_hdr) { > void *next_tc = tc_next_chunk(tc); > TC_INVALIDATE_SHRINK_CHUNK(tc, size); > tc->size = size; >- if (next_tc == pool_tc->hdr.next) { >+ if (next_tc == pool_hdr->end) { > /* note: tc->size has changed, so this works */ >- pool_tc->hdr.next = tc_next_chunk(tc); >+ pool_hdr->end = tc_next_chunk(tc); > } > return ptr; > } else if ((tc->size - size) < 1024) { >@@ -1569,9 +1593,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > tc->flags |= TALLOC_FLAG_FREE; > > #if ALWAYS_REALLOC >- if (pool_tc) { >+ if (pool_hdr) { > new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0); >- pool_tc->hdr.object_count--; >+ pool_hdr->object_count--; > > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); >@@ -1594,15 +1618,17 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > } > #else >- if (pool_tc) { >+ if (pool_hdr) { >+ struct talloc_chunk *pool_tc; > void *next_tc = tc_next_chunk(tc); > size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size); > size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size); > size_t space_needed; > size_t space_left; >- unsigned int chunk_count = pool_tc->hdr.object_count; >+ unsigned int chunk_count = pool_hdr->object_count; > >- if (!(pool_tc->hdr.c.flags & TALLOC_FLAG_FREE)) { >+ pool_tc = talloc_chunk_from_pool(pool_hdr); >+ if (!(pool_tc->flags & TALLOC_FLAG_FREE)) { > chunk_count -= 1; > } > >@@ -1611,9 +1637,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > * optimize for the case where 'tc' is the only > * chunk in the pool. > */ >- char *start = tc_pool_first_chunk(pool_tc); >+ char *start = tc_pool_first_chunk(pool_hdr); > space_needed = new_chunk_size; >- space_left = (char *)tc_pool_end(pool_tc) - start; >+ space_left = (char *)tc_pool_end(pool_hdr) - start; > > if (space_left >= space_needed) { > size_t old_used = TC_HDR_SIZE + tc->size; >@@ -1650,11 +1676,11 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > * because we want to invalidate the padding > * too. > */ >- pool_tc->hdr.next = new_used + (char *)new_ptr; >- tc_invalidate_pool(pool_tc); >+ pool_hdr->end = new_used + (char *)new_ptr; >+ tc_invalidate_pool(pool_hdr); > > /* now the aligned pointer */ >- pool_tc->hdr.next = new_chunk_size + (char *)new_ptr; >+ pool_hdr->end = new_chunk_size + (char *)new_ptr; > goto got_new_ptr; > } > >@@ -1668,19 +1694,19 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > return ptr; > } > >- if (next_tc == pool_tc->hdr.next) { >+ if (next_tc == pool_hdr->end) { > /* > * optimize for the case where 'tc' is the last > * chunk in the pool. > */ > space_needed = new_chunk_size - old_chunk_size; >- space_left = tc_pool_space_left(pool_tc); >+ space_left = tc_pool_space_left(pool_hdr); > > if (space_left >= space_needed) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; > tc->size = size; >- pool_tc->hdr.next = tc_next_chunk(tc); >+ pool_hdr->end = tc_next_chunk(tc); > return ptr; > } > } >@@ -1822,6 +1848,13 @@ static size_t _talloc_total_mem_internal(const void *ptr, > */ > if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { > total = tc->size + TC_HDR_SIZE; >+ /* >+ * If this is a pool, remember to >+ * add the prefix length. >+ */ >+ if (tc->flags & TALLOC_FLAG_POOL) { >+ total += TP_HDR_SIZE; >+ } > } > } > break; >@@ -2579,6 +2612,8 @@ static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > */ > static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) > { >+ size_t limit_shrink_size; >+ > if (!tc->limit) { > return; > } >@@ -2597,7 +2632,18 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) > * we need to subtract the memory used from the counters > */ > >- talloc_memlimit_shrink(tc->limit, tc->size+TC_HDR_SIZE); >+ limit_shrink_size = tc->size+TC_HDR_SIZE; >+ >+ /* >+ * If we're deallocating a pool, take into >+ * account the prefix size added for the pool. >+ */ >+ >+ if (tc->flags & TALLOC_FLAG_POOL) { >+ limit_shrink_size += TP_HDR_SIZE; >+ } >+ >+ talloc_memlimit_shrink(tc->limit, limit_shrink_size); > > if (tc->limit->parent == tc) { > free(tc->limit); >-- >1.9.1 > > >From 35d9ff77439b28f9dd7b87941ab38380aff91c47 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 14:20:20 -0700 >Subject: [PATCH 26/47] talloc: Add a separate pool size > >This is necessary to allow talloc pools to be objects on their own. It >is an incompatible change in the sense that talloc_get_size(pool) now >returns 0 instead of the pool size. When the talloc_pooled_object() >call is added, this will start to make sense again. > >Maybe we should add a talloc_pool_size call? Or is that overkill? > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit a3d9099d9a96b36df21ee0733adc5210438fe9dc) >--- > lib/talloc/talloc.c | 35 +++++++++++++++++++++++------------ > 1 file changed, 23 insertions(+), 12 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index a553050..5d13567 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -461,6 +461,7 @@ _PUBLIC_ const char *talloc_parent_name(const void *ptr) > struct talloc_pool_hdr { > void *end; > unsigned int object_count; >+ size_t poolsize; > }; > > #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) >@@ -478,7 +479,7 @@ static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) > static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) > { > struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); >- return (char *)tc + TC_HDR_SIZE + tc->size; >+ return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize; > } > > static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) >@@ -486,17 +487,18 @@ static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) > return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; > } > >-static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >-{ >- return TC_PTR_FROM_CHUNK(talloc_chunk_from_pool(pool_hdr)); >-} >- > /* If tc is inside a pool, this gives the next neighbour. */ > static void *tc_next_chunk(struct talloc_chunk *tc) > { > return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); > } > >+static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >+{ >+ struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); >+ return tc_next_chunk(tc); >+} >+ > /* Mark the whole remaining pool as not accessable */ > static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > { >@@ -678,9 +680,11 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > return NULL; > } > tc->flags |= TALLOC_FLAG_POOL; >+ tc->size = 0; > > pool_hdr->object_count = 1; > pool_hdr->end = result; >+ pool_hdr->poolsize = size; > > tc_invalidate_pool(pool_hdr); > >@@ -1847,13 +1851,20 @@ static size_t _talloc_total_mem_internal(const void *ptr, > * pool itself. > */ > if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { >- total = tc->size + TC_HDR_SIZE; >- /* >- * If this is a pool, remember to >- * add the prefix length. >- */ > if (tc->flags & TALLOC_FLAG_POOL) { >- total += TP_HDR_SIZE; >+ /* >+ * If this is a pool, the allocated >+ * size is in the pool header, and >+ * remember to add in the prefix >+ * length. >+ */ >+ struct talloc_pool_hdr *pool_hdr >+ = talloc_pool_from_chunk(tc); >+ total = pool_hdr->poolsize + >+ TC_HDR_SIZE + >+ TP_HDR_SIZE; >+ } else { >+ total = tc->size + TC_HDR_SIZE; > } > } > } >-- >1.9.1 > > >From 4bebbe98dfe5326692e6b5a49d720622e136635d Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 14:52:28 -0700 >Subject: [PATCH 27/47] talloc: Allow nested pools. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 20ad6d7aa3dc5e7db4d886202f757ac1f68287d4) >--- > lib/talloc/talloc.c | 47 +++++++++++++++++++++++++---------------------- > lib/talloc/talloc.h | 3 +-- > lib/talloc/testsuite.c | 26 ++++++++++++++++++++++++++ > 3 files changed, 52 insertions(+), 24 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 5d13567..198bab9 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -672,13 +672,6 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > tc = talloc_chunk_from_ptr(result); > pool_hdr = talloc_pool_from_chunk(tc); > >- if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { >- /* We don't handle this correctly, so fail. */ >- talloc_log("talloc: cannot allocate pool off another pool %s\n", >- talloc_get_name(context)); >- talloc_free(result); >- return NULL; >- } > tc->flags |= TALLOC_FLAG_POOL; > tc->size = 0; > >@@ -836,10 +829,19 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > */ > pool_tc->name = location; > >- talloc_memlimit_update_on_free(pool_tc); >- >- TC_INVALIDATE_FULL_CHUNK(pool_tc); >- free(pool); >+ if (pool_tc->flags & TALLOC_FLAG_POOLMEM) { >+ _talloc_free_poolmem(pool_tc, location); >+ } else { >+ /* >+ * The talloc_memlimit_update_on_free() >+ * call takes into account the >+ * prefix TP_HDR_SIZE allocated before >+ * the pool talloc_chunk. >+ */ >+ talloc_memlimit_update_on_free(pool_tc); >+ TC_INVALIDATE_FULL_CHUNK(pool_tc); >+ free(pool); >+ } > return; > } > >@@ -869,6 +871,7 @@ static inline void _talloc_free_children_internal(struct talloc_chunk *tc, > static inline int _talloc_free_internal(void *ptr, const char *location) > { > struct talloc_chunk *tc; >+ void *ptr_to_free; > > if (unlikely(ptr == NULL)) { > return -1; >@@ -961,15 +964,13 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > } > > /* >- * This call takes into account the >- * prefix TP_HDR_SIZE allocated before >- * the pool talloc_chunk. >- */ >- talloc_memlimit_update_on_free(tc); >- >- TC_INVALIDATE_FULL_CHUNK(tc); >- free(pool); >- return 0; >+ * With object_count==0, a pool becomes a normal piece of >+ * memory to free. If it's allocated inside a pool, it needs >+ * to be freed as poolmem, else it needs to be just freed. >+ */ >+ ptr_to_free = pool; >+ } else { >+ ptr_to_free = tc; > } > > if (tc->flags & TALLOC_FLAG_POOLMEM) { >@@ -980,7 +981,7 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > talloc_memlimit_update_on_free(tc); > > TC_INVALIDATE_FULL_CHUNK(tc); >- free(tc); >+ free(ptr_to_free); > return 0; > } > >@@ -2632,7 +2633,9 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) > /* > * Pool entries don't count. Only the pools > * themselves are counted as part of the memory >- * limits. >+ * limits. Note that this also takes care of >+ * nested pools which have both flags >+ * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set. > */ > if (tc->flags & TALLOC_FLAG_POOLMEM) { > return; >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index f3cbcd0..aa9864b 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -839,8 +839,7 @@ void *talloc_find_parent_bytype(const void *ptr, #type); > * talloc pool to a talloc parent outside the pool, the whole pool memory is > * not free(3)'ed until that moved chunk is also talloc_free()ed. > * >- * @param[in] context The talloc context to hang the result off (must not >- * be another pool). >+ * @param[in] context The talloc context to hang the result off. > * > * @param[in] size Size of the talloc pool. > * >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index 426c31a..f04f4f1 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -1267,6 +1267,30 @@ static bool test_pool_steal(void) > return true; > } > >+static bool test_pool_nest(void) >+{ >+ void *p1, *p2, *p3; >+ void *e = talloc_new(NULL); >+ >+ p1 = talloc_pool(NULL, 1024); >+ torture_assert("talloc_pool", p1 != NULL, "failed"); >+ >+ p2 = talloc_pool(p1, 500); >+ torture_assert("talloc_pool", p2 != NULL, "failed"); >+ >+ p3 = talloc_size(p2, 10); >+ >+ talloc_steal(e, p3); >+ >+ talloc_free(p2); >+ >+ talloc_free(p3); >+ >+ talloc_free(p1); >+ >+ return true; >+} >+ > static bool test_free_ref_null_context(void) > { > void *p1, *p2, *p3; >@@ -1567,6 +1591,8 @@ bool torture_local_talloc(struct torture_context *tctx) > setlinebuf(stdout); > > test_reset(); >+ ret &= test_pool_nest(); >+ test_reset(); > ret &= test_ref1(); > test_reset(); > ret &= test_ref2(); >-- >1.9.1 > > >From 362946fb96155b43ed7608d9e4fed8990ae3972c Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 15:15:32 -0700 >Subject: [PATCH 28/47] talloc: Add talloc_pooled_object > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit e82320e5197bcdd0330bc829c0963ad09854a36c) >--- > lib/talloc/ABI/pytalloc-util-2.1.0.sigs | 6 +++ > lib/talloc/ABI/talloc-2.1.0.sigs | 64 ++++++++++++++++++++++++++++++++ > lib/talloc/talloc.c | 66 +++++++++++++++++++++++++++++++++ > lib/talloc/talloc.h | 37 ++++++++++++++++++ > lib/talloc/wscript | 2 +- > 5 files changed, 174 insertions(+), 1 deletion(-) > create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.0.sigs > create mode 100644 lib/talloc/ABI/talloc-2.1.0.sigs > >diff --git a/lib/talloc/ABI/pytalloc-util-2.1.0.sigs b/lib/talloc/ABI/pytalloc-util-2.1.0.sigs >new file mode 100644 >index 0000000..961c1a8 >--- /dev/null >+++ b/lib/talloc/ABI/pytalloc-util-2.1.0.sigs >@@ -0,0 +1,6 @@ >+pytalloc_CObject_FromTallocPtr: PyObject *(void *) >+pytalloc_Check: int (PyObject *) >+pytalloc_GetObjectType: PyTypeObject *(void) >+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >+pytalloc_steal: PyObject *(PyTypeObject *, void *) >+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >diff --git a/lib/talloc/ABI/talloc-2.1.0.sigs b/lib/talloc/ABI/talloc-2.1.0.sigs >new file mode 100644 >index 0000000..eae12cc >--- /dev/null >+++ b/lib/talloc/ABI/talloc-2.1.0.sigs >@@ -0,0 +1,64 @@ >+_talloc: void *(const void *, size_t) >+_talloc_array: void *(const void *, size_t, unsigned int, const char *) >+_talloc_free: int (void *, const char *) >+_talloc_get_type_abort: void *(const void *, const char *, const char *) >+_talloc_memdup: void *(const void *, const void *, size_t, const char *) >+_talloc_move: void *(const void *, const void *) >+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) >+_talloc_realloc: void *(const void *, void *, size_t, const char *) >+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) >+_talloc_reference_loc: void *(const void *, const void *, const char *) >+_talloc_set_destructor: void (const void *, int (*)(void *)) >+_talloc_steal_loc: void *(const void *, const void *, const char *) >+_talloc_zero: void *(const void *, size_t, const char *) >+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) >+talloc_asprintf: char *(const void *, const char *, ...) >+talloc_asprintf_append: char *(char *, const char *, ...) >+talloc_asprintf_append_buffer: char *(char *, const char *, ...) >+talloc_autofree_context: void *(void) >+talloc_check_name: void *(const void *, const char *) >+talloc_disable_null_tracking: void (void) >+talloc_enable_leak_report: void (void) >+talloc_enable_leak_report_full: void (void) >+talloc_enable_null_tracking: void (void) >+talloc_enable_null_tracking_no_autofree: void (void) >+talloc_find_parent_byname: void *(const void *, const char *) >+talloc_free_children: void (void *) >+talloc_get_name: const char *(const void *) >+talloc_get_size: size_t (const void *) >+talloc_increase_ref_count: int (const void *) >+talloc_init: void *(const char *, ...) >+talloc_is_parent: int (const void *, const void *) >+talloc_named: void *(const void *, size_t, const char *, ...) >+talloc_named_const: void *(const void *, size_t, const char *) >+talloc_parent: void *(const void *) >+talloc_parent_name: const char *(const void *) >+talloc_pool: void *(const void *, size_t) >+talloc_realloc_fn: void *(const void *, void *, size_t) >+talloc_reference_count: size_t (const void *) >+talloc_reparent: void *(const void *, const void *, const void *) >+talloc_report: void (const void *, FILE *) >+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) >+talloc_report_depth_file: void (const void *, int, int, FILE *) >+talloc_report_full: void (const void *, FILE *) >+talloc_set_abort_fn: void (void (*)(const char *)) >+talloc_set_log_fn: void (void (*)(const char *)) >+talloc_set_log_stderr: void (void) >+talloc_set_memlimit: int (const void *, size_t) >+talloc_set_name: const char *(const void *, const char *, ...) >+talloc_set_name_const: void (const void *, const char *) >+talloc_show_parents: void (const void *, FILE *) >+talloc_strdup: char *(const void *, const char *) >+talloc_strdup_append: char *(char *, const char *) >+talloc_strdup_append_buffer: char *(char *, const char *) >+talloc_strndup: char *(const void *, const char *, size_t) >+talloc_strndup_append: char *(char *, const char *, size_t) >+talloc_strndup_append_buffer: char *(char *, const char *, size_t) >+talloc_total_blocks: size_t (const void *) >+talloc_total_size: size_t (const void *) >+talloc_unlink: int (const void *, void *) >+talloc_vasprintf: char *(const void *, const char *, va_list) >+talloc_vasprintf_append: char *(char *, const char *, va_list) >+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) >+talloc_version_major: int (void) >+talloc_version_minor: int (void) >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 198bab9..1cb4d7d 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -685,6 +685,72 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > } > > /* >+ * Create a talloc pool correctly sized for a basic size plus >+ * a number of subobjects whose total size is given. Essentially >+ * a custom allocator for talloc to reduce fragmentation. >+ */ >+ >+_PUBLIC_ void *_talloc_pooled_object(const void *ctx, >+ size_t type_size, >+ const char *type_name, >+ unsigned num_subobjects, >+ size_t total_subobjects_size) >+{ >+ size_t poolsize, subobjects_slack, tmp; >+ struct talloc_chunk *tc; >+ struct talloc_pool_hdr *pool_hdr; >+ void *ret; >+ >+ poolsize = type_size + total_subobjects_size; >+ >+ if ((poolsize < type_size) || (poolsize < total_subobjects_size)) { >+ goto overflow; >+ } >+ >+ if (num_subobjects == UINT_MAX) { >+ goto overflow; >+ } >+ num_subobjects += 1; /* the object body itself */ >+ >+ /* >+ * Alignment can increase the pool size by at most 15 bytes per object >+ * plus alignment for the object itself >+ */ >+ subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects; >+ if (subobjects_slack < num_subobjects) { >+ goto overflow; >+ } >+ >+ tmp = poolsize + subobjects_slack; >+ if ((tmp < poolsize) || (tmp < subobjects_slack)) { >+ goto overflow; >+ } >+ poolsize = tmp; >+ >+ ret = talloc_pool(ctx, poolsize); >+ if (ret == NULL) { >+ return NULL; >+ } >+ >+ tc = talloc_chunk_from_ptr(ret); >+ tc->size = type_size; >+ >+ pool_hdr = talloc_pool_from_chunk(tc); >+ >+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) >+ VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size); >+#endif >+ >+ pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size)); >+ >+ talloc_set_name_const(ret, type_name); >+ return ret; >+ >+overflow: >+ return NULL; >+} >+ >+/* > setup a destructor to be called on free of a pointer > the destructor should return 0 on success, or -1 on failure. > if the destructor fails then the free is failed, and the memory can >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index aa9864b..1b59390 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -847,6 +847,43 @@ void *talloc_find_parent_bytype(const void *ptr, #type); > */ > void *talloc_pool(const void *context, size_t size); > >+#ifdef DOXYGEN >+/** >+ * @brief Allocate a talloc object as/with an additional pool. >+ * >+ * This is like talloc_pool(), but's it's more flexible >+ * and allows an object to be a pool for its children. >+ * >+ * @param[in] ctx The talloc context to hang the result off. >+ * >+ * @param[in] type The type that we want to allocate. >+ * >+ * @param[in] num_subobjects The expected number of subobjects, which will >+ * be allocated within the pool. This allocates >+ * space for talloc_chunk headers. >+ * >+ * @param[in] total_subobjects_size The size that all subobjects can use in total. >+ * >+ * >+ * @return The allocated talloc object, NULL on error. >+ */ >+void *talloc_pooled_object(const void *ctx, #type, >+ unsigned num_subobjects, >+ size_t total_subobjects_size); >+#else >+#define talloc_pooled_object(_ctx, _type, \ >+ _num_subobjects, \ >+ _total_subobjects_size) \ >+ (_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \ >+ (_num_subobjects), \ >+ (_total_subobjects_size)) >+void *_talloc_pooled_object(const void *ctx, >+ size_t type_size, >+ const char *type_name, >+ unsigned num_subobjects, >+ size_t total_subobjects_size); >+#endif >+ > /** > * @brief Free a talloc chunk and NULL out the pointer. > * >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index ecc5e24..1ca41f6 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'talloc' >-VERSION = '2.0.8' >+VERSION = '2.1.0' > > > blddir = 'bin' >-- >1.9.1 > > >From 573396891865f25202d064bc51f80bcd72802da9 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 15:30:38 -0700 >Subject: [PATCH 29/47] talloc: Test the pooled object > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 256d10f5792a37d20cbb45f2af3f8578bd354110) >--- > lib/talloc/testsuite.c | 36 ++++++++++++++++++++++++++++++++++++ > 1 file changed, 36 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index f04f4f1..888d260 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -1291,6 +1291,40 @@ static bool test_pool_nest(void) > return true; > } > >+struct pooled { >+ char *s1; >+ char *s2; >+ char *s3; >+}; >+ >+static bool test_pooled_object(void) >+{ >+ struct pooled *p; >+ const char *s1 = "hello"; >+ const char *s2 = "world"; >+ const char *s3 = ""; >+ >+ p = talloc_pooled_object(NULL, struct pooled, 3, >+ strlen(s1)+strlen(s2)+strlen(s3)+3); >+ >+ if (talloc_get_size(p) != sizeof(struct pooled)) { >+ return false; >+ } >+ >+ p->s1 = talloc_strdup(p, s1); >+ >+ TALLOC_FREE(p->s1); >+ p->s1 = talloc_strdup(p, s2); >+ TALLOC_FREE(p->s1); >+ >+ p->s1 = talloc_strdup(p, s1); >+ p->s2 = talloc_strdup(p, s2); >+ p->s3 = talloc_strdup(p, s3); >+ >+ TALLOC_FREE(p); >+ return true; >+} >+ > static bool test_free_ref_null_context(void) > { > void *p1, *p2, *p3; >@@ -1591,6 +1625,8 @@ bool torture_local_talloc(struct torture_context *tctx) > setlinebuf(stdout); > > test_reset(); >+ ret &= test_pooled_object(); >+ test_reset(); > ret &= test_pool_nest(); > test_reset(); > ret &= test_ref1(); >-- >1.9.1 > > >From 6fd1949759e988ad6d322835ed12452ff009c570 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 14 Oct 2013 13:17:12 +0200 >Subject: [PATCH 30/47] talloc: Add a warning to talloc_reference() > documentation. > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Kai Blin <kai@samba.org> > >Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> >Autobuild-Date(master): Mon Oct 14 23:05:54 CEST 2013 on sn-devel-104 > >(cherry picked from commit 2343df451a13115eebfd46f9247ec2ae8c3a85c0) >--- > lib/talloc/talloc.h | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index 1b59390..5d29a8d 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -961,6 +961,10 @@ size_t talloc_reference_count(const void *ptr); > * @return The original pointer 'ptr', NULL if talloc ran out of > * memory in creating the reference. > * >+ * @warning You should try to avoid using this interface. It turns a beautiful >+ * talloc-tree into a graph. It is often really hard to debug if you >+ * screw something up by accident. >+ * > * Example: > * @code > * unsigned int *a, *b, *c; >@@ -1001,6 +1005,10 @@ void *_talloc_reference_loc(const void *context, const void *ptr, const char *lo > * this function will fail and will return -1. Likewise, if ptr is NULL, > * then the function will make no modifications and return -1. > * >+ * @warning You should try to avoid using this interface. It turns a beautiful >+ * talloc-tree into a graph. It is often really hard to debug if you >+ * screw something up by accident. >+ * > * Example: > * @code > * unsigned int *a, *b, *c; >-- >1.9.1 > > >From f5589a3adecce2c859050b56a2ad8ecf41f846df Mon Sep 17 00:00:00 2001 >From: Jelmer Vernooij <jelmer@samba.org> >Date: Wed, 27 Nov 2013 02:12:02 +0000 >Subject: [PATCH 31/47] Add a basic guide on pytalloc. > >Signed-off-by: Jelmer Vernooij <jelmer@samba.org> >Reviewed-By: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Jelmer Vernooij <jelmer@samba.org> >Autobuild-Date(master): Thu Nov 28 02:24:45 CET 2013 on sn-devel-104 > >(cherry picked from commit 91c1053413e1f309b2d5b215a423f37e3883aa91) >--- > lib/talloc/pytalloc.h | 3 + > lib/talloc/pytalloc_guide.txt | 153 ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 156 insertions(+) > create mode 100644 lib/talloc/pytalloc_guide.txt > >diff --git a/lib/talloc/pytalloc.h b/lib/talloc/pytalloc.h >index 2d2c57b..5c3876e 100644 >--- a/lib/talloc/pytalloc.h >+++ b/lib/talloc/pytalloc.h >@@ -29,7 +29,10 @@ typedef struct { > void *ptr; > } pytalloc_Object; > >+/* Return the PyTypeObject for pytalloc_Object. Returns a new reference. */ > PyTypeObject *pytalloc_GetObjectType(void); >+ >+/* Check whether a specific object is a talloc Object. */ > int pytalloc_Check(PyObject *); > > /* Retrieve the pointer for a pytalloc_object. Like talloc_get_type() >diff --git a/lib/talloc/pytalloc_guide.txt b/lib/talloc/pytalloc_guide.txt >new file mode 100644 >index 0000000..755a52b >--- /dev/null >+++ b/lib/talloc/pytalloc_guide.txt >@@ -0,0 +1,153 @@ >+Using talloc in Samba4 >+====================== >+ >+.. contents:: >+ >+Jelmer Vernooij >+August 2013 >+ >+The most current version of this document is available at >+ http://samba.org/ftp/unpacked/talloc/pytalloc_guide.txt >+ >+pytalloc is a small library that provides glue for wrapping >+talloc-allocated objects from C in Python objects. >+ >+What is pytalloc, and what is it not? >+------------------------------------- >+ >+pytalloc is merely a helper library - it provides a convenient base type object >+for objects that wrap talloc-maintained memory in C. It won't write your >+bindings for you but it will make it easier to write C bindings that involve >+talloc, and take away some of the boiler plate. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+pytalloc_Object >+ >+This is the new base class that all Python objects that wrap talloc pointers >+derive from. It is itself a subclass of the "Object" type that all objects >+in Python derive from. >+ >+Note that you will almost never create objects of the pytalloc_Object type >+itself, as they are just opaque pointers that can not be accessed from >+Python. A common pattern is other objects that subclass pytalloc_Object and >+rely on it for their memory management. >+ >+Each `pytalloc_Object` wraps two core of information - a talloc context >+and a pointer. The pointer is the actual data that is wrapped. The talloc >+context is used for memory management purposes only; when the wrapping Python object >+goes away, it unlinks the talloc context. The talloc context pointer and the ptr >+can (and often do) have the same value. >+ >+Each pytalloc_Object has a custom __repr__ implementation that >+describes that it is a talloc object and the location of the >+pointer it is wrapping. it also has a custom __cmp__/__eq__/__neq__ method that >+compares the pointers the object is wrapping rather than the objects >+themselves (since there can be multiple objects that wrap the same talloc >+pointer). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyTypeObject *pytalloc_GetObjectType(void) >+ >+Obtain a reference to the PyTypeObject for `pytalloc_Object`. The reference >+counter for the object will be incremented, so the caller will have to >+decrement it when it no longer needs it (using `Py_DECREF`). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- >+int pytalloc_Check(PyObject *) >+ >+Check whether a specific object is a talloc Object. Returns non-zero if it is >+a pytalloc_Object and zero otherwise. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+type *pytalloc_get_type(PyObject *py_obj, type) >+ >+Retrieve the pointer from a `pytalloc_Object` py_obj. type should be a >+C type, similar to a type passed to `talloc_get_type`. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+pytalloc_get_ptr(PyObject *py_obj) >+ >+Retrieve the pointer from a `pytalloc_Object` py_obj. There is no >+type checking - use `pytalloc_get_type` if possible. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+TALLOC_CTX *pytalloc_get_mem_ctx(PyObject *py_obj) >+ >+Retrieve the talloc context associated with a pytalloc_Object. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) >+ >+Create a new Python wrapping object for a talloc pointer and context, with >+py_type as associated Python sub type object. >+ >+This will *not* increment the reference counter for the talloc context, >+so the caller should make sure such an increment has happened. When the Python >+object goes away, it will unreference the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) >+ >+Create a new Python wrapping object for a talloc pointer and context, with >+py_type as associated Python sub type object. >+ >+This will *not* increment the reference counter for the talloc context, >+so the caller should make sure such an increment has happened. When the Python >+object goes away, it will unreference the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) >+ >+Create a new Python wrapping object for a talloc pointer and context, with >+py_type as associated Python sub type object. >+ >+This will increment the reference counter for the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_reference(PyTypeObject *py_type, void *talloc_ptr) >+ >+Create a new Python wrapping object for a talloc pointer, with >+py_type as associated Python sub type object. The pointer will also be used >+as the talloc context. >+ >+This will increment the reference counter for the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_new(type, PyTypeObject *typeobj) >+ >+Create a new, empty pytalloc_Object with the specified Python type object. type >+should be a C type, similar to talloc_new(). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_CObject_FromTallocPtr(void *); >+ >+Create a new pytalloc_Object for an abitrary talloc-maintained C pointer. This will >+use a generic VoidPtr Python type, which just provides an opaque object in >+Python. The caller is responsible for incrementing the talloc reference count before calling >+this function - it will dereference the talloc pointer when it is garbage collected. >+ >+Debug function for talloc in Python >+----------------------------------- >+ >+The "talloc" module in Python provides a couple of functions that can be used >+to debug issues with objects wrapped by pytalloc. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+report_full(obj?) >+ >+Print a full report on a specific object or on all allocated objects by Python. >+Same behaviour as the `talloc_report_full()` function that is provided by >+C talloc. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+enable_null_tracking() >+ >+This enables tracking of the NULL memory context without enabling leak >+reporting on exit. Useful for when you want to do your own leak >+reporting call via talloc_report_null_full(). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+pytalloc_total_blocks(obj?) >+ >+Return the talloc block count for all allocated objects or a specific object if >+specified. >-- >1.9.1 > > >From 57a06cd5d630979effcadc63a9e362153f3b3bd3 Mon Sep 17 00:00:00 2001 >From: Lukas Slebodnik <lslebodn@redhat.com> >Date: Fri, 4 Apr 2014 13:29:39 +0200 >Subject: [PATCH 32/47] talloc: Update flags in pytalloc-util pkgconfig file > >After exapnding, @LIB_RPATH@ will be -Wl,-rpatch,/usr/local/lib if rpath is >used on install. But "-Wl," will be passed to linker and should not be among >CFLAGS. Other pkgconfig files have @LIB_RPATH@ in the right place. > @see commit 735c1cd2da15167748e92ba6de48fdb5169db587 > >Signed-off-by: Lukas Slebodnik <lslebodn@redhat.com> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Fri Apr 4 23:50:25 CEST 2014 on sn-devel-104 > >(cherry picked from commit e1df75b5a965829db0c1f76673dcc824447b3ae7) >--- > lib/talloc/pytalloc-util.pc.in | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/talloc/pytalloc-util.pc.in b/lib/talloc/pytalloc-util.pc.in >index bc704b4..b7426bb 100644 >--- a/lib/talloc/pytalloc-util.pc.in >+++ b/lib/talloc/pytalloc-util.pc.in >@@ -6,6 +6,6 @@ includedir=@includedir@ > Name: pytalloc-util > Description: Utility functions for using talloc objects with Python > Version: @TALLOC_VERSION@ >-Libs: -L${libdir} -lpytalloc-util >-Cflags: @LIB_RPATH@ -I${includedir} >+Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util >+Cflags: -I${includedir} > URL: http://talloc.samba.org/ >-- >1.9.1 > > >From 9d9eb307165938a8c829ebd518434850cc0280a6 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 10 Jan 2014 10:45:22 +0100 >Subject: [PATCH 33/47] talloc: Tune talloc_vasprintf > >vsnprintf is significantly more expensive than memcpy. For the >common case where the string we print is less than a kilobyte, avoid >the second vsnprintf. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Thu May 15 12:49:14 CEST 2014 on sn-devel-104 > >(cherry picked from commit 593c8103af5a5ed6b3c915369fed5b90efb42c25) >--- > lib/talloc/talloc.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 1cb4d7d..2a5406e 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -2356,11 +2356,11 @@ _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) > int len; > char *ret; > va_list ap2; >- char c; >+ char buf[1024]; > > /* this call looks strange, but it makes it work on older solaris boxes */ > va_copy(ap2, ap); >- len = vsnprintf(&c, 1, fmt, ap2); >+ len = vsnprintf(buf, sizeof(buf), fmt, ap2); > va_end(ap2); > if (unlikely(len < 0)) { > return NULL; >@@ -2369,9 +2369,13 @@ _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) > ret = (char *)__talloc(t, len+1); > if (unlikely(!ret)) return NULL; > >- va_copy(ap2, ap); >- vsnprintf(ret, len+1, fmt, ap2); >- va_end(ap2); >+ if (len < sizeof(buf)) { >+ memcpy(ret, buf, len+1); >+ } else { >+ va_copy(ap2, ap); >+ vsnprintf(ret, len+1, fmt, ap2); >+ va_end(ap2); >+ } > > _talloc_set_name_const(ret, ret); > return ret; >-- >1.9.1 > > >From ccad4583abf54bc766e0dd52fd1187a1cb5c4488 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 20 Nov 2013 09:57:58 +0100 >Subject: [PATCH 34/47] talloc: inline more static functions > >We need the code to be as fast as possible. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 3aa35354724b88acc63f6b4439f7203d10db4e90) >--- > lib/talloc/talloc.c | 45 ++++++++++++++++++++++++++------------------- > 1 file changed, 26 insertions(+), 19 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 2a5406e..56ad4f7 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -235,12 +235,14 @@ struct talloc_memlimit { > size_t cur_size; > }; > >-static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); >-static void talloc_memlimit_grow(struct talloc_memlimit *limit, >+static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); >+static inline void talloc_memlimit_grow(struct talloc_memlimit *limit, > size_t size); >-static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >+static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit, > size_t size); >-static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); >+static inline void talloc_memlimit_update_on_free(struct talloc_chunk *tc); >+ >+static inline void _talloc_set_name_const(const void *ptr, const char *name); > > typedef int (*talloc_destructor_t)(void *); > >@@ -466,41 +468,41 @@ struct talloc_pool_hdr { > > #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) > >-static struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) >+static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) > { > return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE); > } > >-static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) >+static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) > { > return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE); > } > >-static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) >+static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) > { > struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); > return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize; > } > >-static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) >+static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) > { > return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; > } > > /* If tc is inside a pool, this gives the next neighbour. */ >-static void *tc_next_chunk(struct talloc_chunk *tc) >+static inline void *tc_next_chunk(struct talloc_chunk *tc) > { > return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); > } > >-static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >+static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) > { > struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); > return tc_next_chunk(tc); > } > > /* Mark the whole remaining pool as not accessable */ >-static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) >+static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > { > size_t flen = tc_pool_space_left(pool_hdr); > >@@ -517,8 +519,8 @@ static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > Allocate from a pool > */ > >-static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, >- size_t size, size_t prefix_len) >+static inline struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, >+ size_t size, size_t prefix_len) > { > struct talloc_pool_hdr *pool_hdr = NULL; > size_t space_left; >@@ -657,7 +659,7 @@ static inline void *__talloc(const void *context, size_t size) > * Create a talloc pool > */ > >-_PUBLIC_ void *talloc_pool(const void *context, size_t size) >+static inline void *_talloc_pool(const void *context, size_t size) > { > struct talloc_chunk *tc; > struct talloc_pool_hdr *pool_hdr; >@@ -684,6 +686,11 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > return result; > } > >+_PUBLIC_ void *talloc_pool(const void *context, size_t size) >+{ >+ return _talloc_pool(context, size); >+} >+ > /* > * Create a talloc pool correctly sized for a basic size plus > * a number of subobjects whose total size is given. Essentially >@@ -727,7 +734,7 @@ _PUBLIC_ void *_talloc_pooled_object(const void *ctx, > } > poolsize = tmp; > >- ret = talloc_pool(ctx, poolsize); >+ ret = _talloc_pool(ctx, poolsize); > if (ret == NULL) { > return NULL; > } >@@ -743,7 +750,7 @@ _PUBLIC_ void *_talloc_pooled_object(const void *ctx, > > pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size)); > >- talloc_set_name_const(ret, type_name); >+ _talloc_set_name_const(ret, type_name); > return ret; > > overflow: >@@ -1858,7 +1865,7 @@ enum talloc_mem_count_type { > TOTAL_MEM_LIMIT, > }; > >-static size_t _talloc_total_mem_internal(const void *ptr, >+static inline size_t _talloc_total_mem_internal(const void *ptr, > enum talloc_mem_count_type type, > struct talloc_memlimit *old_limit, > struct talloc_memlimit *new_limit) >@@ -2666,7 +2673,7 @@ _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr) > /* > return the total size of memory used by this context and all children > */ >-static size_t _talloc_total_limit_size(const void *ptr, >+static inline size_t _talloc_total_limit_size(const void *ptr, > struct talloc_memlimit *old_limit, > struct talloc_memlimit *new_limit) > { >@@ -2674,7 +2681,7 @@ static size_t _talloc_total_limit_size(const void *ptr, > old_limit, new_limit); > } > >-static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) >+static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > { > struct talloc_memlimit *l; > >-- >1.9.1 > > >From 900a8dc1b6ee7d6ca5e6a78a0048ffc1483b80bf Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 4 Dec 2013 23:22:04 +0100 >Subject: [PATCH 35/47] talloc: inline talloc_get_name() > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 014eecd0b2aead3a160af0d864feddd53c85b580) >--- > lib/talloc/talloc.c | 16 ++++++++++------ > 1 file changed, 10 insertions(+), 6 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 56ad4f7..3b8cb81 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1355,7 +1355,7 @@ _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, . > /* > return the name of a talloc ptr, or "UNNAMED" > */ >-_PUBLIC_ const char *talloc_get_name(const void *ptr) >+static inline const char *__talloc_get_name(const void *ptr) > { > struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); > if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { >@@ -1367,6 +1367,10 @@ _PUBLIC_ const char *talloc_get_name(const void *ptr) > return "UNNAMED"; > } > >+_PUBLIC_ const char *talloc_get_name(const void *ptr) >+{ >+ return __talloc_get_name(ptr); >+} > > /* > check if a pointer has the given name. If it does, return the pointer, >@@ -1376,7 +1380,7 @@ _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name) > { > const char *pname; > if (unlikely(ptr == NULL)) return NULL; >- pname = talloc_get_name(ptr); >+ pname = __talloc_get_name(ptr); > if (likely(pname == name || strcmp(pname, name) == 0)) { > return discard_const_p(void, ptr); > } >@@ -1410,7 +1414,7 @@ _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const c > return NULL; > } > >- pname = talloc_get_name(ptr); >+ pname = __talloc_get_name(ptr); > if (likely(pname == name || strcmp(pname, name) == 0)) { > return discard_const_p(void, ptr); > } >@@ -2028,7 +2032,7 @@ _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, > > static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) > { >- const char *name = talloc_get_name(ptr); >+ const char *name = __talloc_get_name(ptr); > struct talloc_chunk *tc; > FILE *f = (FILE *)_f; > >@@ -2628,9 +2632,9 @@ _PUBLIC_ void talloc_show_parents(const void *context, FILE *file) > } > > tc = talloc_chunk_from_ptr(context); >- fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); >+ fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context)); > while (tc) { >- fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); >+ fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc))); > while (tc && tc->prev) tc = tc->prev; > if (tc) { > tc = tc->parent; >-- >1.9.1 > > >From 2925b6a1c40a47f386304c84b9df408e5642bbe5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 4 Dec 2013 15:35:37 +0100 >Subject: [PATCH 36/47] talloc: avoid a function call in TALLOC_FREE() if > possible. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit b9fcfc6399eab750880ee0b9806311dd351a8ff6) >--- > lib/talloc/talloc.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index 5d29a8d..0d47d23 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -893,7 +893,7 @@ void *_talloc_pooled_object(const void *ctx, > * > * @param[in] ctx The chunk to be freed. > */ >-#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) >+#define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0) > > /* @} ******************************************************************/ > >-- >1.9.1 > > >From 476d00cb2306bcee00398b1990ac599ee7c5b26b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:36:13 +0100 >Subject: [PATCH 37/47] talloc: check for TALLOC_GET_TYPE_ABORT_NOOP > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit eb95fc8866dd1710b4cc2f4a4e1dc9867424def2) >--- > lib/talloc/talloc.h | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index 0d47d23..5ece54d 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -761,7 +761,11 @@ type *talloc_get_type(const void *ptr, #type); > */ > void *talloc_get_type_abort(const void *ptr, #type); > #else >+#ifdef TALLOC_GET_TYPE_ABORT_NOOP >+#define talloc_get_type_abort(ptr, type) (type *)(ptr) >+#else > #define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) >+#endif > void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); > #endif > >-- >1.9.1 > > >From ccfe15462922495e7baa550cc49d3d3a6ba18b44 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 20 Nov 2013 09:58:09 +0100 >Subject: [PATCH 38/47] talloc: fix compiler warning >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This avoids the following warning when using: > >CFLAGS="-O3 -g -fstrict-overflow -Wstrict-overflow=5" > >../talloc.c: In Funktion »talloc_is_parent«: >../talloc.c:2658:21: Warnung: assuming signed overflow does not occur when >changing X +- C1 cmp C2 to X cmp C1 +- C2 [-Wstrict-overflow] > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit de822b58476093dc43c27577d2f7074541113cc5) >--- > lib/talloc/talloc.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 3b8cb81..fa56ea5 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -2655,7 +2655,10 @@ static int _talloc_is_parent(const void *context, const void *ptr, int depth) > } > > tc = talloc_chunk_from_ptr(context); >- while (tc && depth > 0) { >+ while (tc) { >+ if (depth <= 0) { >+ return 0; >+ } > if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; > while (tc && tc->prev) tc = tc->prev; > if (tc) { >-- >1.9.1 > > >From ca5237dbd78440f4b1b5d36220eaf163a1fd82f9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 27 Feb 2014 09:28:02 +0100 >Subject: [PATCH 39/47] talloc/tests: avoid some unused variable warnings > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 8fbb81923ddf3449b4ad1fa1a562c9fab8c74103) >--- > lib/talloc/testsuite.c | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index 888d260..a878278 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -141,6 +141,7 @@ static bool test_ref1(void) > > CHECK_BLOCKS("ref1", p1, 5); > CHECK_BLOCKS("ref1", p2, 1); >+ CHECK_BLOCKS("ref1", ref, 1); > CHECK_BLOCKS("ref1", r1, 2); > > fprintf(stderr, "Freeing p2\n"); >@@ -249,6 +250,7 @@ static bool test_ref3(void) > CHECK_BLOCKS("ref3", p1, 2); > CHECK_BLOCKS("ref3", p2, 2); > CHECK_BLOCKS("ref3", r1, 1); >+ CHECK_BLOCKS("ref3", ref, 1); > > fprintf(stderr, "Freeing p1\n"); > talloc_free(p1); >@@ -291,6 +293,7 @@ static bool test_ref4(void) > > CHECK_BLOCKS("ref4", p1, 5); > CHECK_BLOCKS("ref4", p2, 1); >+ CHECK_BLOCKS("ref4", ref, 1); > CHECK_BLOCKS("ref4", r1, 2); > > fprintf(stderr, "Freeing r1\n"); >@@ -341,6 +344,7 @@ static bool test_unlink1(void) > > CHECK_BLOCKS("unlink", p1, 7); > CHECK_BLOCKS("unlink", p2, 1); >+ CHECK_BLOCKS("unlink", ref, 1); > CHECK_BLOCKS("unlink", r1, 2); > > fprintf(stderr, "Unreferencing r1\n"); >@@ -409,6 +413,8 @@ static bool test_misc(void) > name = talloc_set_name(p1, "my name is %s", "foo"); > torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", > "failed: wrong name after talloc_set_name(my name is foo)"); >+ torture_assert_str_equal("misc", talloc_get_name(p1), name, >+ "failed: wrong name after talloc_set_name(my name is foo)"); > CHECK_BLOCKS("misc", p1, 2); > CHECK_BLOCKS("misc", root, 3); > >@@ -617,6 +623,7 @@ static bool test_realloc_child(void) > el2 = talloc(el1->list, struct el2); > el2 = talloc(el1->list2, struct el2); > el2 = talloc(el1->list3, struct el2); >+ (void)el2; > > el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); > el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200); >@@ -829,6 +836,8 @@ static bool test_speed(void) > p1 = talloc_size(ctx, loop % 100); > p2 = talloc_strdup(p1, "foo bar"); > p3 = talloc_size(p1, 300); >+ (void)p2; >+ (void)p3; > talloc_free(p1); > } > count += 3 * loop; >@@ -848,6 +857,8 @@ static bool test_speed(void) > p1 = talloc_size(ctx, loop % 100); > p2 = talloc_strdup(p1, "foo bar"); > p3 = talloc_size(p1, 300); >+ (void)p2; >+ (void)p3; > talloc_free(p1); > } > count += 3 * loop; >@@ -1380,6 +1391,7 @@ static bool test_free_children(void) > root = talloc_new(NULL); > p1 = talloc_strdup(root, "foo1"); > p2 = talloc_strdup(p1, "foo2"); >+ (void)p2; > > talloc_set_name(p1, "%s", "testname"); > talloc_free_children(p1); >@@ -1404,6 +1416,7 @@ static bool test_free_children(void) > name2 = talloc_get_name(p1); > /* but this does */ > talloc_free_children(p1); >+ (void)name2; > torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, > "wrong name"); > CHECK_BLOCKS("name1", p1, 1); >-- >1.9.1 > > >From 617a5f1320cba411d41fa1664f67ba633e21f271 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 May 2014 14:53:49 +0200 >Subject: [PATCH 40/47] talloc: version 2.1.1 > >Changes: >- documentation updates >- a fix for pytalloc-util.pc >- performance improvements here and there >- fixed compiler warnings > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Fri May 16 19:51:26 CEST 2014 on sn-devel-104 > >(cherry picked from commit b8e5b68de3cff8d16e4be07fdc2e780d2c3c5750) >--- > lib/talloc/ABI/pytalloc-util-2.1.1.sigs | 6 ++++ > lib/talloc/ABI/talloc-2.1.1.sigs | 64 +++++++++++++++++++++++++++++++++ > lib/talloc/wscript | 2 +- > 3 files changed, 71 insertions(+), 1 deletion(-) > create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.1.sigs > create mode 100644 lib/talloc/ABI/talloc-2.1.1.sigs > >diff --git a/lib/talloc/ABI/pytalloc-util-2.1.1.sigs b/lib/talloc/ABI/pytalloc-util-2.1.1.sigs >new file mode 100644 >index 0000000..961c1a8 >--- /dev/null >+++ b/lib/talloc/ABI/pytalloc-util-2.1.1.sigs >@@ -0,0 +1,6 @@ >+pytalloc_CObject_FromTallocPtr: PyObject *(void *) >+pytalloc_Check: int (PyObject *) >+pytalloc_GetObjectType: PyTypeObject *(void) >+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >+pytalloc_steal: PyObject *(PyTypeObject *, void *) >+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >diff --git a/lib/talloc/ABI/talloc-2.1.1.sigs b/lib/talloc/ABI/talloc-2.1.1.sigs >new file mode 100644 >index 0000000..eae12cc >--- /dev/null >+++ b/lib/talloc/ABI/talloc-2.1.1.sigs >@@ -0,0 +1,64 @@ >+_talloc: void *(const void *, size_t) >+_talloc_array: void *(const void *, size_t, unsigned int, const char *) >+_talloc_free: int (void *, const char *) >+_talloc_get_type_abort: void *(const void *, const char *, const char *) >+_talloc_memdup: void *(const void *, const void *, size_t, const char *) >+_talloc_move: void *(const void *, const void *) >+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) >+_talloc_realloc: void *(const void *, void *, size_t, const char *) >+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) >+_talloc_reference_loc: void *(const void *, const void *, const char *) >+_talloc_set_destructor: void (const void *, int (*)(void *)) >+_talloc_steal_loc: void *(const void *, const void *, const char *) >+_talloc_zero: void *(const void *, size_t, const char *) >+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) >+talloc_asprintf: char *(const void *, const char *, ...) >+talloc_asprintf_append: char *(char *, const char *, ...) >+talloc_asprintf_append_buffer: char *(char *, const char *, ...) >+talloc_autofree_context: void *(void) >+talloc_check_name: void *(const void *, const char *) >+talloc_disable_null_tracking: void (void) >+talloc_enable_leak_report: void (void) >+talloc_enable_leak_report_full: void (void) >+talloc_enable_null_tracking: void (void) >+talloc_enable_null_tracking_no_autofree: void (void) >+talloc_find_parent_byname: void *(const void *, const char *) >+talloc_free_children: void (void *) >+talloc_get_name: const char *(const void *) >+talloc_get_size: size_t (const void *) >+talloc_increase_ref_count: int (const void *) >+talloc_init: void *(const char *, ...) >+talloc_is_parent: int (const void *, const void *) >+talloc_named: void *(const void *, size_t, const char *, ...) >+talloc_named_const: void *(const void *, size_t, const char *) >+talloc_parent: void *(const void *) >+talloc_parent_name: const char *(const void *) >+talloc_pool: void *(const void *, size_t) >+talloc_realloc_fn: void *(const void *, void *, size_t) >+talloc_reference_count: size_t (const void *) >+talloc_reparent: void *(const void *, const void *, const void *) >+talloc_report: void (const void *, FILE *) >+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) >+talloc_report_depth_file: void (const void *, int, int, FILE *) >+talloc_report_full: void (const void *, FILE *) >+talloc_set_abort_fn: void (void (*)(const char *)) >+talloc_set_log_fn: void (void (*)(const char *)) >+talloc_set_log_stderr: void (void) >+talloc_set_memlimit: int (const void *, size_t) >+talloc_set_name: const char *(const void *, const char *, ...) >+talloc_set_name_const: void (const void *, const char *) >+talloc_show_parents: void (const void *, FILE *) >+talloc_strdup: char *(const void *, const char *) >+talloc_strdup_append: char *(char *, const char *) >+talloc_strdup_append_buffer: char *(char *, const char *) >+talloc_strndup: char *(const void *, const char *, size_t) >+talloc_strndup_append: char *(char *, const char *, size_t) >+talloc_strndup_append_buffer: char *(char *, const char *, size_t) >+talloc_total_blocks: size_t (const void *) >+talloc_total_size: size_t (const void *) >+talloc_unlink: int (const void *, void *) >+talloc_vasprintf: char *(const void *, const char *, va_list) >+talloc_vasprintf_append: char *(char *, const char *, va_list) >+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) >+talloc_version_major: int (void) >+talloc_version_minor: int (void) >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index 1ca41f6..9df64d9 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'talloc' >-VERSION = '2.1.0' >+VERSION = '2.1.1' > > > blddir = 'bin' >-- >1.9.1 > > >From 57fb19ef597cdf6ddce9b3ed8c6e0c13bb6a0b51 Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Fri, 20 Jun 2014 18:04:44 +0200 >Subject: [PATCH 41/47] talloc:build: improve detection of srcdir > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit cc86b4107acebf56c7bb17f59dd358615aed57b7) >--- > lib/talloc/wscript | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index 9df64d9..986492c 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -12,7 +12,7 @@ import os, sys > # find the buildtools directory > srcdir = '.' > while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: >- srcdir = '../' + srcdir >+ srcdir = srcdir + '/..' > sys.path.insert(0, srcdir + '/buildtools/wafsamba') > > import sys >-- >1.9.1 > > >From 0b702df708b9496ab6408d1bb6a789f44c3bb82b Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 5 Mar 2015 12:48:47 -0800 >Subject: [PATCH 42/47] lib: talloc: Fix bug when calling a destructor. > >If the destructor itself calls talloc_set_destructor() >and returns -1, the new destructor set is overwritten >by talloc. > >Dectect that and leave the new destructor in place. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ira Cooper <ira@samba.org> >(cherry picked from commit 3289a5d84f73bf044e5767a6c47a3f7bf8357c08) >--- > lib/talloc/talloc.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index fa56ea5..1ccb039 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -991,7 +991,13 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > } > tc->destructor = (talloc_destructor_t)-1; > if (d(ptr) == -1) { >- tc->destructor = d; >+ /* >+ * Only replace the destructor pointer if >+ * calling the destructor didn't modify it. >+ */ >+ if (tc->destructor == (talloc_destructor_t)-1) { >+ tc->destructor = d; >+ } > return -1; > } > tc->destructor = NULL; >-- >1.9.1 > > >From 024dd8368da2b2e01754f9ca7339a24b47ba0dd7 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 3 Mar 2015 17:02:47 -0800 >Subject: [PATCH 43/47] lib: talloc: Allow destructors to reparent the object > they're called on. > >If a destructor returns failure (-1) when freeing a child, talloc >must then reparent the child. > >Firstly it tries the owner of any reference, next the parent of the >current object calling _talloc_free_children_internal(), and finally >the null context in the last resort. > >If a destructor reparented its own object, which can be a very >desirable thing to do (a destructor can make a decision it isn't >time to die yet, and as the parent may be going away it might >want to move itself to longer-term storage) then this new parent >gets overwritten by the existing reparenting logic. > >This patch checks when freeing a child if it already reparented >itself, and if it did doesn't then overwrite the new parent. > >Makes destructors more flexible. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Ira Cooper <ira@samba.org> >(cherry picked from commit cc4e5481ea060db7f6d8a83619d859b2e002eb90) >--- > lib/talloc/talloc.c | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 1ccb039..46f10f4 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1470,6 +1470,13 @@ static inline void _talloc_free_children_internal(struct talloc_chunk *tc, > if (p) new_parent = TC_PTR_FROM_CHUNK(p); > } > if (unlikely(_talloc_free_internal(child, location) == -1)) { >+ if (talloc_parent_chunk(child) != tc) { >+ /* >+ * Destructor already reparented this child. >+ * No further reparenting needed. >+ */ >+ return; >+ } > if (new_parent == null_context) { > struct talloc_chunk *p = talloc_parent_chunk(ptr); > if (p) new_parent = TC_PTR_FROM_CHUNK(p); >-- >1.9.1 > > >From 450adcc9a8c539615204d931e5fe52fdf4110091 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 3 Mar 2015 17:12:32 -0800 >Subject: [PATCH 44/47] lib: talloc: Test suite for the new destructor reparent > logic. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Ira Cooper <ira@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Sun Mar 8 20:52:43 CET 2015 on sn-devel-104 > >(cherry picked from commit 6b0cecee1b864a0589836caf9f5f2892f8cb6926) >--- > lib/talloc/testsuite.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 82 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index a878278..eb3e13d 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -981,6 +981,84 @@ static bool test_free_parent_deny_child(void) > return true; > } > >+struct new_parent { >+ void *new_parent; >+ char val[20]; >+}; >+ >+static int reparenting_destructor(struct new_parent *np) >+{ >+ talloc_set_destructor(np, NULL); >+ (void)talloc_move(np->new_parent, &np); >+ return -1; >+} >+ >+static bool test_free_parent_reparent_child(void) >+{ >+ void *top = talloc_new(NULL); >+ char *level1; >+ char *alternate_level1; >+ char *level2; >+ struct new_parent *level3; >+ >+ printf("test: free_parent_reparent_child\n# " >+ "TALLOC FREE PARENT REPARENT CHILD\n"); >+ >+ level1 = talloc_strdup(top, "level1"); >+ alternate_level1 = talloc_strdup(top, "alternate_level1"); >+ level2 = talloc_strdup(level1, "level2"); >+ level3 = talloc(level2, struct new_parent); >+ level3->new_parent = alternate_level1; >+ memset(level3->val, 'x', sizeof(level3->val)); >+ >+ talloc_set_destructor(level3, reparenting_destructor); >+ talloc_free(level1); >+ >+ CHECK_PARENT("free_parent_reparent_child", >+ level3, alternate_level1); >+ >+ talloc_free(top); >+ >+ printf("success: free_parent_reparent_child\n"); >+ return true; >+} >+ >+static bool test_free_parent_reparent_child_in_pool(void) >+{ >+ void *top = talloc_new(NULL); >+ char *level1; >+ char *alternate_level1; >+ char *level2; >+ void *pool; >+ struct new_parent *level3; >+ >+ printf("test: free_parent_reparent_child_in_pool\n# " >+ "TALLOC FREE PARENT REPARENT CHILD IN POOL\n"); >+ >+ pool = talloc_pool(top, 1024); >+ level1 = talloc_strdup(pool, "level1"); >+ alternate_level1 = talloc_strdup(top, "alternate_level1"); >+ level2 = talloc_strdup(level1, "level2"); >+ level3 = talloc(level2, struct new_parent); >+ level3->new_parent = alternate_level1; >+ memset(level3->val, 'x', sizeof(level3->val)); >+ >+ talloc_set_destructor(level3, reparenting_destructor); >+ talloc_free(level1); >+ talloc_set_destructor(level3, NULL); >+ >+ CHECK_PARENT("free_parent_reparent_child_in_pool", >+ level3, alternate_level1); >+ >+ /* Even freeing alternate_level1 should leave pool alone. */ >+ talloc_free(alternate_level1); >+ talloc_free(top); >+ >+ printf("success: free_parent_reparent_child_in_pool\n"); >+ return true; >+} >+ >+ > static bool test_talloc_ptrtype(void) > { > void *top = talloc_new(NULL); >@@ -1674,6 +1752,10 @@ bool torture_local_talloc(struct torture_context *tctx) > test_reset(); > ret &= test_free_parent_deny_child(); > test_reset(); >+ ret &= test_free_parent_reparent_child(); >+ test_reset(); >+ ret &= test_free_parent_reparent_child_in_pool(); >+ test_reset(); > ret &= test_talloc_ptrtype(); > test_reset(); > ret &= test_talloc_free_in_destructor(); >-- >1.9.1 > > >From c2e19b274bde08392c2326ce89946ab61837a6d5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 27 Jan 2015 13:07:34 +0100 >Subject: [PATCH 45/47] talloc: fix _talloc_total_limit_size prototype > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 3929abfc6b5a3ae8a27da57d4dbee9524e3585e3) >--- > lib/talloc/talloc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 46f10f4..c10fd53 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1064,7 +1064,7 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > return 0; > } > >-static size_t _talloc_total_limit_size(const void *ptr, >+static inline size_t _talloc_total_limit_size(const void *ptr, > struct talloc_memlimit *old_limit, > struct talloc_memlimit *new_limit); > >-- >1.9.1 > > >From 77e8f20e41df54fcbaa7ad56d59d932299052e9f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 9 Mar 2015 09:07:24 +0100 >Subject: [PATCH 46/47] talloc: version 2.1.2 >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Changes: >- Allow destructors to reparent the object >- Allow destructors to remove itself >- Build improvements > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Günther Deschner <gd@samba.org> >(cherry picked from commit 7bef5e4f0e5ff4a4187f3d63e51a1725ff32b771) >--- > lib/talloc/ABI/pytalloc-util-2.1.2.sigs | 6 ++++ > lib/talloc/ABI/talloc-2.1.2.sigs | 64 +++++++++++++++++++++++++++++++++ > lib/talloc/wscript | 2 +- > 3 files changed, 71 insertions(+), 1 deletion(-) > create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.2.sigs > create mode 100644 lib/talloc/ABI/talloc-2.1.2.sigs > >diff --git a/lib/talloc/ABI/pytalloc-util-2.1.2.sigs b/lib/talloc/ABI/pytalloc-util-2.1.2.sigs >new file mode 100644 >index 0000000..961c1a8 >--- /dev/null >+++ b/lib/talloc/ABI/pytalloc-util-2.1.2.sigs >@@ -0,0 +1,6 @@ >+pytalloc_CObject_FromTallocPtr: PyObject *(void *) >+pytalloc_Check: int (PyObject *) >+pytalloc_GetObjectType: PyTypeObject *(void) >+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >+pytalloc_steal: PyObject *(PyTypeObject *, void *) >+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >diff --git a/lib/talloc/ABI/talloc-2.1.2.sigs b/lib/talloc/ABI/talloc-2.1.2.sigs >new file mode 100644 >index 0000000..eae12cc >--- /dev/null >+++ b/lib/talloc/ABI/talloc-2.1.2.sigs >@@ -0,0 +1,64 @@ >+_talloc: void *(const void *, size_t) >+_talloc_array: void *(const void *, size_t, unsigned int, const char *) >+_talloc_free: int (void *, const char *) >+_talloc_get_type_abort: void *(const void *, const char *, const char *) >+_talloc_memdup: void *(const void *, const void *, size_t, const char *) >+_talloc_move: void *(const void *, const void *) >+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) >+_talloc_realloc: void *(const void *, void *, size_t, const char *) >+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) >+_talloc_reference_loc: void *(const void *, const void *, const char *) >+_talloc_set_destructor: void (const void *, int (*)(void *)) >+_talloc_steal_loc: void *(const void *, const void *, const char *) >+_talloc_zero: void *(const void *, size_t, const char *) >+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) >+talloc_asprintf: char *(const void *, const char *, ...) >+talloc_asprintf_append: char *(char *, const char *, ...) >+talloc_asprintf_append_buffer: char *(char *, const char *, ...) >+talloc_autofree_context: void *(void) >+talloc_check_name: void *(const void *, const char *) >+talloc_disable_null_tracking: void (void) >+talloc_enable_leak_report: void (void) >+talloc_enable_leak_report_full: void (void) >+talloc_enable_null_tracking: void (void) >+talloc_enable_null_tracking_no_autofree: void (void) >+talloc_find_parent_byname: void *(const void *, const char *) >+talloc_free_children: void (void *) >+talloc_get_name: const char *(const void *) >+talloc_get_size: size_t (const void *) >+talloc_increase_ref_count: int (const void *) >+talloc_init: void *(const char *, ...) >+talloc_is_parent: int (const void *, const void *) >+talloc_named: void *(const void *, size_t, const char *, ...) >+talloc_named_const: void *(const void *, size_t, const char *) >+talloc_parent: void *(const void *) >+talloc_parent_name: const char *(const void *) >+talloc_pool: void *(const void *, size_t) >+talloc_realloc_fn: void *(const void *, void *, size_t) >+talloc_reference_count: size_t (const void *) >+talloc_reparent: void *(const void *, const void *, const void *) >+talloc_report: void (const void *, FILE *) >+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) >+talloc_report_depth_file: void (const void *, int, int, FILE *) >+talloc_report_full: void (const void *, FILE *) >+talloc_set_abort_fn: void (void (*)(const char *)) >+talloc_set_log_fn: void (void (*)(const char *)) >+talloc_set_log_stderr: void (void) >+talloc_set_memlimit: int (const void *, size_t) >+talloc_set_name: const char *(const void *, const char *, ...) >+talloc_set_name_const: void (const void *, const char *) >+talloc_show_parents: void (const void *, FILE *) >+talloc_strdup: char *(const void *, const char *) >+talloc_strdup_append: char *(char *, const char *) >+talloc_strdup_append_buffer: char *(char *, const char *) >+talloc_strndup: char *(const void *, const char *, size_t) >+talloc_strndup_append: char *(char *, const char *, size_t) >+talloc_strndup_append_buffer: char *(char *, const char *, size_t) >+talloc_total_blocks: size_t (const void *) >+talloc_total_size: size_t (const void *) >+talloc_unlink: int (const void *, void *) >+talloc_vasprintf: char *(const void *, const char *, va_list) >+talloc_vasprintf_append: char *(char *, const char *, va_list) >+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) >+talloc_version_major: int (void) >+talloc_version_minor: int (void) >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index 986492c..97c52c3 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'talloc' >-VERSION = '2.1.1' >+VERSION = '2.1.2' > > > blddir = 'bin' >-- >1.9.1 > > >From aa72bd59060f42a979cc9c739484105e055fa74e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 10 Mar 2015 10:51:11 +0100 >Subject: [PATCH 47/47] s3:configure: require external talloc >= 2.1.2 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/configure.in | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/configure.in b/source3/configure.in >index f4403e1..d71d2d6 100644 >--- a/source3/configure.in >+++ b/source3/configure.in >@@ -1837,7 +1837,7 @@ AC_ARG_ENABLE(external_libtalloc, > > if test "x$enable_external_libtalloc" != xno > then >- PKG_CHECK_MODULES(LIBTALLOC, talloc >= 2.0.1, >+ PKG_CHECK_MODULES(LIBTALLOC, talloc >= 2.1.2, > [ enable_external_libtalloc=yes ], > [ if test x$enable_external_libtalloc = xyes; then > AC_MSG_ERROR([Unable to find libtalloc]) >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jra
:
review+
Actions:
View
Attachments on
bug 11144
:
10831
|
10837
| 10838