Commit 8d3b35914aa54232b27e6a2b57d84092aadc5e86
Committed by
Linus Torvalds
1 parent
c0fef676bb
Exists in
master
and in
7 other branches
[PATCH] inotify/idr leak fix
Fix a bug which was reported and diagnosed by Stefan Jones <stefan.jones@churchillrandoms.co.uk> IDR trees include a cache of idr_layer objects. There's no way to destroy this cache, so when we discard an overall idr tree we end up leaking some memory. Add and use idr_destroy() for this. v9fs and infiniband also need to use idr_destroy() to avoid leaks. Or, we make the cache global, like radix_tree_preload(). Which is probably better. Later. Cc: Eric Van Hensbergen <ericvh@ericvh.myip.org> Cc: Roland Dreier <rolandd@cisco.com> Cc: Robert Love <rml@novell.com> Cc: John McCutchan <ttb@tentacle.dhs.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 3 changed files with 15 additions and 0 deletions Side-by-side Diff
fs/inotify.c
include/linux/idr.h
lib/idr.c
... | ... | @@ -346,6 +346,19 @@ |
346 | 346 | EXPORT_SYMBOL(idr_remove); |
347 | 347 | |
348 | 348 | /** |
349 | + * idr_destroy - release all cached layers within an idr tree | |
350 | + * idp: idr handle | |
351 | + */ | |
352 | +void idr_destroy(struct idr *idp) | |
353 | +{ | |
354 | + while (idp->id_free_cnt) { | |
355 | + struct idr_layer *p = alloc_layer(idp); | |
356 | + kmem_cache_free(idr_layer_cache, p); | |
357 | + } | |
358 | +} | |
359 | +EXPORT_SYMBOL(idr_destroy); | |
360 | + | |
361 | +/** | |
349 | 362 | * idr_find - return pointer for given id |
350 | 363 | * @idp: idr handle |
351 | 364 | * @id: lookup key |