diff options
author | Wang Guoli <andy.wangguoli@huawei.com> | 2014-02-14 10:51:40 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2014-02-14 10:51:40 +1100 |
commit | fada9b25c665ba87aa2700c8ca4a350c8e9510ff (patch) | |
tree | c749b97f4d36d03c69e52d752606ede380364651 /fs/jffs2 | |
parent | 313b133e27f8f8701a499ed9d172124b715b4e77 (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>
Cc: Brian Norris <computersforpeace@gmail.com>
Cc: <stable@vger.kernel.org> # 2.6.34+
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/fs.c | 9 |
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); |