dbeug check for leaked blockdev buffers
Subsystems (4)
PATCH 6/27 dbeug check for leaked blockdev buffers
Having just fiddled with the refcounts of blockdev buffers, I want some way of assuring that the code is correct and is not leaking buffer_heads.
There's no easy way to do this: if a blockdev page has pinned buffers then truncate_complete_page just cuts it loose and we leak memory.
The patch adds a bit of debug code to catch these leaks. This code, PF_RADIX_TREE and buffer_error() need to be removed later on.
fs/buffer.c | 2 ++ include/linux/sched.h | 2 +- mm/filemap.c | 7 ++++++- 3 files changed, 9 insertions(+), 2 deletions(-)
mm/filemap.c renamed from mm/filemap.c~buffer-leak-check +6 -1
@@ -177,8 +177,13 @@ static inline void truncate_partial_pagestatic void truncate_complete_page (struct page *page) {/* Leave it on the LRU if it gets converted into anonymous buffers */ -if (!PagePrivate (page) ||do_invalidatepage (page,0 )) +if (!PagePrivate (page) ||do_invalidatepage (page,0 )) {lru_cache_del (page); + }else { +if (current->flags &PF_INVALIDATE ) +printk ("%s: buffer heads were leaked\n" , + current->comm); + }ClearPageDirty (page);ClearPageUptodate (page);remove_inode_page (page);
fs/buffer.c renamed from fs/buffer.c~buffer-leak-check +2 -0
@@ -467,7 +467,9 @@ void invalidate_bdev(struct block_device* We really want to use invalidate_inode_pages2() for * that, but not until that's cleaned up. */ + current->flags |=PF_INVALIDATE ;invalidate_inode_pages (bdev->bd_inode); + current->flags &= ~PF_INVALIDATE ; }void __invalidate_buffers (kdev_t dev,int destroy_dirty_buffers)
include/linux/sched.h renamed from include/linux/sched.h~buffer-leak-check +1 -1
@@ -391,7 +391,7 @@ do { if (atomic_dec_and_test(&(tsk)->usa#define PF_FREEZE 0x00010000/* this task should be frozen for suspend */ #define PF_IOTHREAD 0x00020000/* this thread is needed for doing I/O to swap */ #define PF_FROZEN 0x00040000/* frozen for system suspend */ - +#define PF_INVALIDATE 0x00080000/* debug: unmounting an fs. killme. */ /* * Ptrace flags */
-