Patch "ext4: fix races of writeback with punch hole and zero range" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ext4: fix races of writeback with punch hole and zero range
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ext4-fix-races-of-writeback-with-punch-hole-and-zero-range.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
011278485ecc3cd2a3954b5d4c73101d919bf1faMon Sep 17 00:00:00 2001
From: Jan Kara <[email protected]>
Date: Mon, 7 Dec 2015 14:34:49 -0500
Subject: ext4: fix races of writeback with punch hole and zero range
From: Jan Kara <[email protected]>
commit 011278485ecc3cd2a3954b5d4c73101d919bf1fa upstream.
When doing delayed allocation, update of on-disk inode size is postponed until IO submission time. However hole punch or zero range fallocate calls can end up discarding the tail page cache page and thus on-disk inode size would never be properly updated.
Make sure the on-disk inode size is updated before truncating page cache.
--- fs/ext4/ext4.h | 3 +++ fs/ext4/extents.c | 5 +++++ fs/ext4/inode.c | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-)
fs/ext4/ext4.h +3 -0
@@ -2881,6 +2881,9 @@ static inline int ext4_update_inode_sizereturn changed; } +int ext4_update_disksize_before_punch (struct inode *inode,loff_t offset, +loff_t len); +struct ext4_group_info {unsigned long bb_state;struct rb_root bb_free_root;
fs/ext4/extents.c +5 -0
@@ -4847,6 +4847,11 @@ static long ext4_zero_range(struct file* released from page cache. */ down_write (&EXT4_I (inode)->i_mmap_sem); + ret =ext4_update_disksize_before_punch (inode, offset, len); +if (ret) { +up_write (&EXT4_I (inode)->i_mmap_sem); + goto out_dio; + }/* Now release the pages and zero block aligned part of pages */ truncate_pagecache_range (inode, start, end -1 ); inode->i_mtime = inode->i_ctime =ext4_current_time (inode);
fs/ext4/inode.c +34 -1
@@ -3587,6 +3587,35 @@ int ext4_can_truncate(struct inode *inod }/* +* We have to make sure i_disksize gets properly updated before we truncate +* page cache due to hole punching or zero range. Otherwise i_disksize update +* can get lost as it may have been postponed to submission of writeback but +* that will never happen after we truncate page cache. +*/ +int ext4_update_disksize_before_punch (struct inode *inode,loff_t offset, +loff_t len) +{ +handle_t *handle; +loff_t size =i_size_read (inode); + +WARN_ON (!mutex_is_locked (&inode->i_mutex)); +if (offset > size || offset + len < size) +return 0 ; + +if (EXT4_I (inode)->i_disksize >= size) +return 0 ; + + handle =ext4_journal_start (inode,EXT4_HT_MISC ,1 ); +if (IS_ERR (handle)) +return PTR_ERR (handle); +ext4_update_i_disksize (inode, size); +ext4_mark_inode_dirty (handle, inode); +ext4_journal_stop (handle); + +return 0 ; +} + +/* * ext4_punch_hole: punches a hole in a file by releaseing the blocks * associated with the given offset and length *
@@ -3664,9 +3693,13 @@ int ext4_punch_hole(struct inode *inode, last_block_offset =round_down ((offset + length), sb->s_blocksize) -1 ;/* Now release the pages and zero block aligned part of pages*/ -if (last_block_offset > first_block_offset) +if (last_block_offset > first_block_offset) { + ret =ext4_update_disksize_before_punch (inode, offset, length); +if (ret) + goto out_dio;truncate_pagecache_range (inode, first_block_offset, last_block_offset); + }if (ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )) credits =ext4_writepage_trans_blocks (inode);
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/ext4-fix-races-between-page-faults-and-hole-punching.patch queue-4.4/ext4-move-unlocked-dio-protection-from-ext4_alloc_file_blocks.patch queue-4.4/ext4-fix-races-between-buffered-io-and-collapse-insert-range.patch queue-4.4/ext4-fix-races-of-writeback-with-punch-hole-and-zero-range.patch