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

login
register
mail settings
Submitter Wang Nan
Date Dec. 18, 2013, 3:05 a.m.
Message ID <1387335945-58945-1-git-send-email-wangnan0@huawei.com>
Download mbox | patch
Permalink /patch/302617/
State New
Headers show

Comments

Wang Nan - Dec. 18, 2013, 3:05 a.m.
From: Wang Guoli <andy.wangguoli@huawei.com>

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.

Cc: linux-mtd@lists.infradead.org
Signed-off-by: Wang Guoli <andy.wangguoli@huawei.com>
Signed-off-by: Wang Nan <wangnan0@huawei.com>

---
 fs/jffs2/fs.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Patch

diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 09b3ed4..2b91675 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -456,12 +456,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);
@@ -478,6 +480,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);