Skip to content

Commit 67a7d5f

Browse files
jankaratytso
authored andcommitted
ext4: fix fdatasync(2) after extent manipulation operations
Currently, extent manipulation operations such as hole punch, range zeroing, or extent shifting do not record the fact that file data has changed and thus fdatasync(2) has a work to do. As a result if we crash e.g. after a punch hole and fdatasync, user can still possibly see the punched out data after journal replay. Test generic/392 fails due to these problems. Fix the problem by properly marking that file data has changed in these operations. CC: [email protected] Fixes: a4bb6b6 Signed-off-by: Jan Kara <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]>
1 parent a056bda commit 67a7d5f

File tree

2 files changed

+7
-0
lines changed

2 files changed

+7
-0
lines changed

fs/ext4/extents.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4877,6 +4877,8 @@ static long ext4_zero_range(struct file *file, loff_t offset,
48774877

48784878
/* Zero out partial block at the edges of the range */
48794879
ret = ext4_zero_partial_blocks(handle, inode, offset, len);
4880+
if (ret >= 0)
4881+
ext4_update_inode_fsync_trans(handle, inode, 1);
48804882

48814883
if (file->f_flags & O_SYNC)
48824884
ext4_handle_sync(handle);
@@ -5563,6 +5565,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
55635565
ext4_handle_sync(handle);
55645566
inode->i_mtime = inode->i_ctime = current_time(inode);
55655567
ext4_mark_inode_dirty(handle, inode);
5568+
ext4_update_inode_fsync_trans(handle, inode, 1);
55665569

55675570
out_stop:
55685571
ext4_journal_stop(handle);
@@ -5736,6 +5739,8 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
57365739
up_write(&EXT4_I(inode)->i_data_sem);
57375740
if (IS_SYNC(inode))
57385741
ext4_handle_sync(handle);
5742+
if (ret >= 0)
5743+
ext4_update_inode_fsync_trans(handle, inode, 1);
57395744

57405745
out_stop:
57415746
ext4_journal_stop(handle);

fs/ext4/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4218,6 +4218,8 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
42184218

42194219
inode->i_mtime = inode->i_ctime = current_time(inode);
42204220
ext4_mark_inode_dirty(handle, inode);
4221+
if (ret >= 0)
4222+
ext4_update_inode_fsync_trans(handle, inode, 1);
42214223
out_stop:
42224224
ext4_journal_stop(handle);
42234225
out_dio:

0 commit comments

Comments
 (0)