summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWang Guoli <andy.wangguoli@huawei.com>2014-02-12 12:44:54 -0800
committerBrian Norris <computersforpeace@gmail.com>2014-03-10 22:42:28 -0700
commit01887a3a2353f1c2fc7488b871d6df8055acb109 (patch)
tree77e1565fb98aac1f717cc2ef86638d340a0ea382
parent13b546d96207c131eeae15dc7b26c6e7d0f1cad7 (diff)
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@huawei.com> Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Wang Guoli <andy.wangguoli@huawei.com> Signed-off-by: Andrew Morton <akpm@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@gmail.com>
-rw-r--r--fs/jffs2/fs.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index a69e426435dd..560821bff038 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);