Message ID | 20240529012003.4006535-4-harshadshirwadkar@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | Ext4 fast commit performance patch series | expand |
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@gmail.com> > --- > 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
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; + /* * We have to update i_size under i_data_sem together * with i_disksize to avoid races with writeback code
Mark inode dirty first and then grab i_data_sem in ext4_setattr(). Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@gmail.com> --- fs/ext4/inode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)