forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
13b546d962
commit
01887a3a23
|
@ -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 */
|
The umask is only applied if there's no default ACL */
|
||||||
ret = jffs2_init_acl_pre(dir_i, inode, &mode);
|
ret = jffs2_init_acl_pre(dir_i, inode, &mode);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
make_bad_inode(inode);
|
mutex_unlock(&f->sem);
|
||||||
iput(inode);
|
make_bad_inode(inode);
|
||||||
return ERR_PTR(ret);
|
iput(inode);
|
||||||
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
ret = jffs2_do_new_inode (c, f, mode, ri);
|
ret = jffs2_do_new_inode (c, f, mode, ri);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
mutex_unlock(&f->sem);
|
||||||
make_bad_inode(inode);
|
make_bad_inode(inode);
|
||||||
iput(inode);
|
iput(inode);
|
||||||
return ERR_PTR(ret);
|
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;
|
inode->i_size = 0;
|
||||||
|
|
||||||
if (insert_inode_locked(inode) < 0) {
|
if (insert_inode_locked(inode) < 0) {
|
||||||
|
mutex_unlock(&f->sem);
|
||||||
make_bad_inode(inode);
|
make_bad_inode(inode);
|
||||||
iput(inode);
|
iput(inode);
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user