From d7ccdb33c2e84bab25bf0898866104f8a85b4217 Mon Sep 17 00:00:00 2001 From: Kinglong Mee Date: Wed, 30 Aug 2017 17:54:09 +0800 Subject: gfapi: adds a glfs_mem_header for exported memory glfs_free releases different types of data depends on memory type. Drop the depends of memory type of memory accounting, new macro GLFS_CALLOC/GLFS_MALLOC/GLFS_REALLOC/GLFS_FREE are added to support assign release function dynamically, it adds a separate memory header named glfs_mem_header for gfapi. Updates: #312 Change-Id: Ie608e5227cbaa05d3f4681a515e83a50d5b17c3f Signed-off-by: Kinglong Mee Reviewed-on: https://review.gluster.org/18092 Smoke: Gluster Build System Reviewed-by: Niels de Vos Tested-by: Niels de Vos Reviewed-by: Jeff Darcy CentOS-regression: Gluster Build System --- api/src/glfs-fops.c | 23 +++++++--- api/src/glfs-handleops.c | 15 +++++-- api/src/glfs-internal.h | 108 +++++++++++++++++++++++++++++++++++++++++++++++ api/src/glfs.c | 29 +------------ 4 files changed, 137 insertions(+), 38 deletions(-) (limited to 'api/src') diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index c8ddeea196e..e6ed07a68a9 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -4104,8 +4104,8 @@ glfs_realpath_common (struct glfs *fs, const char *path, char *resolved_path, "glfs_realpath()"); } } else { - retpath = allocpath = GF_CALLOC (1, PATH_MAX + 1, - glfs_mt_realpath_t); + retpath = allocpath = GLFS_CALLOC (1, PATH_MAX + 1, NULL, + glfs_mt_realpath_t); } if (!retpath) { @@ -4140,7 +4140,7 @@ out: if (warn_deprecated && allocpath) free (allocpath); else if (allocpath) - GF_FREE (allocpath); + GLFS_FREE (allocpath); retpath = NULL; } @@ -4619,6 +4619,14 @@ invalid_fs: return ret; } +static void glfs_release_xreaddirp_stat (void *ptr) +{ + struct glfs_xreaddirp_stat *to_free = ptr; + + if (to_free->object) + glfs_h_close (to_free->object); +} + /* * Given glfd of a directory, this function does readdirp and returns * xstat along with dirents. @@ -4652,8 +4660,9 @@ pub_glfs_xreaddirplus_r (struct glfs_fd *glfd, uint32_t flags, if (!buf) goto out; - xstat = GF_CALLOC(1, sizeof(struct glfs_xreaddirp_stat), - glfs_mt_xreaddirp_stat_t); + xstat = GLFS_CALLOC(1, sizeof(struct glfs_xreaddirp_stat), + glfs_release_xreaddirp_stat, + glfs_mt_xreaddirp_stat_t); if (!xstat) goto out; @@ -4677,7 +4686,7 @@ pub_glfs_xreaddirplus_r (struct glfs_fd *glfd, uint32_t flags, *xstat_p = NULL; /* free xstat as applications shall not be using it */ - glfs_free (xstat); + GLFS_FREE (xstat); goto out; } @@ -4728,7 +4737,7 @@ out: strerror(errno)); if (xstat) - glfs_free (xstat); + GLFS_FREE (xstat); } __GLFS_EXIT_FS; diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index 4180f5cf777..65b2b6a467c 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -1987,6 +1987,14 @@ out: return ret; } +static void glfs_release_upcall (void *ptr) +{ + struct glfs_upcall *to_free = ptr; + + if (to_free->event) + to_free->free_event (to_free->event); +} + /* * This API is used to poll for upcall events stored in the upcall list. * Current users of this API is NFS-Ganesha. Incase of any event received, it @@ -2068,8 +2076,9 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct glfs_upcall **up_arg) if (upcall_data) { switch (upcall_data->event_type) { case GF_UPCALL_CACHE_INVALIDATION: - *up_arg = GF_CALLOC (1, sizeof (struct gf_upcall), - glfs_mt_upcall_entry_t); + *up_arg = GLFS_CALLOC (1, sizeof (struct gf_upcall), + glfs_release_upcall, + glfs_mt_upcall_entry_t); if (!*up_arg) { errno = ENOMEM; break; /* goto free u_list */ @@ -2088,7 +2097,7 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct glfs_upcall **up_arg) if ((*up_arg)->reason == GLFS_UPCALL_EVENT_NULL) errno = ENOENT; - GF_FREE (*up_arg); + GLFS_FREE (*up_arg); *up_arg = NULL; } break; diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 180981830d7..be2d60a38e0 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -258,6 +258,114 @@ struct glfs_xreaddirp_stat { #define GF_MEMPOOL_COUNT_OF_LRU_BUF_T 256 +typedef void (glfs_mem_release_t) (void *ptr); + +struct glfs_mem_header { + uint32_t magic; + size_t nmemb; + size_t size; + glfs_mem_release_t *release; +}; + +#define GLFS_MEM_HEADER_SIZE (sizeof (struct glfs_mem_header)) +#define GLFS_MEM_HEADER_MAGIC 0x20170830 + +static inline void * +__glfs_calloc (size_t nmemb, size_t size, glfs_mem_release_t release, + uint32_t type, const char *typestr) +{ + struct glfs_mem_header *header = NULL; + + header = __gf_calloc(nmemb, (size + GLFS_MEM_HEADER_SIZE), + type, typestr); + if (!header) + return NULL; + + header->magic = GLFS_MEM_HEADER_MAGIC; + header->nmemb = nmemb; + header->size = size; + header->release = release; + + return header + 1; +} + +static inline void * +__glfs_malloc (size_t size, glfs_mem_release_t release, + uint32_t type, const char *typestr) +{ + struct glfs_mem_header *header = NULL; + + header = __gf_malloc((size + GLFS_MEM_HEADER_SIZE), type, typestr); + if (!header) + return NULL; + + header->magic = GLFS_MEM_HEADER_MAGIC; + header->nmemb = 1; + header->size = size; + header->release = release; + + return header + 1; +} + +static inline void * +__glfs_realloc (void *ptr, size_t size) +{ + struct glfs_mem_header *old_header = NULL; + struct glfs_mem_header *new_header = NULL; + struct glfs_mem_header tmp_header; + void *new_ptr = NULL; + + GF_ASSERT (NULL != ptr); + + old_header = (struct glfs_mem_header *) (ptr - GLFS_MEM_HEADER_SIZE); + GF_ASSERT (old_header->magic == GLFS_MEM_HEADER_MAGIC); + tmp_header = *old_header; + + new_ptr = __gf_realloc (old_header, (size + GLFS_MEM_HEADER_SIZE)); + if (!new_ptr) + return NULL; + + new_header = (struct glfs_mem_header *) new_ptr; + *new_header = tmp_header; + new_header->size = size; + + return new_header + 1; +} + +static inline void +__glfs_free (void *free_ptr) +{ + struct glfs_mem_header *header = NULL; + void *release_ptr = NULL; + int i = 0; + + if (!free_ptr) + return; + + header = (struct glfs_mem_header *) (free_ptr - GLFS_MEM_HEADER_SIZE); + GF_ASSERT (header->magic == GLFS_MEM_HEADER_MAGIC); + + if (header->release) { + release_ptr = free_ptr; + for (i = 0; i < header->nmemb; i++) { + header->release (release_ptr); + release_ptr += header->size; + } + } + + __gf_free (header); +} + +#define GLFS_CALLOC(nmemb, size, release, type) \ + __glfs_calloc (nmemb, size, release, type, #type) + +#define GLFS_MALLOC(size, release, type) \ + __glfs_malloc (size, release, type, #type) + +#define GLFS_REALLOC(ptr, size) __glfs_realloc(ptr, size) + +#define GLFS_FREE(free_ptr) __glfs_free(free_ptr) + int glfs_mgmt_init (struct glfs *fs); void glfs_init_done (struct glfs *fs, int ret) GFAPI_PRIVATE(glfs_init_done, 3.4.0); diff --git a/api/src/glfs.c b/api/src/glfs.c index 3313fab0372..db3ea10bb84 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -1390,34 +1390,7 @@ GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_ipc, 3.12.0); void pub_glfs_free (void *ptr) { - int mem_type = 0; - - mem_type = gf_get_mem_type (ptr); - - switch (mem_type) { - case glfs_mt_upcall_entry_t: - { - struct glfs_upcall *to_free = ptr; - - if (to_free->event) - to_free->free_event (to_free->event); - - GF_FREE (ptr); - break; - } - case glfs_mt_xreaddirp_stat_t: - { - struct glfs_xreaddirp_stat *to_free = ptr; - - if (to_free->object) - glfs_h_close (to_free->object); - - GF_FREE (ptr); - break; - } - default: - GF_FREE (ptr); - } + GLFS_FREE (ptr); } GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_free, 3.7.16); -- cgit