jffs2: unlock f->sem on error in jffs2_new_inode()

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Sat Apr 5 02:59:03 EDT 2014


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=01887a3a2353f1c2fc7488b871d6df8055acb109
Commit:     01887a3a2353f1c2fc7488b871d6df8055acb109
Parent:     13b546d96207c131eeae15dc7b26c6e7d0f1cad7
Author:     Wang Guoli <andy.wangguoli at huawei.com>
AuthorDate: Wed Feb 12 12:44:54 2014 -0800
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Mar 10 22:42:28 2014 -0700

    jffs2: unlock f->sem on error in jffs2_new_inode()
    
    If jffs2_new_inode() succeeds, it returns with f->sem held, and the caller
    is responsible for releasing the lock.  If it fails, it still returns with
    the lock held, but the caller won't release the lock, which will lead to
    deadlock.
    
    Fix it by releasing the lock in jffs2_new_inode() on error.
    
    Signed-off-by: Wang Guoli <andy.wangguoli at huawei.com>
    Signed-off-by: Wang Nan <wangnan0 at huawei.com>
    Cc: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
    Cc: David Woodhouse <dwmw2 at infradead.org>
    Cc: Wang Guoli <andy.wangguoli at huawei.com>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    [Brian: not marked for stable; no one observed deadlock, and I don't
            think it can happen here]
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 fs/jffs2/fs.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index a69e426..560821b 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -457,12 +457,14 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r
 	   The umask is only applied if there's no default ACL */
 	ret = jffs2_init_acl_pre(dir_i, inode, &mode);
 	if (ret) {
-	    make_bad_inode(inode);
-	    iput(inode);
-	    return ERR_PTR(ret);
+		mutex_unlock(&f->sem);
+		make_bad_inode(inode);
+		iput(inode);
+		return ERR_PTR(ret);
 	}
 	ret = jffs2_do_new_inode (c, f, mode, ri);
 	if (ret) {
+		mutex_unlock(&f->sem);
 		make_bad_inode(inode);
 		iput(inode);
 		return ERR_PTR(ret);
@@ -479,6 +481,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r
 	inode->i_size = 0;
 
 	if (insert_inode_locked(inode) < 0) {
+		mutex_unlock(&f->sem);
 		make_bad_inode(inode);
 		iput(inode);
 		return ERR_PTR(-EINVAL);



More information about the linux-mtd-cvs mailing list