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: stable@vger.kernel.org
Fixes: a4bb6b64e39abc0e41ca077725f2a72c868e7622
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by Jan Kara and committed by Theodore Ts'o 67a7d5f5 a056bdaa

Changed files
+7
fs
+5
fs/ext4/extents.c
··· 4877 4877 4878 4878 /* Zero out partial block at the edges of the range */ 4879 4879 ret = ext4_zero_partial_blocks(handle, inode, offset, len); 4880 + if (ret >= 0) 4881 + ext4_update_inode_fsync_trans(handle, inode, 1); 4880 4882 4881 4883 if (file->f_flags & O_SYNC) 4882 4884 ext4_handle_sync(handle); ··· 5565 5563 ext4_handle_sync(handle); 5566 5564 inode->i_mtime = inode->i_ctime = current_time(inode); 5567 5565 ext4_mark_inode_dirty(handle, inode); 5566 + ext4_update_inode_fsync_trans(handle, inode, 1); 5568 5567 5569 5568 out_stop: 5570 5569 ext4_journal_stop(handle); ··· 5739 5736 up_write(&EXT4_I(inode)->i_data_sem); 5740 5737 if (IS_SYNC(inode)) 5741 5738 ext4_handle_sync(handle); 5739 + if (ret >= 0) 5740 + ext4_update_inode_fsync_trans(handle, inode, 1); 5742 5741 5743 5742 out_stop: 5744 5743 ext4_journal_stop(handle);
+2
fs/ext4/inode.c
··· 4218 4218 4219 4219 inode->i_mtime = inode->i_ctime = current_time(inode); 4220 4220 ext4_mark_inode_dirty(handle, inode); 4221 + if (ret >= 0) 4222 + ext4_update_inode_fsync_trans(handle, inode, 1); 4221 4223 out_stop: 4222 4224 ext4_journal_stop(handle); 4223 4225 out_dio: