GFS2: Fix uninitialized VFS inode in gfs2_create_inode
When gfs2_create_inode() fails due to quota violation, the VFS inode is not completely uninitialized. This can cause a list corruption error. This patch correctly uninitializes the VFS inode when a quota violation occurs in the gfs2_create_inode codepath. Resolves: rhbz#1059808 Signed-off-by: Abhi Das <adas@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
Родитель
e9fb7c73a4
Коммит
059788039f
|
@ -371,6 +371,7 @@ enum {
|
|||
GIF_ALLOC_FAILED = 2,
|
||||
GIF_SW_PAGED = 3,
|
||||
GIF_ORDERED = 4,
|
||||
GIF_FREE_VFS_INODE = 5,
|
||||
};
|
||||
|
||||
struct gfs2_inode {
|
||||
|
|
|
@ -597,7 +597,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
|||
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||
struct gfs2_glock *io_gl;
|
||||
struct dentry *d;
|
||||
int error;
|
||||
int error, free_vfs_inode = 0;
|
||||
u32 aflags = 0;
|
||||
unsigned blocks = 1;
|
||||
struct gfs2_diradd da = { .bh = NULL, };
|
||||
|
@ -788,15 +788,16 @@ fail_free_acls:
|
|||
if (acl)
|
||||
posix_acl_release(acl);
|
||||
fail_free_vfs_inode:
|
||||
free_inode_nonrcu(inode);
|
||||
inode = NULL;
|
||||
free_vfs_inode = 1;
|
||||
fail_gunlock:
|
||||
gfs2_dir_no_add(&da);
|
||||
gfs2_glock_dq_uninit(ghs);
|
||||
if (inode && !IS_ERR(inode)) {
|
||||
clear_nlink(inode);
|
||||
mark_inode_dirty(inode);
|
||||
set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags);
|
||||
if (!free_vfs_inode)
|
||||
mark_inode_dirty(inode);
|
||||
set_bit(free_vfs_inode ? GIF_FREE_VFS_INODE : GIF_ALLOC_FAILED,
|
||||
&GFS2_I(inode)->i_flags);
|
||||
iput(inode);
|
||||
}
|
||||
fail:
|
||||
|
|
|
@ -1248,7 +1248,7 @@ static int gfs2_drop_inode(struct inode *inode)
|
|||
{
|
||||
struct gfs2_inode *ip = GFS2_I(inode);
|
||||
|
||||
if (inode->i_nlink) {
|
||||
if (!test_bit(GIF_FREE_VFS_INODE, &ip->i_flags) && inode->i_nlink) {
|
||||
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
|
||||
if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags))
|
||||
clear_nlink(inode);
|
||||
|
@ -1463,6 +1463,11 @@ static void gfs2_evict_inode(struct inode *inode)
|
|||
struct gfs2_holder gh;
|
||||
int error;
|
||||
|
||||
if (test_bit(GIF_FREE_VFS_INODE, &ip->i_flags)) {
|
||||
clear_inode(inode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inode->i_nlink || (sb->s_flags & MS_RDONLY))
|
||||
goto out;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче