| From: Joseph Qi <joseph.qi@linux.alibaba.com> |
| Subject: ocfs2: fix BUG when iput after ocfs2_mknod fails |
| Date: Mon, 17 Oct 2022 21:02:26 +0800 |
| |
| Commit b1529a41f777 "ocfs2: should reclaim the inode if |
| '__ocfs2_mknod_locked' returns an error" tried to reclaim the claimed |
| inode if __ocfs2_mknod_locked() fails later. But this introduce a race, |
| the freed bit may be reused immediately by another thread, which will |
| update dinode, e.g. i_generation. Then iput this inode will lead to BUG: |
| inode->i_generation != le32_to_cpu(fe->i_generation) |
| |
| We could make this inode as bad, but we did want to do operations like |
| wipe in some cases. Since the claimed inode bit can only affect that an |
| dinode is missing and will return back after fsck, it seems not a big |
| problem. So just leave it as is by revert the reclaim logic. |
| |
| Link: https://lkml.kernel.org/r/20221017130227.234480-1-joseph.qi@linux.alibaba.com |
| Fixes: b1529a41f777 ("ocfs2: should reclaim the inode if '__ocfs2_mknod_locked' returns an error") |
| Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com> |
| Reported-by: Yan Wang <wangyan122@huawei.com> |
| Cc: Mark Fasheh <mark@fasheh.com> |
| Cc: Joel Becker <jlbec@evilplan.org> |
| Cc: Junxiao Bi <junxiao.bi@oracle.com> |
| Cc: Changwei Ge <gechangwei@live.cn> |
| Cc: Gang He <ghe@suse.com> |
| Cc: Jun Piao <piaojun@huawei.com> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| fs/ocfs2/namei.c | 11 +---------- |
| 1 file changed, 1 insertion(+), 10 deletions(-) |
| |
| --- a/fs/ocfs2/namei.c~ocfs2-fix-bug-when-iput-after-ocfs2_mknod-fails |
| +++ a/fs/ocfs2/namei.c |
| @@ -632,18 +632,9 @@ static int ocfs2_mknod_locked(struct ocf |
| return status; |
| } |
| |
| - status = __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, |
| + return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, |
| parent_fe_bh, handle, inode_ac, |
| fe_blkno, suballoc_loc, suballoc_bit); |
| - if (status < 0) { |
| - u64 bg_blkno = ocfs2_which_suballoc_group(fe_blkno, suballoc_bit); |
| - int tmp = ocfs2_free_suballoc_bits(handle, inode_ac->ac_inode, |
| - inode_ac->ac_bh, suballoc_bit, bg_blkno, 1); |
| - if (tmp) |
| - mlog_errno(tmp); |
| - } |
| - |
| - return status; |
| } |
| |
| static int ocfs2_mkdir(struct user_namespace *mnt_userns, |
| _ |