Return error codes from slab constructors; originally due to Manfred Spraul. fs/adfs/super.c | 3 +- fs/affs/super.c | 3 +- fs/afs/super.c | 5 ++- fs/befs/linuxvfs.c | 3 +- fs/bfs/inode.c | 3 +- fs/block_dev.c | 3 +- fs/buffer.c | 3 +- fs/char_dev.c | 3 +- fs/cifs/cifsfs.c | 3 +- fs/coda/inode.c | 3 +- fs/efs/super.c | 3 +- fs/ext2/super.c | 3 +- fs/ext3/super.c | 3 +- fs/fat/inode.c | 3 +- fs/hfs/super.c | 3 +- fs/hpfs/super.c | 3 +- fs/inode.c | 3 +- fs/isofs/inode.c | 3 +- fs/jffs2/super.c | 3 +- fs/jfs/jfs_metapage.c | 3 +- fs/jfs/super.c | 3 +- fs/locks.c | 5 ++- fs/minix/inode.c | 3 +- fs/ncpfs/inode.c | 3 +- fs/nfs/inode.c | 3 +- fs/ntfs/super.c | 3 +- fs/proc/inode.c | 3 +- fs/qnx4/inode.c | 3 +- fs/reiserfs/super.c | 3 +- fs/romfs/inode.c | 3 +- fs/smbfs/inode.c | 3 +- fs/sysv/inode.c | 3 +- fs/udf/super.c | 3 +- fs/ufs/super.c | 3 +- fs/xfs/linux/xfs_super.c | 3 +- include/linux/slab.h | 4 +- lib/radix-tree.c | 3 +- mm/rmap.c | 3 +- mm/shmem.c | 3 +- mm/slab.c | 68 ++++++++++++++++++++++++++++++++++++++++------- net/core/skbuff.c | 3 +- net/socket.c | 3 +- 42 files changed, 143 insertions(+), 53 deletions(-) diff -urpN wli-2.5.50-bk6-11/fs/adfs/super.c wli-2.5.50-bk6-12/fs/adfs/super.c --- wli-2.5.50-bk6-11/fs/adfs/super.c 2002-11-27 14:35:46.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/adfs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -220,13 +220,14 @@ static void adfs_destroy_inode(struct in kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/affs/super.c wli-2.5.50-bk6-12/fs/affs/super.c --- wli-2.5.50-bk6-11/fs/affs/super.c 2002-11-27 14:36:15.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/affs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -100,7 +100,7 @@ static void affs_destroy_inode(struct in kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct affs_inode_info *ei = (struct affs_inode_info *) foo; @@ -110,6 +110,7 @@ static void init_once(void * foo, kmem_c init_MUTEX(&ei->i_ext_lock); inode_init_once(&ei->vfs_inode); } + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/afs/super.c wli-2.5.50-bk6-12/fs/afs/super.c --- wli-2.5.50-bk6-11/fs/afs/super.c 2002-11-27 14:35:58.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/afs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -37,7 +37,7 @@ static inline char *strdup(const char *s return ns; } -static void afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags); +static int afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags); static struct super_block *afs_get_sb(struct file_system_type *fs_type, int flags, char *dev_name, void *data); @@ -460,7 +460,7 @@ static void afs_put_super(struct super_b /* * initialise an inode cache slab element prior to any use */ -static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags) +static int afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags) { afs_vnode_t *vnode = (afs_vnode_t *) _vnode; @@ -473,6 +473,7 @@ static void afs_i_init_once(void *_vnode INIT_LIST_HEAD(&vnode->cb_hash_link); afs_timer_init(&vnode->cb_timeout,&afs_vnode_cb_timed_out_ops); } + return 0; } /* end afs_i_init_once() */ diff -urpN wli-2.5.50-bk6-11/fs/befs/linuxvfs.c wli-2.5.50-bk6-12/fs/befs/linuxvfs.c --- wli-2.5.50-bk6-11/fs/befs/linuxvfs.c 2002-11-27 14:35:59.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/befs/linuxvfs.c 2002-12-06 14:53:19.000000000 -0800 @@ -293,7 +293,7 @@ befs_destroy_inode(struct inode *inode) kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct befs_inode_info *bi = (struct befs_inode_info *) foo; @@ -301,6 +301,7 @@ static void init_once(void * foo, kmem_c SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&bi->vfs_inode); } + return 0; } static void diff -urpN wli-2.5.50-bk6-11/fs/bfs/inode.c wli-2.5.50-bk6-12/fs/bfs/inode.c --- wli-2.5.50-bk6-11/fs/bfs/inode.c 2002-11-27 14:35:58.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/bfs/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -229,13 +229,14 @@ static void bfs_destroy_inode(struct ino kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct bfs_inode_info *bi = foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&bi->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/block_dev.c wli-2.5.50-bk6-12/fs/block_dev.c --- wli-2.5.50-bk6-11/fs/block_dev.c 2002-11-27 14:36:24.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/block_dev.c 2002-12-06 14:53:19.000000000 -0800 @@ -224,7 +224,7 @@ static kmem_cache_t * bdev_cachep; ((struct block_device *) kmem_cache_alloc(bdev_cachep, SLAB_KERNEL)) #define destroy_bdev(bdev) kmem_cache_free(bdev_cachep, (bdev)) -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct block_device * bdev = (struct block_device *) foo; @@ -235,6 +235,7 @@ static void init_once(void * foo, kmem_c sema_init(&bdev->bd_sem, 1); INIT_LIST_HEAD(&bdev->bd_inodes); } + return 0; } void __init bdev_cache_init(void) diff -urpN wli-2.5.50-bk6-11/fs/buffer.c wli-2.5.50-bk6-12/fs/buffer.c --- wli-2.5.50-bk6-11/fs/buffer.c 2002-12-06 13:44:47.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/buffer.c 2002-12-06 14:53:19.000000000 -0800 @@ -2827,7 +2827,7 @@ void free_buffer_head(struct buffer_head } EXPORT_SYMBOL(free_buffer_head); -static void init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) +static int init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) { if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { @@ -2836,6 +2836,7 @@ static void init_buffer_head(void *data, memset(bh, 0, sizeof(*bh)); INIT_LIST_HEAD(&bh->b_assoc_buffers); } + return 0; } static void *bh_mempool_alloc(int gfp_mask, void *pool_data) diff -urpN wli-2.5.50-bk6-11/fs/char_dev.c wli-2.5.50-bk6-12/fs/char_dev.c --- wli-2.5.50-bk6-11/fs/char_dev.c 2002-11-27 14:35:56.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/char_dev.c 2002-12-06 14:53:19.000000000 -0800 @@ -38,7 +38,7 @@ static kmem_cache_t * cdev_cachep; ((struct char_device *) kmem_cache_alloc(cdev_cachep, SLAB_KERNEL)) #define destroy_cdev(cdev) kmem_cache_free(cdev_cachep, (cdev)) -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct char_device * cdev = (struct char_device *) foo; @@ -48,6 +48,7 @@ static void init_once(void * foo, kmem_c memset(cdev, 0, sizeof(*cdev)); sema_init(&cdev->sem, 1); } + return 0; } void __init cdev_cache_init(void) diff -urpN wli-2.5.50-bk6-11/fs/cifs/cifsfs.c wli-2.5.50-bk6-12/fs/cifs/cifsfs.c --- wli-2.5.50-bk6-11/fs/cifs/cifsfs.c 2002-11-27 14:36:01.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/cifs/cifsfs.c 2002-12-06 14:53:19.000000000 -0800 @@ -303,7 +303,7 @@ struct file_operations cifs_dir_ops = { .release = cifs_closedir, }; -static void +static int cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags) { struct cifsInodeInfo *cifsi = (struct cifsInodeInfo *) inode; @@ -313,6 +313,7 @@ cifs_init_once(void *inode, kmem_cache_t inode_init_once(&cifsi->vfs_inode); INIT_LIST_HEAD(&cifsi->lockList); } + return 0; } int diff -urpN wli-2.5.50-bk6-11/fs/coda/inode.c wli-2.5.50-bk6-12/fs/coda/inode.c --- wli-2.5.50-bk6-11/fs/coda/inode.c 2002-11-27 14:36:00.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/coda/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -56,13 +56,14 @@ static void coda_destroy_inode(struct in kmem_cache_free(coda_inode_cachep, ITOC(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct coda_inode_info *ei = (struct coda_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } int coda_init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/efs/super.c wli-2.5.50-bk6-12/fs/efs/super.c --- wli-2.5.50-bk6-11/fs/efs/super.c 2002-11-27 14:36:17.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/efs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -44,13 +44,14 @@ static void efs_destroy_inode(struct ino kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct efs_inode_info *ei = (struct efs_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/ext2/super.c wli-2.5.50-bk6-12/fs/ext2/super.c --- wli-2.5.50-bk6-11/fs/ext2/super.c 2002-11-27 14:36:14.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/ext2/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -169,7 +169,7 @@ static void ext2_destroy_inode(struct in kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; @@ -178,6 +178,7 @@ static void init_once(void * foo, kmem_c rwlock_init(&ei->i_meta_lock); inode_init_once(&ei->vfs_inode); } + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/ext3/super.c wli-2.5.50-bk6-12/fs/ext3/super.c --- wli-2.5.50-bk6-11/fs/ext3/super.c 2002-12-06 13:44:47.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/ext3/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -443,7 +443,7 @@ static void ext3_destroy_inode(struct in kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; @@ -453,6 +453,7 @@ static void init_once(void * foo, kmem_c init_rwsem(&ei->truncate_sem); inode_init_once(&ei->vfs_inode); } + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/fat/inode.c wli-2.5.50-bk6-12/fs/fat/inode.c --- wli-2.5.50-bk6-11/fs/fat/inode.c 2002-12-06 13:44:47.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/fat/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -682,7 +682,7 @@ static void fat_destroy_inode(struct ino kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct msdos_inode_info *ei = (struct msdos_inode_info *) foo; @@ -691,6 +691,7 @@ static void init_once(void * foo, kmem_c INIT_LIST_HEAD(&ei->i_fat_hash); inode_init_once(&ei->vfs_inode); } + return 0; } int __init fat_init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/hfs/super.c wli-2.5.50-bk6-12/fs/hfs/super.c --- wli-2.5.50-bk6-11/fs/hfs/super.c 2002-11-27 14:35:56.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/hfs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -58,13 +58,14 @@ static void hfs_destroy_inode(struct ino kmem_cache_free(hfs_inode_cachep, HFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct hfs_inode_info *ei = (struct hfs_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/hpfs/super.c wli-2.5.50-bk6-12/fs/hpfs/super.c --- wli-2.5.50-bk6-11/fs/hpfs/super.c 2002-11-27 14:36:04.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/hpfs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -175,7 +175,7 @@ static void hpfs_destroy_inode(struct in kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; @@ -184,6 +184,7 @@ static void init_once(void * foo, kmem_c init_MUTEX(&ei->i_sem); inode_init_once(&ei->vfs_inode); } + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/inode.c wli-2.5.50-bk6-12/fs/inode.c --- wli-2.5.50-bk6-11/fs/inode.c 2002-12-06 14:00:29.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -178,13 +178,14 @@ void inode_init_once(struct inode *inode INIT_LIST_HEAD(&inode->i_data.i_mmap_shared); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct inode * inode = (struct inode *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(inode); + return 0; } /* diff -urpN wli-2.5.50-bk6-11/fs/isofs/inode.c wli-2.5.50-bk6-12/fs/isofs/inode.c --- wli-2.5.50-bk6-11/fs/isofs/inode.c 2002-11-27 14:36:22.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/isofs/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -92,13 +92,14 @@ static void isofs_destroy_inode(struct i kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct iso_inode_info *ei = (struct iso_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/jffs2/super.c wli-2.5.50-bk6-12/fs/jffs2/super.c --- wli-2.5.50-bk6-11/fs/jffs2/super.c 2002-11-27 14:35:56.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/jffs2/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -47,7 +47,7 @@ static void jffs2_destroy_inode(struct i kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); } -static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; @@ -56,6 +56,7 @@ static void jffs2_i_init_once(void * foo init_MUTEX(&ei->sem); inode_init_once(&ei->vfs_inode); } + return 0; } static struct super_operations jffs2_super_operations = diff -urpN wli-2.5.50-bk6-11/fs/jfs/jfs_metapage.c wli-2.5.50-bk6-12/fs/jfs/jfs_metapage.c --- wli-2.5.50-bk6-11/fs/jfs/jfs_metapage.c 2002-11-27 14:35:53.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/jfs/jfs_metapage.c 2002-12-06 14:53:19.000000000 -0800 @@ -90,7 +90,7 @@ static inline void lock_metapage(struct static kmem_cache_t *metapage_cache; static mempool_t *metapage_mempool; -static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) +static int init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct metapage *mp = (struct metapage *)foo; @@ -105,6 +105,7 @@ static void init_once(void *foo, kmem_ca set_bit(META_free, &mp->flag); init_waitqueue_head(&mp->wait); } + return 0; } static inline struct metapage *alloc_metapage(int no_wait) diff -urpN wli-2.5.50-bk6-11/fs/jfs/super.c wli-2.5.50-bk6-12/fs/jfs/super.c --- wli-2.5.50-bk6-11/fs/jfs/super.c 2002-11-27 14:35:59.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/jfs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -405,7 +405,7 @@ extern int txInit(void); extern void txExit(void); extern void metapage_exit(void); -static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; @@ -423,6 +423,7 @@ static void init_once(void *foo, kmem_ca #endif inode_init_once(&jfs_ip->vfs_inode); } + return 0; } static int __init init_jfs_fs(void) diff -urpN wli-2.5.50-bk6-11/fs/locks.c wli-2.5.50-bk6-12/fs/locks.c --- wli-2.5.50-bk6-11/fs/locks.c 2002-12-06 13:44:47.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/locks.c 2002-12-06 14:53:19.000000000 -0800 @@ -196,15 +196,16 @@ void locks_init_lock(struct file_lock *f * Initialises the fields of the file lock which are invariant for * free file_locks. */ -static void init_once(void *foo, kmem_cache_t *cache, unsigned long flags) +static int init_once(void *foo, kmem_cache_t *cache, unsigned long flags) { struct file_lock *lock = (struct file_lock *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) != SLAB_CTOR_CONSTRUCTOR) - return; + return 0; locks_init_lock(lock); + return 0; } /* diff -urpN wli-2.5.50-bk6-11/fs/minix/inode.c wli-2.5.50-bk6-12/fs/minix/inode.c --- wli-2.5.50-bk6-11/fs/minix/inode.c 2002-11-27 14:36:01.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/minix/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -65,13 +65,14 @@ static void minix_destroy_inode(struct i kmem_cache_free(minix_inode_cachep, minix_i(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct minix_inode_info *ei = (struct minix_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/ncpfs/inode.c wli-2.5.50-bk6-12/fs/ncpfs/inode.c --- wli-2.5.50-bk6-11/fs/ncpfs/inode.c 2002-11-27 14:36:00.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/ncpfs/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -56,7 +56,7 @@ static void ncp_destroy_inode(struct ino kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; @@ -65,6 +65,7 @@ static void init_once(void * foo, kmem_c init_MUTEX(&ei->open_sem); inode_init_once(&ei->vfs_inode); } + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/nfs/inode.c wli-2.5.50-bk6-12/fs/nfs/inode.c --- wli-2.5.50-bk6-11/fs/nfs/inode.c 2002-11-27 14:36:17.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/nfs/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -1524,7 +1524,7 @@ static void nfs_destroy_inode(struct ino kmem_cache_free(nfs_inode_cachep, NFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct nfs_inode *nfsi = (struct nfs_inode *) foo; @@ -1539,6 +1539,7 @@ static void init_once(void * foo, kmem_c nfsi->npages = 0; init_waitqueue_head(&nfsi->nfs_i_wait); } + return 0; } int nfs_init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/ntfs/super.c wli-2.5.50-bk6-12/fs/ntfs/super.c --- wli-2.5.50-bk6-11/fs/ntfs/super.c 2002-11-27 14:36:15.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/ntfs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -1598,7 +1598,7 @@ kmem_cache_t *ntfs_inode_cache; kmem_cache_t *ntfs_big_inode_cache; /* Init once constructor for the inode slab cache. */ -static void ntfs_big_inode_init_once(void *foo, kmem_cache_t *cachep, +static int ntfs_big_inode_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { ntfs_inode *ni = (ntfs_inode *)foo; @@ -1606,6 +1606,7 @@ static void ntfs_big_inode_init_once(voi if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(VFS_I(ni)); + return 0; } /* diff -urpN wli-2.5.50-bk6-11/fs/proc/inode.c wli-2.5.50-bk6-12/fs/proc/inode.c --- wli-2.5.50-bk6-11/fs/proc/inode.c 2002-12-06 13:55:27.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/proc/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -109,13 +109,14 @@ static void proc_destroy_inode(struct in kmem_cache_free(proc_inode_cachep, PROC_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct proc_inode *ei = (struct proc_inode *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } int __init proc_init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/qnx4/inode.c wli-2.5.50-bk6-12/fs/qnx4/inode.c --- wli-2.5.50-bk6-11/fs/qnx4/inode.c 2002-11-27 14:36:18.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/qnx4/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -527,7 +527,7 @@ static void qnx4_destroy_inode(struct in kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); } -static void init_once(void *foo, kmem_cache_t * cachep, +static int init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; @@ -535,6 +535,7 @@ static void init_once(void *foo, kmem_ca if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/reiserfs/super.c wli-2.5.50-bk6-12/fs/reiserfs/super.c --- wli-2.5.50-bk6-11/fs/reiserfs/super.c 2002-11-27 14:35:59.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/reiserfs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -424,7 +424,7 @@ static void reiserfs_destroy_inode(struc kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *) foo; @@ -433,6 +433,7 @@ static void init_once(void * foo, kmem_c INIT_LIST_HEAD(&ei->i_prealloc_list) ; inode_init_once(&ei->vfs_inode); } + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/romfs/inode.c wli-2.5.50-bk6-12/fs/romfs/inode.c --- wli-2.5.50-bk6-11/fs/romfs/inode.c 2002-11-27 14:36:15.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/romfs/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -564,13 +564,14 @@ static void romfs_destroy_inode(struct i kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/smbfs/inode.c wli-2.5.50-bk6-12/fs/smbfs/inode.c --- wli-2.5.50-bk6-11/fs/smbfs/inode.c 2002-11-27 14:35:50.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/smbfs/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -66,13 +66,14 @@ static void smb_destroy_inode(struct ino kmem_cache_free(smb_inode_cachep, SMB_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct smb_inode_info *ei = (struct smb_inode_info *) foo; unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; if ((flags & flagmask) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/sysv/inode.c wli-2.5.50-bk6-12/fs/sysv/inode.c --- wli-2.5.50-bk6-11/fs/sysv/inode.c 2002-11-27 14:35:47.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/sysv/inode.c 2002-12-06 14:53:19.000000000 -0800 @@ -304,13 +304,14 @@ static void sysv_destroy_inode(struct in kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); } -static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags) +static int init_once(void *p, kmem_cache_t *cachep, unsigned long flags) { struct sysv_inode_info *si = (struct sysv_inode_info *)p; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&si->vfs_inode); + return 0; } struct super_operations sysv_sops = { diff -urpN wli-2.5.50-bk6-11/fs/udf/super.c wli-2.5.50-bk6-12/fs/udf/super.c --- wli-2.5.50-bk6-11/fs/udf/super.c 2002-11-27 14:36:14.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/udf/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -127,13 +127,14 @@ static void udf_destroy_inode(struct ino kmem_cache_free(udf_inode_cachep, UDF_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct udf_inode_info *ei = (struct udf_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/ufs/super.c wli-2.5.50-bk6-12/fs/ufs/super.c --- wli-2.5.50-bk6-11/fs/ufs/super.c 2002-11-27 14:35:46.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/ufs/super.c 2002-12-06 14:53:19.000000000 -0800 @@ -1015,13 +1015,14 @@ static void ufs_destroy_inode(struct ino kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/fs/xfs/linux/xfs_super.c wli-2.5.50-bk6-12/fs/xfs/linux/xfs_super.c --- wli-2.5.50-bk6-11/fs/xfs/linux/xfs_super.c 2002-12-06 13:44:47.000000000 -0800 +++ wli-2.5.50-bk6-12/fs/xfs/linux/xfs_super.c 2002-12-06 14:53:19.000000000 -0800 @@ -578,7 +578,7 @@ linvfs_destroy_inode( kmem_cache_free(linvfs_inode_cachep, LINVFS_GET_VP(inode)); } -STATIC void +STATIC int init_once( void *data, kmem_cache_t *cachep, @@ -589,6 +589,7 @@ init_once( if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(LINVFS_GET_IP(vp)); + return 0; } STATIC int diff -urpN wli-2.5.50-bk6-11/include/linux/slab.h wli-2.5.50-bk6-12/include/linux/slab.h --- wli-2.5.50-bk6-11/include/linux/slab.h 2002-11-27 14:36:23.000000000 -0800 +++ wli-2.5.50-bk6-12/include/linux/slab.h 2002-12-06 14:53:19.000000000 -0800 @@ -50,8 +50,8 @@ extern void kmem_cache_sizes_init(void); extern kmem_cache_t *kmem_find_general_cachep(size_t, int gfpflags); extern kmem_cache_t *kmem_cache_create(const char *, size_t, size_t, unsigned long, - void (*)(void *, kmem_cache_t *, unsigned long), - void (*)(void *, kmem_cache_t *, unsigned long)); + int (*ctor)(void *, kmem_cache_t *, unsigned long), + void (*dtor)(void *, kmem_cache_t *, unsigned long)); extern int kmem_cache_destroy(kmem_cache_t *); extern int kmem_cache_shrink(kmem_cache_t *); extern void *kmem_cache_alloc(kmem_cache_t *, int); diff -urpN wli-2.5.50-bk6-11/lib/radix-tree.c wli-2.5.50-bk6-12/lib/radix-tree.c --- wli-2.5.50-bk6-11/lib/radix-tree.c 2002-11-27 14:35:52.000000000 -0800 +++ wli-2.5.50-bk6-12/lib/radix-tree.c 2002-12-06 14:53:19.000000000 -0800 @@ -341,9 +341,10 @@ int radix_tree_delete(struct radix_tree_ } EXPORT_SYMBOL(radix_tree_delete); -static void radix_tree_node_ctor(void *node, kmem_cache_t *cachep, unsigned long flags) +static int radix_tree_node_ctor(void *node, kmem_cache_t *cachep, unsigned long flags) { memset(node, 0, sizeof(struct radix_tree_node)); + return 0; } static void *radix_tree_node_pool_alloc(int gfp_mask, void *data) diff -urpN wli-2.5.50-bk6-11/mm/rmap.c wli-2.5.50-bk6-12/mm/rmap.c --- wli-2.5.50-bk6-11/mm/rmap.c 2002-11-27 14:36:19.000000000 -0800 +++ wli-2.5.50-bk6-12/mm/rmap.c 2002-12-06 14:53:19.000000000 -0800 @@ -514,11 +514,12 @@ out: ** functions. **/ -static void pte_chain_ctor(void *p, kmem_cache_t *cachep, unsigned long flags) +static int pte_chain_ctor(void *p, kmem_cache_t *cachep, unsigned long flags) { struct pte_chain *pc = p; memset(pc, 0, sizeof(*pc)); + return 0; } void __init pte_chain_init(void) diff -urpN wli-2.5.50-bk6-11/mm/shmem.c wli-2.5.50-bk6-12/mm/shmem.c --- wli-2.5.50-bk6-11/mm/shmem.c 2002-11-27 14:35:59.000000000 -0800 +++ wli-2.5.50-bk6-12/mm/shmem.c 2002-12-06 14:53:19.000000000 -0800 @@ -1773,7 +1773,7 @@ static void shmem_destroy_inode(struct i kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); } -static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) +static int init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct shmem_inode_info *p = (struct shmem_inode_info *) foo; @@ -1781,6 +1781,7 @@ static void init_once(void *foo, kmem_ca SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&p->vfs_inode); } + return 0; } static int init_inodecache(void) diff -urpN wli-2.5.50-bk6-11/mm/slab.c wli-2.5.50-bk6-12/mm/slab.c --- wli-2.5.50-bk6-11/mm/slab.c 2002-12-06 13:44:48.000000000 -0800 +++ wli-2.5.50-bk6-12/mm/slab.c 2002-12-06 14:53:19.000000000 -0800 @@ -255,7 +255,7 @@ struct kmem_cache_s { unsigned int dflags; /* dynamic flags */ /* constructor func */ - void (*ctor)(void *, kmem_cache_t *, unsigned long); + int (*ctor)(void *, kmem_cache_t *, unsigned long); /* de-constructor func */ void (*dtor)(void *, kmem_cache_t *, unsigned long); @@ -822,6 +822,7 @@ static void slab_destroy (kmem_cache_t * * Cannot be called within a int, but can be interrupted. * The @ctor is run when new pages are allocated by the cache * and the @dtor is run before the pages are handed back. + * The @ctor must return 0 to indicate a successful initialization. * * @name must be valid until the cache is destroyed. This implies that * the module calling this has to destroy the cache before getting @@ -844,7 +845,7 @@ static void slab_destroy (kmem_cache_t * */ kmem_cache_t * kmem_cache_create (const char *name, size_t size, size_t offset, - unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long), + unsigned long flags, int (*ctor)(void*, kmem_cache_t *, unsigned long), void (*dtor)(void*, kmem_cache_t *, unsigned long)) { const char *func_nm = KERN_ERR "kmem_create: "; @@ -1256,7 +1257,7 @@ static inline kmem_bufctl_t *slab_bufctl return (kmem_bufctl_t *)(slabp+1); } -static void cache_init_objs (kmem_cache_t * cachep, +static int cache_init_objs (kmem_cache_t * cachep, struct slab * slabp, unsigned long ctor_flags) { int i; @@ -1279,8 +1280,10 @@ static void cache_init_objs (kmem_cache_ * the same cache which they are a constructor for. * Otherwise, deadlock. They must also be threaded. */ - if (cachep->ctor && !(cachep->flags & SLAB_POISON)) - cachep->ctor(objp, cachep, ctor_flags); + if (cachep->ctor && !(cachep->flags & SLAB_POISON)) { + if (cachep->ctor(objp, cachep, ctor_flags) != 0) + goto failed; + } if (cachep->flags & SLAB_RED_ZONE) { objp -= BYTES_PER_WORD; @@ -1291,13 +1294,29 @@ static void cache_init_objs (kmem_cache_ BUG(); } #else - if (cachep->ctor) - cachep->ctor(objp, cachep, ctor_flags); + if (cachep->ctor) { + if (cachep->ctor(objp, cachep, ctor_flags) != 0) + goto failed; + } #endif slab_bufctl(slabp)[i] = i+1; } slab_bufctl(slabp)[i-1] = BUFCTL_END; slabp->free = 0; + return 0; +failed: + if (cachep->dtor) { + i--; + for (;i >= 0;i--) { + void* objp = slabp->s_mem+cachep->objsize*i; +#if DEBUG + if (cachep->flags & SLAB_RED_ZONE) + objp += BYTES_PER_WORD; +#endif + cachep->dtor(objp, cachep, 0); + } + } + return -1; } static void kmem_flagcheck(kmem_cache_t *cachep, int flags) @@ -1388,7 +1407,8 @@ static int cache_grow (kmem_cache_t * ca page++; } while (--i); - cache_init_objs(cachep, slabp, ctor_flags); + if (cache_init_objs(cachep, slabp, ctor_flags) < 0) + goto opps2; if (local_flags & __GFP_WAIT) local_irq_disable(); @@ -1401,6 +1421,9 @@ static int cache_grow (kmem_cache_t * ca list3_data(cachep)->free_objects += cachep->num; spin_unlock(&cachep->spinlock); return 1; +opps2: + if (OFF_SLAB(cachep)) + kmem_cache_free(cachep->slabp_cache, slabp); opps1: kmem_freepages(cachep, objp); failed: @@ -1602,6 +1625,30 @@ static inline void cache_alloc_debugchec #endif } +#if DEBUG +/* + * Return an object to the slab lists if the ctor failed. + * Debug only, doesn't have to be efficient. + */ +static void cache_return_obj (kmem_cache_t *cachep, void *objp) +{ + unsigned long flags; + if (cachep->flags & SLAB_RED_ZONE) { + objp -= BYTES_PER_WORD; + /* Set alloc red-zone, and check old one. */ + if (xchg((unsigned long *)objp, RED_MAGIC1) != + RED_MAGIC2) + BUG(); + if (xchg((unsigned long *)(objp+cachep->objsize - + BYTES_PER_WORD), RED_MAGIC1) != RED_MAGIC2) + BUG(); + } + local_irq_save(flags); + free_block(cachep, &objp, 1); + local_irq_restore(flags); +} +#endif + static inline void *cache_alloc_debugcheck_after (kmem_cache_t *cachep, unsigned long flags, void *objp) { #if DEBUG @@ -1626,7 +1673,10 @@ static inline void *cache_alloc_debugche if (!flags & __GFP_WAIT) ctor_flags |= SLAB_CTOR_ATOMIC; - cachep->ctor(objp, cachep, ctor_flags); + if (cachep->ctor(objp, cachep, ctor_flags) != 0) { + cache_return_obj(cachep, objp); + objp = NULL; + } } #endif return objp; diff -urpN wli-2.5.50-bk6-11/net/core/skbuff.c wli-2.5.50-bk6-12/net/core/skbuff.c --- wli-2.5.50-bk6-11/net/core/skbuff.c 2002-11-27 14:36:16.000000000 -0800 +++ wli-2.5.50-bk6-12/net/core/skbuff.c 2002-12-06 14:53:19.000000000 -0800 @@ -225,7 +225,7 @@ nodata: /* * Slab constructor for a skb head. */ -static inline void skb_headerinit(void *p, kmem_cache_t *cache, +static inline int skb_headerinit(void *p, kmem_cache_t *cache, unsigned long flags) { struct sk_buff *skb = p; @@ -257,6 +257,7 @@ static inline void skb_headerinit(void * #ifdef CONFIG_NET_SCHED skb->tc_index = 0; #endif + return 0; } static void skb_drop_fraglist(struct sk_buff *skb) diff -urpN wli-2.5.50-bk6-11/net/socket.c wli-2.5.50-bk6-12/net/socket.c --- wli-2.5.50-bk6-11/net/socket.c 2002-11-27 14:35:56.000000000 -0800 +++ wli-2.5.50-bk6-12/net/socket.c 2002-12-06 14:53:19.000000000 -0800 @@ -299,13 +299,14 @@ static void sock_destroy_inode(struct in container_of(inode, struct socket_alloc, vfs_inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static int init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct socket_alloc *ei = (struct socket_alloc *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) inode_init_once(&ei->vfs_inode); + return 0; } static int init_inodecache(void)