提交 40ac218f 编写于 作者: S Steven Whitehouse

GFS2: Fix inode allocation error path

If we have got far enough through the inode allocation code
path that an inode has already been allocated, then we must
call iput to dispose of it, if an error occurs during a
later part of the process. This will always be the final iput
since there will be no other references to the inode.

Unlike when the inode has been unlinked, its block state will
be GFS2_BLKST_INODE rather than GFS2_BLKST_UNLINKED so we need
to skip the test in ->evict_inode() for this one case in order
to ensure that it will be deallocated correctly. This patch adds
a new flag in order to ensure that this will happen correctly.
Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
上级 1d4ec642
...@@ -267,6 +267,7 @@ struct gfs2_alloc { ...@@ -267,6 +267,7 @@ struct gfs2_alloc {
enum { enum {
GIF_INVALID = 0, GIF_INVALID = 0,
GIF_QD_LOCKED = 1, GIF_QD_LOCKED = 1,
GIF_ALLOC_FAILED = 2,
GIF_SW_PAGED = 3, GIF_SW_PAGED = 3,
}; };
......
...@@ -736,10 +736,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -736,10 +736,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
fail_gunlock2: fail_gunlock2:
gfs2_glock_dq_uninit(ghs + 1); gfs2_glock_dq_uninit(ghs + 1);
if (inode && !IS_ERR(inode))
iput(inode);
fail_gunlock: fail_gunlock:
gfs2_glock_dq_uninit(ghs); gfs2_glock_dq_uninit(ghs);
if (inode && !IS_ERR(inode)) {
set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags);
iput(inode);
}
fail: fail:
if (bh) if (bh)
brelse(bh); brelse(bh);
......
...@@ -1471,9 +1471,11 @@ static void gfs2_evict_inode(struct inode *inode) ...@@ -1471,9 +1471,11 @@ static void gfs2_evict_inode(struct inode *inode)
goto out; goto out;
} }
error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED); if (!test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) {
if (error) error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED);
goto out_truncate; if (error)
goto out_truncate;
}
if (test_bit(GIF_INVALID, &ip->i_flags)) { if (test_bit(GIF_INVALID, &ip->i_flags)) {
error = gfs2_inode_refresh(ip); error = gfs2_inode_refresh(ip);
...@@ -1513,6 +1515,10 @@ static void gfs2_evict_inode(struct inode *inode) ...@@ -1513,6 +1515,10 @@ static void gfs2_evict_inode(struct inode *inode)
goto out_unlock; goto out_unlock;
out_truncate: out_truncate:
gfs2_log_flush(sdp, ip->i_gl);
write_inode_now(inode, 1);
gfs2_ail_flush(ip->i_gl);
/* Case 2 starts here */ /* Case 2 starts here */
error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
if (error) if (error)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册