@@ -6,6 +6,9 @@
#ifndef __KMEM_H__
#define __KMEM_H__
+void kmem_start_leak_check(void);
+bool kmem_found_leaks(void);
+
#define KM_NOFS 0x0004u
#define KM_MAYFAIL 0x0008u
#define KM_LARGE 0x0010u
@@ -38,17 +41,10 @@ kmem_zone_init(unsigned int size, const char *name)
return kmem_cache_create(name, size, 0, 0, NULL);
}
+void kmem_cache_destroy(kmem_zone_t *);
+
extern void *kmem_cache_alloc(kmem_zone_t *, gfp_t);
extern void *kmem_cache_zalloc(kmem_zone_t *, gfp_t);
-extern int kmem_zone_destroy(kmem_zone_t *);
-
-
-static inline void
-kmem_cache_destroy(kmem_zone_t *zone)
-{
- kmem_zone_destroy(zone);
-}
-
static inline void
kmem_cache_free(kmem_zone_t *zone, void *ptr)
@@ -255,22 +255,18 @@ init_zones(void)
sizeof(struct xfs_trans), "xfs_trans");
}
-static int
-destroy_zones(void)
+static void
+destroy_kmem_caches(void)
{
- int leaked = 0;
-
- leaked += kmem_zone_destroy(xfs_buf_zone);
- leaked += kmem_zone_destroy(xfs_ili_zone);
- leaked += kmem_zone_destroy(xfs_inode_zone);
- leaked += kmem_zone_destroy(xfs_ifork_zone);
- leaked += kmem_zone_destroy(xfs_buf_item_zone);
- leaked += kmem_zone_destroy(xfs_da_state_zone);
+ kmem_cache_destroy(xfs_buf_zone);
+ kmem_cache_destroy(xfs_ili_zone);
+ kmem_cache_destroy(xfs_inode_zone);
+ kmem_cache_destroy(xfs_ifork_zone);
+ kmem_cache_destroy(xfs_buf_item_zone);
+ kmem_cache_destroy(xfs_da_state_zone);
xfs_btree_destroy_cur_caches();
- leaked += kmem_zone_destroy(xfs_bmap_free_item_zone);
- leaked += kmem_zone_destroy(xfs_trans_zone);
-
- return leaked;
+ kmem_cache_destroy(xfs_bmap_free_item_zone);
+ kmem_cache_destroy(xfs_trans_zone);
}
static void
@@ -1025,17 +1021,17 @@ void
libxfs_destroy(
struct libxfs_xinit *li)
{
- int leaked;
-
+ kmem_start_leak_check();
libxfs_close_devices(li);
/* Free everything from the buffer cache before freeing buffer zone */
libxfs_bcache_purge();
libxfs_bcache_free();
cache_destroy(libxfs_bcache);
- leaked = destroy_zones();
+ destroy_kmem_caches();
rcu_unregister_thread();
- if (getenv("LIBXFS_LEAK_CHECK") && leaked)
+
+ if (kmem_found_leaks())
exit(1);
}
@@ -3,6 +3,18 @@
#include "libxfs_priv.h"
+static bool leaked;
+
+void kmem_start_leak_check(void)
+{
+ leaked = false;
+}
+
+bool kmem_found_leaks(void)
+{
+ return leaked;
+}
+
/*
* Simple memory interface
*/
@@ -27,18 +39,15 @@ kmem_cache_create(const char *name, unsigned int size, unsigned int align,
return ptr;
}
-int
-kmem_zone_destroy(kmem_zone_t *zone)
+void
+kmem_cache_destroy(kmem_zone_t *zone)
{
- int leaked = 0;
-
if (getenv("LIBXFS_LEAK_CHECK") && zone->allocated) {
- leaked = 1;
+ leaked = true;
fprintf(stderr, "zone %s freed with %d items allocated\n",
zone->zone_name, zone->allocated);
}
free(zone);
- return leaked;
}
void *