gfs2: Fix uninitialized VFS inode in gfs2_create_inode
PATCH 1/1 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 <[email protected]>
--- fs/gfs2/incore.h | 1 + fs/gfs2/inode.c | 11 ++++++----- fs/gfs2/super.c | 7 ++++++- 3 files changed, 13 insertions(+), 6 deletions(-)
fs/gfs2/incore.h +1 -0
@@ -371,6 +371,7 @@ enum {GIF_ALLOC_FAILED =2 ,GIF_SW_PAGED =3 ,GIF_ORDERED =4 , + GIF_FREE_VFS_INODE = 5, }; struct gfs2_inode {
fs/gfs2/inode.c +6 -5
@@ -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:
fs/gfs2/super.c +6 -1
@@ -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;
Signature · 1 line
1.8.1.4