On Sun 18-08-24 04:03:50, Harshad Shirwadkar wrote: > Mark inode dirty first and then grab i_data_sem in ext4_setattr(). > > Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@xxxxxxxxx> ... > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index e11f00ff8..c82eba178 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5489,12 +5489,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; Well, but this doesn't really work, does it? If you modify inode metadata *after* calling ext4_mark_inode_dirty() the new metadata will not be copied into the inode buffer and thus will not be written out... You can move the ext4_mark_inode_dirty() call to the point where i_data_sem is already released though. That is perfectly fine. Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR