[JFFS2] Fix the slab cache constructor of 'struct jffs2_inode_info' objects.
authorThomas Gleixner <tglx@mtd.linutronix.de>
Tue, 29 Nov 2005 15:57:17 +0000 (16:57 +0100)
committerThomas Gleixner <tglx@mtd.linutronix.de>
Tue, 29 Nov 2005 15:57:17 +0000 (16:57 +0100)
JFFS2 initialize f->sem mutex as "locked" in the slab constructor which is a
bug. Objects are freed with unlocked f->sem mutex. So, when they allocated
again, f->sem is unlocked because the slab cache constructor is not called for
them. The constructor is called only once when memory pages are allocated for
objects (namely, when the slab layer allocates new slabs). So, sometimes
'struct jffs2_inode_info' are allocated with unlocked f->sem, sometimes with
locked. This is a bug. Instead, initialize f->sem as unlocked in the
constructor. I.e., in the "constructed" state f->sem must be unlocked.

From: Keijiro Yano <keijiro_yano@yahoo.co.jp>
Acked-by: Artem B. Bityutskiy <dedekind@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
fs/jffs2/fs.c
fs/jffs2/super.c

index 543420665c5be2f641eacc6fa52062b15b4bcd0f..d0fcc5f3497ed1e757f6b420b78d3ba7193c3c3d 100644 (file)
@@ -234,6 +234,7 @@ void jffs2_read_inode (struct inode *inode)
        c = JFFS2_SB_INFO(inode->i_sb);
 
        jffs2_init_inode_info(f);
+       down(&f->sem);
 
        ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
 
@@ -400,6 +401,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
 
        f = JFFS2_INODE_INFO(inode);
        jffs2_init_inode_info(f);
+       down(&f->sem);
 
        memset(ri, 0, sizeof(*ri));
        /* Set OS-specific defaults for new inodes */
index 9e0b5458d9c072bc76e4fa6825e2b02163e4e0c4..93883817cbd0332df2d2e2652c7781baece90cde 100644 (file)
@@ -51,7 +51,7 @@ static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long f
 
        if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
            SLAB_CTOR_CONSTRUCTOR) {
-               init_MUTEX_LOCKED(&ei->sem);
+               init_MUTEX(&ei->sem);
                inode_init_once(&ei->vfs_inode);
        }
 }