--- fs/inode.c | 23 +++++++++++++++++++++++ mm/slub.c | 5 +++++ 2 files changed, 28 insertions(+) Index: slub/fs/inode.c =================================================================== --- slub.orig/fs/inode.c 2007-06-07 12:35:47.000000000 -0700 +++ slub/fs/inode.c 2007-06-07 12:53:23.000000000 -0700 @@ -1388,6 +1388,7 @@ void kick_inodes(struct kmem_cache *s, i struct inode *inode; int i; int abort = 0; + int done = 0; LIST_HEAD(freeable); struct super_block *sb; @@ -1402,6 +1403,16 @@ void kick_inodes(struct kmem_cache *s, i 0, -1); } + /* Invalidate children and dentry */ + if (S_ISDIR(inode->i_mode)) { + struct dentry *d = d_find_alias(inode); + + if (d) { + d_invalidate(d); + dput(d); + } + } + if (inode->i_state & I_DIRTY) write_inode_now(inode, 1); @@ -1421,11 +1432,23 @@ void kick_inodes(struct kmem_cache *s, i spin_lock(&inode_lock); abort = !can_unuse(inode); + if (abort) { + struct dentry *d = d_find_alias(inode); + + dput(d); + printk("Aborting on object '%s' %p state=%lx count=%ld pages=%d done=%d" + " mode=%o links=%d subdirs empty=%d dcount=%d\n", + d ? d->d_name.name:NULL, inode, inode->i_state, atomic_read(&inode->i_count), + inode->i_data.nrpages, done, inode->i_mode, inode->i_nlink, + d ? list_empty(&d->d_subdirs): -1, d ? atomic_read(&d->d_count): -1); + + } if (!abort) { list_move(&inode->i_list, &freeable); inode->i_state |= I_FREEING; inodes_stat.nr_unused--; + done++; } spin_unlock(&inode_lock); } Index: slub/mm/slub.c =================================================================== --- slub.orig/mm/slub.c 2007-06-07 12:35:42.000000000 -0700 +++ slub/mm/slub.c 2007-06-07 12:50:37.000000000 -0700 @@ -2428,6 +2428,8 @@ static int __kmem_cache_vacate(struct km int objects; void *private; + printk(KERN_ERR "__kmem_cache_vacate %s %p inuse=%d\n", + s->name, page, page->inuse); if (!page->inuse) goto out; @@ -2579,6 +2581,9 @@ static unsigned long __kmem_cache_shrink if (__kmem_cache_vacate(s, page, flags, scratch) == 0) freed++; } + + printk(KERN_ERR "kmem_cache_shrink %s partial slabs freed=%d left=%ld.\n", + s->name, freed, n->nr_partial); return freed; }