ext2 ext3 ext4: support inode slab defragmentation Signed-off-by: Christoph Lameter --- fs/ext2/super.c | 23 +++++++++++++++++++++-- fs/ext3/super.c | 21 ++++++++++++++++++++- fs/ext4/super.c | 23 ++++++++++++++++++++++- include/linux/fs.h | 2 ++ 4 files changed, 65 insertions(+), 4 deletions(-) Index: slub/fs/ext2/super.c =================================================================== --- slub.orig/fs/ext2/super.c 2007-05-19 20:21:02.000000000 -0700 +++ slub/fs/ext2/super.c 2007-05-19 20:21:57.000000000 -0700 @@ -168,14 +168,26 @@ static void init_once(void * foo, struct mutex_init(&ei->truncate_mutex); inode_init_once(&ei->vfs_inode); } - + +static void *ext2_get_inodes(struct kmem_cache *s, int nr, void **v) +{ + return fs_get_inodes(s, nr, v, + offsetof(struct ext2_inode_info, vfs_inode)); +} + +static struct kmem_cache_ops ext2_kmem_cache_ops = { + .get = ext2_get_inodes, + .kick = kick_inodes +}; + static int init_inodecache(void) { ext2_inode_cachep = kmem_cache_create("ext2_inode_cache", sizeof(struct ext2_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once, NULL); + init_once, + &ext2_kmem_cache_ops); if (ext2_inode_cachep == NULL) return -ENOMEM; return 0; @@ -235,12 +247,19 @@ static ssize_t ext2_quota_read(struct su static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); #endif +static void ext2_shrink_inodes(int nr_freed) +{ + if (nr_freed > 100) + kmem_cache_shrink(ext2_inode_cachep); +} + static const struct super_operations ext2_sops = { .alloc_inode = ext2_alloc_inode, .destroy_inode = ext2_destroy_inode, .read_inode = ext2_read_inode, .write_inode = ext2_write_inode, .delete_inode = ext2_delete_inode, + .shrink_inodes = ext2_shrink_inodes, .put_super = ext2_put_super, .write_super = ext2_write_super, .statfs = ext2_statfs, Index: slub/fs/ext3/super.c =================================================================== --- slub.orig/fs/ext3/super.c 2007-05-19 20:21:02.000000000 -0700 +++ slub/fs/ext3/super.c 2007-05-19 20:21:57.000000000 -0700 @@ -475,13 +475,25 @@ static void init_once(void * foo, struct inode_init_once(&ei->vfs_inode); } +static void *ext3_get_inodes(struct kmem_cache *s, int nr, void **v) +{ + return fs_get_inodes(s, nr, v, + offsetof(struct ext3_inode_info, vfs_inode)); +} + +static struct kmem_cache_ops ext3_kmem_cache_ops = { + .get = ext3_get_inodes, + .kick = kick_inodes +}; + static int init_inodecache(void) { ext3_inode_cachep = kmem_cache_create("ext3_inode_cache", sizeof(struct ext3_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once, NULL); + init_once, + &ext3_kmem_cache_ops); if (ext3_inode_cachep == NULL) return -ENOMEM; return 0; @@ -637,6 +649,12 @@ static struct quotactl_ops ext3_qctl_ope }; #endif +static void ext3_shrink_inodes(int nr_freed) +{ + if (nr_freed > 100) + kmem_cache_shrink(ext3_inode_cachep); +} + static const struct super_operations ext3_sops = { .alloc_inode = ext3_alloc_inode, .destroy_inode = ext3_destroy_inode, @@ -644,6 +662,7 @@ static const struct super_operations ext .write_inode = ext3_write_inode, .dirty_inode = ext3_dirty_inode, .delete_inode = ext3_delete_inode, + .shrink_inodes = ext3_shrink_inodes, .put_super = ext3_put_super, .write_super = ext3_write_super, .sync_fs = ext3_sync_fs, Index: slub/fs/ext4/super.c =================================================================== --- slub.orig/fs/ext4/super.c 2007-05-19 20:21:02.000000000 -0700 +++ slub/fs/ext4/super.c 2007-05-19 20:21:57.000000000 -0700 @@ -535,13 +535,26 @@ static void init_once(void * foo, struct inode_init_once(&ei->vfs_inode); } +static void *ext4_get_inodes(struct kmem_cache *s, int nr, void **v) +{ + return fs_get_inodes(s, nr, v, + offsetof(struct ext4_inode_info, vfs_inode)); +} + +static struct kmem_cache_ops ext4_kmem_cache_ops = { + .get = ext4_get_inodes, + .kick = kick_inodes +}; + + static int init_inodecache(void) { ext4_inode_cachep = kmem_cache_create("ext4_inode_cache", sizeof(struct ext4_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once, NULL); + init_once, + &ext4_kmem_cache_ops); if (ext4_inode_cachep == NULL) return -ENOMEM; return 0; @@ -697,6 +710,13 @@ static struct quotactl_ops ext4_qctl_ope }; #endif +static void ext4_shrink_inodes(int nr_freed) +{ + if (nr_freed > 100) + kmem_cache_shrink(ext4_inode_cachep); +} + + static const struct super_operations ext4_sops = { .alloc_inode = ext4_alloc_inode, .destroy_inode = ext4_destroy_inode, @@ -706,6 +726,7 @@ static const struct super_operations ext .delete_inode = ext4_delete_inode, .put_super = ext4_put_super, .write_super = ext4_write_super, + .shrink_inodes = ext4_shrink_inodes, .sync_fs = ext4_sync_fs, .write_super_lockfs = ext4_write_super_lockfs, .unlockfs = ext4_unlockfs, Index: slub/include/linux/fs.h =================================================================== --- slub.orig/include/linux/fs.h 2007-05-19 21:28:04.000000000 -0700 +++ slub/include/linux/fs.h 2007-05-19 21:36:27.000000000 -0700 @@ -974,6 +974,8 @@ struct super_block { * in /proc/mounts will be "type.subtype" */ char *s_subtype; + unsigned long last_shrink; + unsigned long pruned_since_shrink; }; extern struct timespec current_fs_time(struct super_block *sb);