diff --git a/include/asterisk/stringfields.h b/include/asterisk/stringfields.h
index 5631682b2abfdec4b882f2529e0fdb708603f1c9..22e066d21a9ce34dba0d32dcb43f7e5d481302e8 100644
--- a/include/asterisk/stringfields.h
+++ b/include/asterisk/stringfields.h
@@ -107,31 +107,40 @@ extern const char *__ast_string_field_empty;
 
 /*!
   \internal
-  \brief Structure used to manage the storage for a field pool
+  \brief Structure used to hold a pool of space for string fields
 */
 struct ast_string_field_pool {
-	char *base;	/*!< the address of the pool's base in memory */
-	size_t size;	/*!< the total size of the pool */
-	size_t space;	/*!< the space available in the pool */
-	size_t used;	/*!< the space used in the pool */
+	struct ast_string_field_pool *prev;	/*!< pointer to the previous pool, if any */
+	char base[0];				/*!< storage space for the fields */
 };
 
 /*!
   \internal
-  \brief Initialize a field pool and fields
-  \param pool Pointer to the pool structure
+  \brief Structure used to manage the storage for a set of string fields
+*/
+struct ast_string_field_mgr {
+	struct ast_string_field_pool *pool;	/*!< the address of the pool's structure */
+	size_t size;				/*!< the total size of the current pool */
+	size_t space;				/*!< the space available in the current pool */
+	size_t used;				/*!< the space used in the current pool */
+};
+
+/*!
+  \internal
+  \brief Initialize a field pool manager and fields
+  \param mgr Pointer to the pool manager structure
   \param size Amount of storage to allocate
   \param fields Pointer to the first entry of the field array
   \param num_fields Number of fields in the array
   \return 0 on failure, non-zero on success
 */
-int __ast_string_field_init(struct ast_string_field_pool *pool, size_t size,
+int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
 			    ast_string_field *fields, int num_fields);
 
 /*!
   \internal
-  \brief Allocate space for field in the pool
-  \param pool Pointer to the pool structure
+  \brief Allocate space for a field
+  \param mgr Pointer to the pool manager structure
   \param needed Amount of space needed for this field
   \param fields Pointer to the first entry of the field array
   \param num_fields Number of fields in the array
@@ -139,24 +148,22 @@ int __ast_string_field_init(struct ast_string_field_pool *pool, size_t size,
 
   This function will allocate the requested amount of space from
   the field pool. If the requested amount of space is not available,
-  the pool will be expanded until enough space becomes available,
-  and the existing fields stored there will be updated to point
-  into the new pool.
+  an additional pool will be allocated.
 */
-ast_string_field __ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t needed,
+ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
 						ast_string_field *fields, int num_fields);
 
 /*!
   \internal
   \brief Set a field to a complex (built) value
-  \param pool Pointer to the pool structure
+  \param mgr Pointer to the pool manager structure
   \param fields Pointer to the first entry of the field array
   \param num_fields Number of fields in the array
   \param index Index position of the field within the structure
   \param format printf-style format string
   \return nothing
 */
-void __ast_string_field_index_build(struct ast_string_field_pool *pool,
+void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
 				    ast_string_field *fields, int num_fields,
 				    int index, const char *format, ...);
 
@@ -179,7 +186,7 @@ void __ast_string_field_index_build(struct ast_string_field_pool *pool,
 	ast_string_field __begin_field[0]; \
 	field_list \
 	ast_string_field __end_field[0]; \
-	struct ast_string_field_pool __field_pool;
+	struct ast_string_field_mgr __field_mgr;
 
 /*!
   \brief Get the number of string fields in a structure
@@ -205,7 +212,7 @@ void __ast_string_field_index_build(struct ast_string_field_pool *pool,
   \return 0 on failure, non-zero on success
 */
 #define ast_string_field_init(x) \
-	__ast_string_field_init(&x->__field_pool, AST_STRING_FIELD_DEFAULT_POOL, &x->__begin_field[0], ast_string_field_count(x))
+	__ast_string_field_init(&x->__field_mgr, AST_STRING_FIELD_DEFAULT_POOL, &x->__begin_field[0], ast_string_field_count(x))
 
 /*!
   \brief Set a field to a simple string value
@@ -215,7 +222,7 @@ void __ast_string_field_index_build(struct ast_string_field_pool *pool,
   \return nothing
 */
 #define ast_string_field_index_set(x, index, data) do { \
-	if ((x->__begin_field[index] = __ast_string_field_alloc_space(&x->__field_pool, strlen(data) + 1, &x->__begin_field[0], ast_string_field_count(x)))) \
+	if ((x->__begin_field[index] = __ast_string_field_alloc_space(&x->__field_mgr, strlen(data) + 1, &x->__begin_field[0], ast_string_field_count(x)))) \
 		strcpy((char *) x->__begin_field[index], data); \
 	} while (0)
 
@@ -238,7 +245,7 @@ void __ast_string_field_index_build(struct ast_string_field_pool *pool,
   \return nothing
 */
 #define ast_string_field_index_build(x, index, fmt, args...) \
-	__ast_string_field_index_build(&x->__field_pool, &x->__begin_field[0], ast_string_field_count(x), index, fmt, args)
+	__ast_string_field_index_build(&x->__field_mgr, &x->__begin_field[0], ast_string_field_count(x), index, fmt, args)
 
 /*!
   \brief Set a field to a complex (built) value
@@ -289,9 +296,13 @@ void __ast_string_field_index_build(struct ast_string_field_pool *pool,
 */
 #define ast_string_field_free_all(x) do { \
 	int index; \
+	struct ast_string_field_pool *this, *prev; \
 	for (index = 0; index < ast_string_field_count(x); index ++) \
 		ast_string_field_index_free(x, index); \
-	free(x->__field_pool.base); \
+	for (this = x->__field_mgr.pool; this; this = prev) { \
+		prev = this->prev; \
+		free(this); \
+	} \
 	} while(0)
 
 #endif /* _ASTERISK_STRINGFIELDS_H */
diff --git a/utils.c b/utils.c
index ef0246252a4aabc2eea6efd8e8528de827339340..977f0cdd04623587e3f5b6d3ea66d7bcf7e65598 100644
--- a/utils.c
+++ b/utils.c
@@ -944,70 +944,86 @@ void ast_join(char *s, size_t len, char * const w[])
 
 const char const *__ast_string_field_empty = "";
 
-int __ast_string_field_init(struct ast_string_field_pool *pool, size_t size,
+static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
+{
+	struct ast_string_field_pool *pool;
+
+	if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
+		return -1;
+	
+	pool->prev = mgr->pool;
+	mgr->pool = pool;
+	mgr->size = size;
+	mgr->space = size;
+	mgr->used = 0;
+
+	return 0;
+}
+
+int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
 			    ast_string_field *fields, int num_fields)
 {
 	int index;
 
-	pool->base = calloc(1, size);
-	if (pool->base) {
-		pool->size = size;
-		pool->space = size;
-		for (index = 0; index < num_fields; index++)
-			fields[index] = __ast_string_field_empty;
-	}
-	return pool->base ? 0 : -1;
+	if (add_string_pool(mgr, size))
+		return -1;
+
+	for (index = 0; index < num_fields; index++)
+		fields[index] = __ast_string_field_empty;
+
+	return 0;
 }
 
-ast_string_field __ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t needed,
+ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
 						ast_string_field *fields, int num_fields)
 {
 	char *result = NULL;
 
-	if (__builtin_expect(needed > pool->space, 0)) {
-		int index;
-		char *new_base;
-		size_t new_size = pool->size * 2;
+	if (__builtin_expect(needed > mgr->space, 0)) {
+		size_t new_size = mgr->size * 2;
 
-		while (new_size < (pool->used + needed))
+		while (new_size < needed)
 			new_size *= 2;
 
-		if (!(new_base = realloc(pool->base, new_size)))
+		if (add_string_pool(mgr, new_size))
 			return NULL;
-
-		for (index = 0; index < num_fields; index++) {
-			if (fields[index] != __ast_string_field_empty)
-				fields[index] = new_base + (fields[index] - pool->base);
-		}
-
-		pool->base = new_base;
-		pool->space += new_size - pool->size;
-		pool->size = new_size;
 	}
 
-	result = pool->base + pool->used;
-	pool->used += needed;
-	pool->space -= needed;
+	result = mgr->pool->base + mgr->used;
+	mgr->used += needed;
+	mgr->space -= needed;
 	return result;
 }
 
-void __ast_string_field_index_build(struct ast_string_field_pool *pool,
+void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
 				    ast_string_field *fields, int num_fields,
 				    int index, const char *format, ...)
 {
-	char s;
 	size_t needed;
 	va_list ap1, ap2;
 
 	va_start(ap1, format);
 	va_copy(ap2, ap1);
 
-	needed = vsnprintf(&s, 1, format, ap1) + 1;
+	needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
 
 	va_end(ap1);
 
-	if ((fields[index] = __ast_string_field_alloc_space(pool, needed, fields, num_fields)))
-		vsprintf((char *) fields[index], format, ap2);
+	if (needed > mgr->space) {
+		size_t new_size = mgr->size * 2;
+
+		while (new_size < needed)
+			new_size *= 2;
+
+		if (add_string_pool(mgr, new_size))
+			return;
+
+		vsprintf(mgr->pool->base + mgr->used, format, ap2);
+	}
+
+	fields[index] = mgr->pool->base + mgr->used;
+	mgr->used += needed;
+	mgr->space -= needed;
 
 	va_end(ap2);
 }