forked from Minki/linux
ocfs2: clear dinode links count in case of error
In ocfs2_mknod(), if error occurs after dinode successfully allocated, ocfs2 i_links_count will not be 0. So even though we clear inode i_nlink before iput in error handling, it still won't wipe inode since we'll refresh inode from dinode during inode lock. So just like clear inode i_nlink, we clear ocfs2 i_links_count as well. Also do the same change for ocfs2_symlink(). Link: https://lkml.kernel.org/r/20221017130227.234480-2-joseph.qi@linux.alibaba.com 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>
This commit is contained in:
parent
759a7c6126
commit
28f4821b1b
@ -232,6 +232,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns,
|
|||||||
handle_t *handle = NULL;
|
handle_t *handle = NULL;
|
||||||
struct ocfs2_super *osb;
|
struct ocfs2_super *osb;
|
||||||
struct ocfs2_dinode *dirfe;
|
struct ocfs2_dinode *dirfe;
|
||||||
|
struct ocfs2_dinode *fe = NULL;
|
||||||
struct buffer_head *new_fe_bh = NULL;
|
struct buffer_head *new_fe_bh = NULL;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
struct ocfs2_alloc_context *inode_ac = NULL;
|
struct ocfs2_alloc_context *inode_ac = NULL;
|
||||||
@ -382,6 +383,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
|
||||||
if (S_ISDIR(mode)) {
|
if (S_ISDIR(mode)) {
|
||||||
status = ocfs2_fill_new_dir(osb, handle, dir, inode,
|
status = ocfs2_fill_new_dir(osb, handle, dir, inode,
|
||||||
new_fe_bh, data_ac, meta_ac);
|
new_fe_bh, data_ac, meta_ac);
|
||||||
@ -454,8 +456,11 @@ roll_back:
|
|||||||
leave:
|
leave:
|
||||||
if (status < 0 && did_quota_inode)
|
if (status < 0 && did_quota_inode)
|
||||||
dquot_free_inode(inode);
|
dquot_free_inode(inode);
|
||||||
if (handle)
|
if (handle) {
|
||||||
|
if (status < 0 && fe)
|
||||||
|
ocfs2_set_links_count(fe, 0);
|
||||||
ocfs2_commit_trans(osb, handle);
|
ocfs2_commit_trans(osb, handle);
|
||||||
|
}
|
||||||
|
|
||||||
ocfs2_inode_unlock(dir, 1);
|
ocfs2_inode_unlock(dir, 1);
|
||||||
if (did_block_signals)
|
if (did_block_signals)
|
||||||
@ -2019,8 +2024,11 @@ bail:
|
|||||||
ocfs2_clusters_to_bytes(osb->sb, 1));
|
ocfs2_clusters_to_bytes(osb->sb, 1));
|
||||||
if (status < 0 && did_quota_inode)
|
if (status < 0 && did_quota_inode)
|
||||||
dquot_free_inode(inode);
|
dquot_free_inode(inode);
|
||||||
if (handle)
|
if (handle) {
|
||||||
|
if (status < 0 && fe)
|
||||||
|
ocfs2_set_links_count(fe, 0);
|
||||||
ocfs2_commit_trans(osb, handle);
|
ocfs2_commit_trans(osb, handle);
|
||||||
|
}
|
||||||
|
|
||||||
ocfs2_inode_unlock(dir, 1);
|
ocfs2_inode_unlock(dir, 1);
|
||||||
if (did_block_signals)
|
if (did_block_signals)
|
||||||
|
Loading…
Reference in New Issue
Block a user