Bug Summary

File:libglusterfs/src/mem-pool.c
Location:line 248, column 14
Description:Dereference of null pointer

Annotated Source Code

1/*
2 Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10
11#include "mem-pool.h"
12#include "logging.h"
13#include "xlator.h"
14#include <stdlib.h>
15#include <stdarg.h>
16
17#define GF_MEM_POOL_LIST_BOUNDARY(sizeof(struct list_head)) (sizeof(struct list_head))
18#define GF_MEM_POOL_PTR(sizeof(struct mem_pool*)) (sizeof(struct mem_pool*))
19#define GF_MEM_POOL_PAD_BOUNDARY((sizeof(struct list_head)) + (sizeof(struct mem_pool*)) + sizeof
(int))
(GF_MEM_POOL_LIST_BOUNDARY(sizeof(struct list_head)) + GF_MEM_POOL_PTR(sizeof(struct mem_pool*)) + sizeof(int))
20#define mem_pool_chunkhead2ptr(head)((head) + ((sizeof(struct list_head)) + (sizeof(struct mem_pool
*)) + sizeof(int)))
((head) + GF_MEM_POOL_PAD_BOUNDARY((sizeof(struct list_head)) + (sizeof(struct mem_pool*)) + sizeof
(int))
)
21#define mem_pool_ptr2chunkhead(ptr)((ptr) - ((sizeof(struct list_head)) + (sizeof(struct mem_pool
*)) + sizeof(int)))
((ptr) - GF_MEM_POOL_PAD_BOUNDARY((sizeof(struct list_head)) + (sizeof(struct mem_pool*)) + sizeof
(int))
)
22#define is_mem_chunk_in_use(ptr)(*ptr == 1) (*ptr == 1)
23#define mem_pool_from_ptr(ptr)((ptr) + (sizeof(struct list_head))) ((ptr) + GF_MEM_POOL_LIST_BOUNDARY(sizeof(struct list_head)))
24
25#define GF_MEM_HEADER_SIZE(4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8) (4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8)
26#define GF_MEM_TRAILER_SIZE8 8
27
28#define GF_MEM_HEADER_MAGIC0xCAFEBABE 0xCAFEBABE
29#define GF_MEM_TRAILER_MAGIC0xBAADF00D 0xBAADF00D
30
31#define GLUSTERFS_ENV_MEM_ACCT_STR"GLUSTERFS_DISABLE_MEM_ACCT" "GLUSTERFS_DISABLE_MEM_ACCT"
32
33void
34gf_mem_acct_enable_set (void *data)
35{
36 glusterfs_ctx_t *ctx = NULL((void*)0);
37
38 ctx = data;
39
40 GF_ASSERT (ctx)do { if (!(ctx)) { do { do { if (0) printf ("Assertion failed: "
"ctx"); } while (0); _gf_log_callingfn ("", "mem-pool.c", __FUNCTION__
, 40, GF_LOG_ERROR, "Assertion failed: " "ctx"); } while (0);
} } while (0)
;
41
42 ctx->mem_acct_enable = 1;
43
44 return;
45}
46
47void
48gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr,
49 size_t size, uint32_t type)
50{
51
52 char *ptr = NULL((void*)0);
53
54 if (!alloc_ptr)
55 return;
56
57 ptr = (char *) (*alloc_ptr);
58
59 GF_ASSERT (xl != NULL)do { if (!(xl != ((void*)0))) { do { do { if (0) printf ("Assertion failed: "
"xl != NULL"); } while (0); _gf_log_callingfn ("", "mem-pool.c"
, __FUNCTION__, 59, GF_LOG_ERROR, "Assertion failed: " "xl != NULL"
); } while (0); } } while (0)
;
60
61 GF_ASSERT (xl->mem_acct.rec != NULL)do { if (!(xl->mem_acct.rec != ((void*)0))) { do { do { if
(0) printf ("Assertion failed: " "xl->mem_acct.rec != NULL"
); } while (0); _gf_log_callingfn ("", "mem-pool.c", __FUNCTION__
, 61, GF_LOG_ERROR, "Assertion failed: " "xl->mem_acct.rec != NULL"
); } while (0); } } while (0)
;
62
63 GF_ASSERT (type <= xl->mem_acct.num_types)do { if (!(type <= xl->mem_acct.num_types)) { do { do {
if (0) printf ("Assertion failed: " "type <= xl->mem_acct.num_types"
); } while (0); _gf_log_callingfn ("", "mem-pool.c", __FUNCTION__
, 63, GF_LOG_ERROR, "Assertion failed: " "type <= xl->mem_acct.num_types"
); } while (0); } } while (0)
;
64
65 LOCK(&xl->mem_acct.rec[type].lock)pthread_spin_lock (&xl->mem_acct.rec[type].lock);
66 {
67 xl->mem_acct.rec[type].size += size;
68 xl->mem_acct.rec[type].num_allocs++;
69 xl->mem_acct.rec[type].total_allocs++;
70 xl->mem_acct.rec[type].max_size =
71 max (xl->mem_acct.rec[type].max_size,((xl->mem_acct.rec[type].max_size)>(xl->mem_acct.rec
[type].size)?(xl->mem_acct.rec[type].max_size):(xl->mem_acct
.rec[type].size))
72 xl->mem_acct.rec[type].size)((xl->mem_acct.rec[type].max_size)>(xl->mem_acct.rec
[type].size)?(xl->mem_acct.rec[type].max_size):(xl->mem_acct
.rec[type].size))
;
73 xl->mem_acct.rec[type].max_num_allocs =
74 max (xl->mem_acct.rec[type].max_num_allocs,((xl->mem_acct.rec[type].max_num_allocs)>(xl->mem_acct
.rec[type].num_allocs)?(xl->mem_acct.rec[type].max_num_allocs
):(xl->mem_acct.rec[type].num_allocs))
75 xl->mem_acct.rec[type].num_allocs)((xl->mem_acct.rec[type].max_num_allocs)>(xl->mem_acct
.rec[type].num_allocs)?(xl->mem_acct.rec[type].max_num_allocs
):(xl->mem_acct.rec[type].num_allocs))
;
76 }
77 UNLOCK(&xl->mem_acct.rec[type].lock)pthread_spin_unlock (&xl->mem_acct.rec[type].lock);
78
79 *(uint32_t *)(ptr) = type;
80 ptr = ptr + 4;
81 memcpy (ptr, &size, sizeof(size_t));
82 ptr += sizeof (size_t);
83 memcpy (ptr, &xl, sizeof(xlator_t *));
84 ptr += sizeof (xlator_t *);
85 *(uint32_t *)(ptr) = GF_MEM_HEADER_MAGIC0xCAFEBABE;
86 ptr = ptr + 4;
87 ptr = ptr + 8; //padding
88 *(uint32_t *) (ptr + size) = GF_MEM_TRAILER_MAGIC0xBAADF00D;
89
90 *alloc_ptr = (void *)ptr;
91 return;
92}
93
94
95void *
96__gf_calloc (size_t nmemb, size_t size, uint32_t type)
97{
98 size_t tot_size = 0;
99 size_t req_size = 0;
100 char *ptr = NULL((void*)0);
101 xlator_t *xl = NULL((void*)0);
102
103 if (!THIS(*__glusterfs_this_location())->ctx->mem_acct_enable)
104 return CALLOC (nmemb, size)__gf_default_calloc(nmemb,size);
105
106 xl = THIS(*__glusterfs_this_location());
107
108 req_size = nmemb * size;
109 tot_size = req_size + GF_MEM_HEADER_SIZE(4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8) + GF_MEM_TRAILER_SIZE8;
110
111 ptr = calloc (1, tot_size);
112
113 if (!ptr) {
114 gf_log_nomem ("", GF_LOG_ALERT, tot_size)do { _gf_log_nomem ("", "mem-pool.c", __FUNCTION__, 114, GF_LOG_ALERT
, tot_size); } while (0)
;
115 return NULL((void*)0);
116 }
117 gf_mem_set_acct_info (xl, &ptr, req_size, type);
118
119 return (void *)ptr;
120}
121
122void *
123__gf_malloc (size_t size, uint32_t type)
124{
125 size_t tot_size = 0;
126 char *ptr = NULL((void*)0);
127 xlator_t *xl = NULL((void*)0);
128
129 if (!THIS(*__glusterfs_this_location())->ctx->mem_acct_enable)
130 return MALLOC (size)__gf_default_malloc(size);
131
132 xl = THIS(*__glusterfs_this_location());
133
134 tot_size = size + GF_MEM_HEADER_SIZE(4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8) + GF_MEM_TRAILER_SIZE8;
135
136 ptr = malloc (tot_size);
137 if (!ptr) {
138 gf_log_nomem ("", GF_LOG_ALERT, tot_size)do { _gf_log_nomem ("", "mem-pool.c", __FUNCTION__, 138, GF_LOG_ALERT
, tot_size); } while (0)
;
139 return NULL((void*)0);
140 }
141 gf_mem_set_acct_info (xl, &ptr, size, type);
142
143 return (void *)ptr;
144}
145
146void *
147__gf_realloc (void *ptr, size_t size)
148{
149 size_t tot_size = 0;
150 char *orig_ptr = NULL((void*)0);
151 xlator_t *xl = NULL((void*)0);
152 uint32_t type = 0;
153
154 if (!THIS(*__glusterfs_this_location())->ctx->mem_acct_enable)
155 return REALLOC (ptr, size)__gf_default_realloc(ptr,size);
156
157 tot_size = size + GF_MEM_HEADER_SIZE(4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8) + GF_MEM_TRAILER_SIZE8;
158
159 orig_ptr = (char *)ptr - 8 - 4;
160
161 GF_ASSERT (*(uint32_t *)orig_ptr == GF_MEM_HEADER_MAGIC)do { if (!(*(uint32_t *)orig_ptr == 0xCAFEBABE)) { do { do { if
(0) printf ("Assertion failed: " "*(uint32_t *)orig_ptr == GF_MEM_HEADER_MAGIC"
); } while (0); _gf_log_callingfn ("", "mem-pool.c", __FUNCTION__
, 161, GF_LOG_ERROR, "Assertion failed: " "*(uint32_t *)orig_ptr == GF_MEM_HEADER_MAGIC"
); } while (0); } } while (0)
;
162
163 orig_ptr = orig_ptr - sizeof(xlator_t *);
164 xl = *((xlator_t **)orig_ptr);
165
166 orig_ptr = (char *)ptr - GF_MEM_HEADER_SIZE(4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8);
167 type = *(uint32_t *)orig_ptr;
168
169 ptr = realloc (orig_ptr, tot_size);
170 if (!ptr) {
171 gf_log_nomem ("", GF_LOG_ALERT, tot_size)do { _gf_log_nomem ("", "mem-pool.c", __FUNCTION__, 171, GF_LOG_ALERT
, tot_size); } while (0)
;
172 return NULL((void*)0);
173 }
174
175 gf_mem_set_acct_info (xl, (char **)&ptr, size, type);
176
177 return (void *)ptr;
178}
179
180int
181gf_vasprintf (char **string_ptr, const char *format, va_list arg)
182{
183 va_list arg_save;
184 char *str = NULL((void*)0);
185 int size = 0;
186 int rv = 0;
187
188 if (!string_ptr || !format)
189 return -1;
190
191 va_copy (arg_save, arg)__builtin_va_copy(arg_save, arg);
192
193 size = vsnprintf (NULL((void*)0), 0, format, arg);
194 size++;
195 str = GF_MALLOC (size, gf_common_mt_asprintf)__gf_malloc (size, gf_common_mt_asprintf);
196 if (str == NULL((void*)0)) {
197 /* log is done in GF_MALLOC itself */
198 return -1;
199 }
200 rv = vsnprintf (str, size, format, arg_save);
201
202 *string_ptr = str;
203 return (rv);
204}
205
206int
207gf_asprintf (char **string_ptr, const char *format, ...)
208{
209 va_list arg;
210 int rv = 0;
211
212 va_start (arg, format)__builtin_va_start(arg, format);
213 rv = gf_vasprintf (string_ptr, format, arg);
214 va_end (arg)__builtin_va_end(arg);
215
216 return rv;
217}
218
219void
220__gf_free (void *free_ptr)
221{
222 size_t req_size = 0;
223 char *ptr = NULL((void*)0);
224 uint32_t type = 0;
225 xlator_t *xl = NULL((void*)0);
226
227 if (!THIS(*__glusterfs_this_location())->ctx->mem_acct_enable) {
4
Taking false branch
228 FREE (free_ptr)if (free_ptr != ((void*)0)) { free ((void *)free_ptr); free_ptr
= (void *)0xeeeeeeee; }
;
229 return;
230 }
231
232 if (!free_ptr)
5
Assuming 'free_ptr' is non-null
6
Taking false branch
233 return;
234
235 ptr = (char *)free_ptr - 8 - 4;
236
237 //Possible corruption, assert here
238 GF_ASSERT (GF_MEM_HEADER_MAGIC == *(uint32_t *)ptr)do { if (!(0xCAFEBABE == *(uint32_t *)ptr)) { do { do { if (0
) printf ("Assertion failed: " "GF_MEM_HEADER_MAGIC == *(uint32_t *)ptr"
); } while (0); _gf_log_callingfn ("", "mem-pool.c", __FUNCTION__
, 238, GF_LOG_ERROR, "Assertion failed: " "GF_MEM_HEADER_MAGIC == *(uint32_t *)ptr"
); } while (0); } } while (0)
;
239
240 *(uint32_t *)ptr = 0;
241
242 ptr = ptr - sizeof(xlator_t *);
243 memcpy (&xl, ptr, sizeof(xlator_t *));
7
Value assigned to 'xl'
244
245 //gf_free expects xl to be available
246 GF_ASSERT (xl != NULL)do { if (!(xl != ((void*)0))) { do { do { if (0) printf ("Assertion failed: "
"xl != NULL"); } while (0); _gf_log_callingfn ("", "mem-pool.c"
, __FUNCTION__, 246, GF_LOG_ERROR, "Assertion failed: " "xl != NULL"
); } while (0); } } while (0)
;
8
Within the expansion of the macro 'GF_ASSERT':
a
Assuming 'xl' is equal to null
b
Assuming pointer value is null
247
248 if (!xl->mem_acct.rec) {
9
Dereference of null pointer
249 ptr = (char *)free_ptr - GF_MEM_HEADER_SIZE(4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8);
250 goto free;
251 }
252
253
254 ptr = ptr - sizeof(size_t);
255 memcpy (&req_size, ptr, sizeof (size_t));
256 ptr = ptr - 4;
257 type = *(uint32_t *)ptr;
258
259 // This points to a memory overrun
260 GF_ASSERT (GF_MEM_TRAILER_MAGIC ==do { if (!(0xBAADF00D == *(uint32_t *)((char *)free_ptr + req_size
))) { do { do { if (0) printf ("Assertion failed: " "GF_MEM_TRAILER_MAGIC == *(uint32_t *)((char *)free_ptr + req_size)"
); } while (0); _gf_log_callingfn ("", "mem-pool.c", __FUNCTION__
, 261, GF_LOG_ERROR, "Assertion failed: " "GF_MEM_TRAILER_MAGIC == *(uint32_t *)((char *)free_ptr + req_size)"
); } while (0); } } while (0)
261 *(uint32_t *)((char *)free_ptr + req_size))do { if (!(0xBAADF00D == *(uint32_t *)((char *)free_ptr + req_size
))) { do { do { if (0) printf ("Assertion failed: " "GF_MEM_TRAILER_MAGIC == *(uint32_t *)((char *)free_ptr + req_size)"
); } while (0); _gf_log_callingfn ("", "mem-pool.c", __FUNCTION__
, 261, GF_LOG_ERROR, "Assertion failed: " "GF_MEM_TRAILER_MAGIC == *(uint32_t *)((char *)free_ptr + req_size)"
); } while (0); } } while (0)
;
262
263 *(uint32_t *) ((char *)free_ptr + req_size) = 0;
264
265 LOCK (&xl->mem_acct.rec[type].lock)pthread_spin_lock (&xl->mem_acct.rec[type].lock);
266 {
267 xl->mem_acct.rec[type].size -= req_size;
268 xl->mem_acct.rec[type].num_allocs--;
269 }
270 UNLOCK (&xl->mem_acct.rec[type].lock)pthread_spin_unlock (&xl->mem_acct.rec[type].lock);
271free:
272 FREE (ptr)if (ptr != ((void*)0)) { free ((void *)ptr); ptr = (void *)0xeeeeeeee
; }
;
273}
274
275
276
277struct mem_pool *
278mem_pool_new_fn (unsigned long sizeof_type,
279 unsigned long count, char *name)
280{
281 struct mem_pool *mem_pool = NULL((void*)0);
282 unsigned long padded_sizeof_type = 0;
283 void *pool = NULL((void*)0);
284 int i = 0;
285 int ret = 0;
286 struct list_head *list = NULL((void*)0);
287 glusterfs_ctx_t *ctx = NULL((void*)0);
288
289 if (!sizeof_type || !count) {
290 gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("mem-pool", "mem-pool.c", __FUNCTION__, 290, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
291 return NULL((void*)0);
292 }
293 padded_sizeof_type = sizeof_type + GF_MEM_POOL_PAD_BOUNDARY((sizeof(struct list_head)) + (sizeof(struct mem_pool*)) + sizeof
(int))
;
294
295 mem_pool = GF_CALLOC (sizeof (*mem_pool), 1, gf_common_mt_mem_pool)__gf_calloc (sizeof (*mem_pool), 1, gf_common_mt_mem_pool);
296 if (!mem_pool)
297 return NULL((void*)0);
298
299 ret = gf_asprintf (&mem_pool->name, "%s:%s", THIS(*__glusterfs_this_location())->name, name);
300 if (ret < 0)
301 return NULL((void*)0);
302
303 if (!mem_pool->name) {
304 GF_FREE (mem_pool)__gf_free (mem_pool);
305 return NULL((void*)0);
306 }
307
308 LOCK_INIT (&mem_pool->lock)pthread_spin_init (&mem_pool->lock, 0);
309 INIT_LIST_HEAD (&mem_pool->list)do { (&mem_pool->list)->next = (&mem_pool->list
)->prev = &mem_pool->list; } while (0)
;
310 INIT_LIST_HEAD (&mem_pool->global_list)do { (&mem_pool->global_list)->next = (&mem_pool
->global_list)->prev = &mem_pool->global_list; }
while (0)
;
311
312 mem_pool->padded_sizeof_type = padded_sizeof_type;
313 mem_pool->cold_count = count;
314 mem_pool->real_sizeof_type = sizeof_type;
315
316 pool = GF_CALLOC (count, padded_sizeof_type, gf_common_mt_long)__gf_calloc (count, padded_sizeof_type, gf_common_mt_long);
317 if (!pool) {
318 GF_FREE (mem_pool->name)__gf_free (mem_pool->name);
319 GF_FREE (mem_pool)__gf_free (mem_pool);
320 return NULL((void*)0);
321 }
322
323 for (i = 0; i < count; i++) {
324 list = pool + (i * (padded_sizeof_type));
325 INIT_LIST_HEAD (list)do { (list)->next = (list)->prev = list; } while (0);
326 list_add_tail (list, &mem_pool->list);
327 }
328
329 mem_pool->pool = pool;
330 mem_pool->pool_end = pool + (count * (padded_sizeof_type));
331
332 /* add this pool to the global list */
333 ctx = THIS(*__glusterfs_this_location())->ctx;
334 if (!ctx)
335 goto out;
336
337 list_add (&mem_pool->global_list, &ctx->mempool_list);
338
339out:
340 return mem_pool;
341}
342
343void*
344mem_get0 (struct mem_pool *mem_pool)
345{
346 void *ptr = NULL((void*)0);
347
348 if (!mem_pool) {
349 gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("mem-pool", "mem-pool.c", __FUNCTION__, 349, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
350 return NULL((void*)0);
351 }
352
353 ptr = mem_get(mem_pool);
354
355 if (ptr)
356 memset(ptr, 0, mem_pool->real_sizeof_type);
357
358 return ptr;
359}
360
361void *
362mem_get (struct mem_pool *mem_pool)
363{
364 struct list_head *list = NULL((void*)0);
365 void *ptr = NULL((void*)0);
366 int *in_use = NULL((void*)0);
367 struct mem_pool **pool_ptr = NULL((void*)0);
368
369 if (!mem_pool) {
370 gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("mem-pool", "mem-pool.c", __FUNCTION__, 370, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
371 return NULL((void*)0);
372 }
373
374 LOCK (&mem_pool->lock)pthread_spin_lock (&mem_pool->lock);
375 {
376 mem_pool->alloc_count++;
377 if (mem_pool->cold_count) {
378 list = mem_pool->list.next;
379 list_del (list);
380
381 mem_pool->hot_count++;
382 mem_pool->cold_count--;
383
384 if (mem_pool->max_alloc < mem_pool->hot_count)
385 mem_pool->max_alloc = mem_pool->hot_count;
386
387 ptr = list;
388 in_use = (ptr + GF_MEM_POOL_LIST_BOUNDARY(sizeof(struct list_head)) +
389 GF_MEM_POOL_PTR(sizeof(struct mem_pool*)));
390 *in_use = 1;
391
392 goto fwd_addr_out;
393 }
394
395 /* This is a problem area. If we've run out of
396 * chunks in our slab above, we need to allocate
397 * enough memory to service this request.
398 * The problem is, these individual chunks will fail
399 * the first address range check in __is_member. Now, since
400 * we're not allocating a full second slab, we wont have
401 * enough info perform the range check in __is_member.
402 *
403 * I am working around this by performing a regular allocation
404 * , just the way the caller would've done when not using the
405 * mem-pool. That also means, we're not padding the size with
406 * the list_head structure because, this will not be added to
407 * the list of chunks that belong to the mem-pool allocated
408 * initially.
409 *
410 * This is the best we can do without adding functionality for
411 * managing multiple slabs. That does not interest us at present
412 * because it is too much work knowing that a better slab
413 * allocator is coming RSN.
414 */
415 mem_pool->pool_misses++;
416 mem_pool->curr_stdalloc++;
417 if (mem_pool->max_stdalloc < mem_pool->curr_stdalloc)
418 mem_pool->max_stdalloc = mem_pool->curr_stdalloc;
419 ptr = GF_CALLOC (1, mem_pool->padded_sizeof_type,__gf_calloc (1, mem_pool->padded_sizeof_type, gf_common_mt_mem_pool
)
420 gf_common_mt_mem_pool)__gf_calloc (1, mem_pool->padded_sizeof_type, gf_common_mt_mem_pool
)
;
421 gf_log_callingfn ("mem-pool", GF_LOG_DEBUG, "Mem pool is full. "do { do { if (0) printf ("Mem pool is full. " "Callocing mem"
); } while (0); _gf_log_callingfn ("mem-pool", "mem-pool.c", __FUNCTION__
, 422, GF_LOG_DEBUG, "Mem pool is full. " "Callocing mem"); }
while (0)
422 "Callocing mem")do { do { if (0) printf ("Mem pool is full. " "Callocing mem"
); } while (0); _gf_log_callingfn ("mem-pool", "mem-pool.c", __FUNCTION__
, 422, GF_LOG_DEBUG, "Mem pool is full. " "Callocing mem"); }
while (0)
;
423
424 /* Memory coming from the heap need not be transformed from a
425 * chunkhead to a usable pointer since it is not coming from
426 * the pool.
427 */
428 }
429fwd_addr_out:
430 pool_ptr = mem_pool_from_ptr (ptr)((ptr) + (sizeof(struct list_head)));
431 *pool_ptr = (struct mem_pool *)mem_pool;
432 ptr = mem_pool_chunkhead2ptr (ptr)((ptr) + ((sizeof(struct list_head)) + (sizeof(struct mem_pool
*)) + sizeof(int)))
;
433 UNLOCK (&mem_pool->lock)pthread_spin_unlock (&mem_pool->lock);
434
435 return ptr;
436}
437
438
439static int
440__is_member (struct mem_pool *pool, void *ptr)
441{
442 if (!pool || !ptr) {
443 gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("mem-pool", "mem-pool.c", __FUNCTION__, 443, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
444 return -1;
445 }
446
447 if (ptr < pool->pool || ptr >= pool->pool_end)
448 return 0;
449
450 if ((mem_pool_ptr2chunkhead (ptr)((ptr) - ((sizeof(struct list_head)) + (sizeof(struct mem_pool
*)) + sizeof(int)))
- pool->pool)
451 % pool->padded_sizeof_type)
452 return -1;
453
454 return 1;
455}
456
457
458void
459mem_put (void *ptr)
460{
461 struct list_head *list = NULL((void*)0);
462 int *in_use = NULL((void*)0);
463 void *head = NULL((void*)0);
464 struct mem_pool **tmp = NULL((void*)0);
465 struct mem_pool *pool = NULL((void*)0);
466
467 if (!ptr) {
468 gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("mem-pool", "mem-pool.c", __FUNCTION__, 468, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
469 return;
470 }
471
472 list = head = mem_pool_ptr2chunkhead (ptr)((ptr) - ((sizeof(struct list_head)) + (sizeof(struct mem_pool
*)) + sizeof(int)))
;
473 tmp = mem_pool_from_ptr (head)((head) + (sizeof(struct list_head)));
474 if (!tmp) {
475 gf_log_callingfn ("mem-pool", GF_LOG_ERROR,do { do { if (0) printf ("ptr header is corrupted"); } while (
0); _gf_log_callingfn ("mem-pool", "mem-pool.c", __FUNCTION__
, 476, GF_LOG_ERROR, "ptr header is corrupted"); } while (0)
476 "ptr header is corrupted")do { do { if (0) printf ("ptr header is corrupted"); } while (
0); _gf_log_callingfn ("mem-pool", "mem-pool.c", __FUNCTION__
, 476, GF_LOG_ERROR, "ptr header is corrupted"); } while (0)
;
477 return;
478 }
479
480 pool = *tmp;
481 if (!pool) {
482 gf_log_callingfn ("mem-pool", GF_LOG_ERROR,do { do { if (0) printf ("mem-pool ptr is NULL"); } while (0)
; _gf_log_callingfn ("mem-pool", "mem-pool.c", __FUNCTION__, 483
, GF_LOG_ERROR, "mem-pool ptr is NULL"); } while (0)
483 "mem-pool ptr is NULL")do { do { if (0) printf ("mem-pool ptr is NULL"); } while (0)
; _gf_log_callingfn ("mem-pool", "mem-pool.c", __FUNCTION__, 483
, GF_LOG_ERROR, "mem-pool ptr is NULL"); } while (0)
;
484 return;
485 }
486 LOCK (&pool->lock)pthread_spin_lock (&pool->lock);
487 {
488
489 switch (__is_member (pool, ptr))
490 {
491 case 1:
492 in_use = (head + GF_MEM_POOL_LIST_BOUNDARY(sizeof(struct list_head)) +
493 GF_MEM_POOL_PTR(sizeof(struct mem_pool*)));
494 if (!is_mem_chunk_in_use(in_use)(*in_use == 1)) {
495 gf_log_callingfn ("mem-pool", GF_LOG_CRITICAL,do { do { if (0) printf ("mem_put called on freed ptr %p of mem "
"pool %p", ptr, pool); } while (0); _gf_log_callingfn ("mem-pool"
, "mem-pool.c", __FUNCTION__, 497, GF_LOG_CRITICAL, "mem_put called on freed ptr %p of mem "
"pool %p", ptr, pool); } while (0)
496 "mem_put called on freed ptr %p of mem "do { do { if (0) printf ("mem_put called on freed ptr %p of mem "
"pool %p", ptr, pool); } while (0); _gf_log_callingfn ("mem-pool"
, "mem-pool.c", __FUNCTION__, 497, GF_LOG_CRITICAL, "mem_put called on freed ptr %p of mem "
"pool %p", ptr, pool); } while (0)
497 "pool %p", ptr, pool)do { do { if (0) printf ("mem_put called on freed ptr %p of mem "
"pool %p", ptr, pool); } while (0); _gf_log_callingfn ("mem-pool"
, "mem-pool.c", __FUNCTION__, 497, GF_LOG_CRITICAL, "mem_put called on freed ptr %p of mem "
"pool %p", ptr, pool); } while (0)
;
498 break;
499 }
500 pool->hot_count--;
501 pool->cold_count++;
502 *in_use = 0;
503 list_add (list, &pool->list);
504 break;
505 case -1:
506 /* For some reason, the address given is within
507 * the address range of the mem-pool but does not align
508 * with the expected start of a chunk that includes
509 * the list headers also. Sounds like a problem in
510 * layers of clouds up above us. ;)
511 */
512 abort ();
513 break;
514 case 0:
515 /* The address is outside the range of the mem-pool. We
516 * assume here that this address was allocated at a
517 * point when the mem-pool was out of chunks in mem_get
518 * or the programmer has made a mistake by calling the
519 * wrong de-allocation interface. We do
520 * not have enough info to distinguish between the two
521 * situations.
522 */
523 pool->curr_stdalloc--;
524 GF_FREE (list)__gf_free (list);
525 break;
526 default:
527 /* log error */
528 break;
529 }
530 }
531 UNLOCK (&pool->lock)pthread_spin_unlock (&pool->lock);
532}
533
534void
535mem_pool_destroy (struct mem_pool *pool)
536{
537 if (!pool)
1
Assuming 'pool' is non-null
2
Taking false branch
538 return;
539
540 gf_log (THIS->name, GF_LOG_INFO, "size=%lu max=%d total=%"PRIu64,do { do { if (0) printf ("size=%lu max=%d total=%""ll" "u", pool
->padded_sizeof_type, pool->max_alloc, pool->alloc_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "mem-pool.c", __FUNCTION__, 541, GF_LOG_INFO, "size=%lu max=%d total=%"
"ll" "u", pool->padded_sizeof_type, pool->max_alloc, pool
->alloc_count); } while (0)
541 pool->padded_sizeof_type, pool->max_alloc, pool->alloc_count)do { do { if (0) printf ("size=%lu max=%d total=%""ll" "u", pool
->padded_sizeof_type, pool->max_alloc, pool->alloc_count
); } while (0); _gf_log ((*__glusterfs_this_location())->name
, "mem-pool.c", __FUNCTION__, 541, GF_LOG_INFO, "size=%lu max=%d total=%"
"ll" "u", pool->padded_sizeof_type, pool->max_alloc, pool
->alloc_count); } while (0)
;
542
543 list_del (&pool->global_list);
544
545 LOCK_DESTROY (&pool->lock)pthread_spin_destroy (&pool->lock);
546 GF_FREE (pool->name)__gf_free (pool->name);
3
Within the expansion of the macro 'GF_FREE':
a
Calling '__gf_free'
547 GF_FREE (pool->pool)__gf_free (pool->pool);
548 GF_FREE (pool)__gf_free (pool);
549
550 return;
551}