On Wed 29-05-24 01:19:56, Harshad Shirwadkar wrote: > Mark inode dirty first and then grab i_data_sem in ext4_setattr(). > > Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@xxxxxxxxx> > --- > fs/ext4/inode.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index aa6440992a55..61ffbdc2fb16 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5410,12 +5410,13 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, > (attr->ia_size > 0 ? attr->ia_size - 1 : 0) >> > inode->i_sb->s_blocksize_bits); > > - down_write(&EXT4_I(inode)->i_data_sem); > - old_disksize = EXT4_I(inode)->i_disksize; > - EXT4_I(inode)->i_disksize = attr->ia_size; > rc = ext4_mark_inode_dirty(handle, inode); > if (!error) > error = rc; > + down_write(&EXT4_I(inode)->i_data_sem); > + old_disksize = EXT4_I(inode)->i_disksize; > + EXT4_I(inode)->i_disksize = attr->ia_size; > + This is wrong. ext4_mark_inode_dirty() will copy the data to on-disk buffer. If you set i_disksize after ext4_mark_inode_dirty(), the change will not get properly logged in the transaction. What you rather need is calling ext4_mark_inode_dirty() after dropping i_data_sem which should be completely fine. Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR