[f2fs-dev] [PATCH 05/14] ext4: Convert to use mapping->invalidate_lock
Convert ext4 to use mapping->invalidate_lock instead of its private EXT4_I(inode)->i_mmap_sem. This is mostly search-and-replace. By this conversion we fix a long standing race between hole punching and read(2) / readahead(2) paths that can lead to stale page cache contents. CC: CC: Ted Tso Acked-by: Theodore Ts'o Reviewed-by: Darrick J. Wong Signed-off-by: Jan Kara --- fs/ext4/ext4.h | 10 -- fs/ext4/extents.c | 25 +--- fs/ext4/file.c | 13 +++-- fs/ext4/inode.c| 47 +- fs/ext4/ioctl.c| 4 ++-- fs/ext4/super.c| 13 + fs/ext4/truncate.h | 8 +--- 7 files changed, 50 insertions(+), 70 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 3c51e243450d..7ebaf66b6e31 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1086,15 +1086,6 @@ struct ext4_inode_info { * by other means, so we have i_data_sem. */ struct rw_semaphore i_data_sem; - /* -* i_mmap_sem is for serializing page faults with truncate / punch hole -* operations. We have to make sure that new page cannot be faulted in -* a section of the inode that is being punched. We cannot easily use -* i_data_sem for this since we need protection for the whole punch -* operation and i_data_sem ranks below transaction start so we have -* to occasionally drop it. -*/ - struct rw_semaphore i_mmap_sem; struct inode vfs_inode; struct jbd2_inode *jinode; @@ -2972,7 +2963,6 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, loff_t lstart, loff_t lend); extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); -extern vm_fault_t ext4_filemap_fault(struct vm_fault *vmf); extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); extern void ext4_da_release_space(struct inode *inode, int to_free); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 92ad64b89d9b..c33e0a2cb6c3 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4474,6 +4474,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, loff_t len, int mode) { struct inode *inode = file_inode(file); + struct address_space *mapping = file->f_mapping; handle_t *handle = NULL; unsigned int max_blocks; loff_t new_size = 0; @@ -4560,17 +4561,17 @@ static long ext4_zero_range(struct file *file, loff_t offset, * Prevent page faults from reinstantiating pages we have * released from page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } ret = ext4_update_disksize_before_punch(inode, offset, len); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } /* Now release the pages and zero block aligned part of pages */ @@ -4579,7 +4580,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags); - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); if (ret) goto out_mutex; } @@ -5221,6 +5222,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) { struct super_block *sb = inode->i_sb; + struct address_space *mapping = inode->i_mapping; ext4_lblk_t punch_start, punch_stop; handle_t *handle; unsigned int credits; @@ -5274,7 +5276,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Prevent page faults from reinstantiating pages we have released from * page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) @@ -5289,15 +5291,15 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Write tail of the last page before removed range since it will get * removed from the page cache below. */ - ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset); + ret =
[f2fs-dev] [PATCH 05/14] ext4: Convert to use mapping->invalidate_lock
Convert ext4 to use mapping->invalidate_lock instead of its private EXT4_I(inode)->i_mmap_sem. This is mostly search-and-replace. By this conversion we fix a long standing race between hole punching and read(2) / readahead(2) paths that can lead to stale page cache contents. CC: CC: Ted Tso Acked-by: Theodore Ts'o Reviewed-by: Darrick J. Wong Signed-off-by: Jan Kara --- fs/ext4/ext4.h | 10 -- fs/ext4/extents.c | 25 +--- fs/ext4/file.c | 13 +++-- fs/ext4/inode.c| 47 +- fs/ext4/ioctl.c| 4 ++-- fs/ext4/super.c| 13 + fs/ext4/truncate.h | 8 +--- 7 files changed, 50 insertions(+), 70 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 3c51e243450d..7ebaf66b6e31 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1086,15 +1086,6 @@ struct ext4_inode_info { * by other means, so we have i_data_sem. */ struct rw_semaphore i_data_sem; - /* -* i_mmap_sem is for serializing page faults with truncate / punch hole -* operations. We have to make sure that new page cannot be faulted in -* a section of the inode that is being punched. We cannot easily use -* i_data_sem for this since we need protection for the whole punch -* operation and i_data_sem ranks below transaction start so we have -* to occasionally drop it. -*/ - struct rw_semaphore i_mmap_sem; struct inode vfs_inode; struct jbd2_inode *jinode; @@ -2972,7 +2963,6 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, loff_t lstart, loff_t lend); extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); -extern vm_fault_t ext4_filemap_fault(struct vm_fault *vmf); extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); extern void ext4_da_release_space(struct inode *inode, int to_free); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 92ad64b89d9b..c33e0a2cb6c3 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4474,6 +4474,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, loff_t len, int mode) { struct inode *inode = file_inode(file); + struct address_space *mapping = file->f_mapping; handle_t *handle = NULL; unsigned int max_blocks; loff_t new_size = 0; @@ -4560,17 +4561,17 @@ static long ext4_zero_range(struct file *file, loff_t offset, * Prevent page faults from reinstantiating pages we have * released from page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } ret = ext4_update_disksize_before_punch(inode, offset, len); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } /* Now release the pages and zero block aligned part of pages */ @@ -4579,7 +4580,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags); - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); if (ret) goto out_mutex; } @@ -5221,6 +5222,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) { struct super_block *sb = inode->i_sb; + struct address_space *mapping = inode->i_mapping; ext4_lblk_t punch_start, punch_stop; handle_t *handle; unsigned int credits; @@ -5274,7 +5276,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Prevent page faults from reinstantiating pages we have released from * page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) @@ -5289,15 +5291,15 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Write tail of the last page before removed range since it will get * removed from the page cache below. */ - ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset); + ret =
Re: [f2fs-dev] [PATCH 05/14] ext4: Convert to use mapping->invalidate_lock
Sorry, forgot to send it out. Acked-by: Theodore Ts'o ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 05/14] ext4: Convert to use mapping->invalidate_lock
On Thu 17-06-21 09:22:40, Darrick J. Wong wrote: > On Tue, Jun 15, 2021 at 11:17:55AM +0200, Jan Kara wrote: > > Convert ext4 to use mapping->invalidate_lock instead of its private > > EXT4_I(inode)->i_mmap_sem. This is mostly search-and-replace. By this > > conversion we fix a long standing race between hole punching and read(2) > > / readahead(2) paths that can lead to stale page cache contents. > > > > CC: > > CC: Ted Tso > > Hmm, still no ACK from Ted? On ext4 call he mentioned he's fine with the patches and testing has passed for him but he has not given an official tag... > This looks like a pretty straightforward i_mmap_sem conversion, though > in general I'd like /some/ kind of response from anyone in the ext4 > community who has been writing code more recently than me... > > Reviewed-by: Darrick J. Wong Yeah, this was basically search-and-replace. Thanks for review! Honza > > --D > > > Signed-off-by: Jan Kara > > --- > > fs/ext4/ext4.h | 10 -- > > fs/ext4/extents.c | 25 +--- > > fs/ext4/file.c | 13 +++-- > > fs/ext4/inode.c| 47 +- > > fs/ext4/ioctl.c| 4 ++-- > > fs/ext4/super.c| 13 + > > fs/ext4/truncate.h | 8 +--- > > 7 files changed, 50 insertions(+), 70 deletions(-) > > > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > > index 37002663d521..ed64b4b217a1 100644 > > --- a/fs/ext4/ext4.h > > +++ b/fs/ext4/ext4.h > > @@ -1077,15 +1077,6 @@ struct ext4_inode_info { > > * by other means, so we have i_data_sem. > > */ > > struct rw_semaphore i_data_sem; > > - /* > > -* i_mmap_sem is for serializing page faults with truncate / punch hole > > -* operations. We have to make sure that new page cannot be faulted in > > -* a section of the inode that is being punched. We cannot easily use > > -* i_data_sem for this since we need protection for the whole punch > > -* operation and i_data_sem ranks below transaction start so we have > > -* to occasionally drop it. > > -*/ > > - struct rw_semaphore i_mmap_sem; > > struct inode vfs_inode; > > struct jbd2_inode *jinode; > > > > @@ -2962,7 +2953,6 @@ extern int ext4_chunk_trans_blocks(struct inode *, > > int nrblocks); > > extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, > > loff_t lstart, loff_t lend); > > extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); > > -extern vm_fault_t ext4_filemap_fault(struct vm_fault *vmf); > > extern qsize_t *ext4_get_reserved_space(struct inode *inode); > > extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); > > extern void ext4_da_release_space(struct inode *inode, int to_free); > > diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c > > index cbf37b2cf871..db5d38af9ba8 100644 > > --- a/fs/ext4/extents.c > > +++ b/fs/ext4/extents.c > > @@ -4470,6 +4470,7 @@ static long ext4_zero_range(struct file *file, loff_t > > offset, > > loff_t len, int mode) > > { > > struct inode *inode = file_inode(file); > > + struct address_space *mapping = file->f_mapping; > > handle_t *handle = NULL; > > unsigned int max_blocks; > > loff_t new_size = 0; > > @@ -4556,17 +4557,17 @@ static long ext4_zero_range(struct file *file, > > loff_t offset, > > * Prevent page faults from reinstantiating pages we have > > * released from page cache. > > */ > > - down_write(_I(inode)->i_mmap_sem); > > + filemap_invalidate_lock(mapping); > > > > ret = ext4_break_layouts(inode); > > if (ret) { > > - up_write(_I(inode)->i_mmap_sem); > > + filemap_invalidate_unlock(mapping); > > goto out_mutex; > > } > > > > ret = ext4_update_disksize_before_punch(inode, offset, len); > > if (ret) { > > - up_write(_I(inode)->i_mmap_sem); > > + filemap_invalidate_unlock(mapping); > > goto out_mutex; > > } > > /* Now release the pages and zero block aligned part of pages */ > > @@ -4575,7 +4576,7 @@ static long ext4_zero_range(struct file *file, loff_t > > offset, > > > > ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, > > flags); > > - up_write(_I(inode)->i_mmap_sem); > > + filemap_invalidate_unlock(mapping); > > if (ret) > > goto out_mutex; > > } > > @@ -5217,6 +5218,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t > > *handle, > > static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t > > len) > > { > > struct super_block *sb = inode->i_sb; > > + struct address_space *mapping =
Re: [f2fs-dev] [PATCH 05/14] ext4: Convert to use mapping->invalidate_lock
On Tue, Jun 15, 2021 at 11:17:55AM +0200, Jan Kara wrote: > Convert ext4 to use mapping->invalidate_lock instead of its private > EXT4_I(inode)->i_mmap_sem. This is mostly search-and-replace. By this > conversion we fix a long standing race between hole punching and read(2) > / readahead(2) paths that can lead to stale page cache contents. > > CC: > CC: Ted Tso Hmm, still no ACK from Ted? This looks like a pretty straightforward i_mmap_sem conversion, though in general I'd like /some/ kind of response from anyone in the ext4 community who has been writing code more recently than me... Reviewed-by: Darrick J. Wong --D > Signed-off-by: Jan Kara > --- > fs/ext4/ext4.h | 10 -- > fs/ext4/extents.c | 25 +--- > fs/ext4/file.c | 13 +++-- > fs/ext4/inode.c| 47 +- > fs/ext4/ioctl.c| 4 ++-- > fs/ext4/super.c| 13 + > fs/ext4/truncate.h | 8 +--- > 7 files changed, 50 insertions(+), 70 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index 37002663d521..ed64b4b217a1 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -1077,15 +1077,6 @@ struct ext4_inode_info { >* by other means, so we have i_data_sem. >*/ > struct rw_semaphore i_data_sem; > - /* > - * i_mmap_sem is for serializing page faults with truncate / punch hole > - * operations. We have to make sure that new page cannot be faulted in > - * a section of the inode that is being punched. We cannot easily use > - * i_data_sem for this since we need protection for the whole punch > - * operation and i_data_sem ranks below transaction start so we have > - * to occasionally drop it. > - */ > - struct rw_semaphore i_mmap_sem; > struct inode vfs_inode; > struct jbd2_inode *jinode; > > @@ -2962,7 +2953,6 @@ extern int ext4_chunk_trans_blocks(struct inode *, int > nrblocks); > extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, >loff_t lstart, loff_t lend); > extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); > -extern vm_fault_t ext4_filemap_fault(struct vm_fault *vmf); > extern qsize_t *ext4_get_reserved_space(struct inode *inode); > extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); > extern void ext4_da_release_space(struct inode *inode, int to_free); > diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c > index cbf37b2cf871..db5d38af9ba8 100644 > --- a/fs/ext4/extents.c > +++ b/fs/ext4/extents.c > @@ -4470,6 +4470,7 @@ static long ext4_zero_range(struct file *file, loff_t > offset, > loff_t len, int mode) > { > struct inode *inode = file_inode(file); > + struct address_space *mapping = file->f_mapping; > handle_t *handle = NULL; > unsigned int max_blocks; > loff_t new_size = 0; > @@ -4556,17 +4557,17 @@ static long ext4_zero_range(struct file *file, loff_t > offset, >* Prevent page faults from reinstantiating pages we have >* released from page cache. >*/ > - down_write(_I(inode)->i_mmap_sem); > + filemap_invalidate_lock(mapping); > > ret = ext4_break_layouts(inode); > if (ret) { > - up_write(_I(inode)->i_mmap_sem); > + filemap_invalidate_unlock(mapping); > goto out_mutex; > } > > ret = ext4_update_disksize_before_punch(inode, offset, len); > if (ret) { > - up_write(_I(inode)->i_mmap_sem); > + filemap_invalidate_unlock(mapping); > goto out_mutex; > } > /* Now release the pages and zero block aligned part of pages */ > @@ -4575,7 +4576,7 @@ static long ext4_zero_range(struct file *file, loff_t > offset, > > ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, >flags); > - up_write(_I(inode)->i_mmap_sem); > + filemap_invalidate_unlock(mapping); > if (ret) > goto out_mutex; > } > @@ -5217,6 +5218,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t > *handle, > static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t > len) > { > struct super_block *sb = inode->i_sb; > + struct address_space *mapping = inode->i_mapping; > ext4_lblk_t punch_start, punch_stop; > handle_t *handle; > unsigned int credits; > @@ -5270,7 +5272,7 @@ static int ext4_collapse_range(struct inode *inode, > loff_t offset, loff_t len) >* Prevent page faults from reinstantiating pages we have released from >* page cache. >*/ > - down_write(_I(inode)->i_mmap_sem); > + filemap_invalidate_lock(mapping); > > ret =
[f2fs-dev] [PATCH 05/14] ext4: Convert to use mapping->invalidate_lock
Convert ext4 to use mapping->invalidate_lock instead of its private EXT4_I(inode)->i_mmap_sem. This is mostly search-and-replace. By this conversion we fix a long standing race between hole punching and read(2) / readahead(2) paths that can lead to stale page cache contents. CC: CC: Ted Tso Signed-off-by: Jan Kara --- fs/ext4/ext4.h | 10 -- fs/ext4/extents.c | 25 +--- fs/ext4/file.c | 13 +++-- fs/ext4/inode.c| 47 +- fs/ext4/ioctl.c| 4 ++-- fs/ext4/super.c| 13 + fs/ext4/truncate.h | 8 +--- 7 files changed, 50 insertions(+), 70 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 37002663d521..ed64b4b217a1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1077,15 +1077,6 @@ struct ext4_inode_info { * by other means, so we have i_data_sem. */ struct rw_semaphore i_data_sem; - /* -* i_mmap_sem is for serializing page faults with truncate / punch hole -* operations. We have to make sure that new page cannot be faulted in -* a section of the inode that is being punched. We cannot easily use -* i_data_sem for this since we need protection for the whole punch -* operation and i_data_sem ranks below transaction start so we have -* to occasionally drop it. -*/ - struct rw_semaphore i_mmap_sem; struct inode vfs_inode; struct jbd2_inode *jinode; @@ -2962,7 +2953,6 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, loff_t lstart, loff_t lend); extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); -extern vm_fault_t ext4_filemap_fault(struct vm_fault *vmf); extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); extern void ext4_da_release_space(struct inode *inode, int to_free); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index cbf37b2cf871..db5d38af9ba8 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4470,6 +4470,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, loff_t len, int mode) { struct inode *inode = file_inode(file); + struct address_space *mapping = file->f_mapping; handle_t *handle = NULL; unsigned int max_blocks; loff_t new_size = 0; @@ -4556,17 +4557,17 @@ static long ext4_zero_range(struct file *file, loff_t offset, * Prevent page faults from reinstantiating pages we have * released from page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } ret = ext4_update_disksize_before_punch(inode, offset, len); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } /* Now release the pages and zero block aligned part of pages */ @@ -4575,7 +4576,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags); - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); if (ret) goto out_mutex; } @@ -5217,6 +5218,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) { struct super_block *sb = inode->i_sb; + struct address_space *mapping = inode->i_mapping; ext4_lblk_t punch_start, punch_stop; handle_t *handle; unsigned int credits; @@ -5270,7 +5272,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Prevent page faults from reinstantiating pages we have released from * page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) @@ -5285,15 +5287,15 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Write tail of the last page before removed range since it will get * removed from the page cache below. */ - ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset); + ret = filemap_write_and_wait_range(mapping, ioffset, offset);
[f2fs-dev] [PATCH 05/14] ext4: Convert to use mapping->invalidate_lock
Convert ext4 to use mapping->invalidate_lock instead of its private EXT4_I(inode)->i_mmap_sem. This is mostly search-and-replace. By this conversion we fix a long standing race between hole punching and read(2) / readahead(2) paths that can lead to stale page cache contents. CC: CC: Ted Tso Signed-off-by: Jan Kara --- fs/ext4/ext4.h | 10 -- fs/ext4/extents.c | 25 +--- fs/ext4/file.c | 13 +++-- fs/ext4/inode.c| 47 +- fs/ext4/ioctl.c| 4 ++-- fs/ext4/super.c| 13 + fs/ext4/truncate.h | 8 +--- 7 files changed, 50 insertions(+), 70 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 37002663d521..ed64b4b217a1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1077,15 +1077,6 @@ struct ext4_inode_info { * by other means, so we have i_data_sem. */ struct rw_semaphore i_data_sem; - /* -* i_mmap_sem is for serializing page faults with truncate / punch hole -* operations. We have to make sure that new page cannot be faulted in -* a section of the inode that is being punched. We cannot easily use -* i_data_sem for this since we need protection for the whole punch -* operation and i_data_sem ranks below transaction start so we have -* to occasionally drop it. -*/ - struct rw_semaphore i_mmap_sem; struct inode vfs_inode; struct jbd2_inode *jinode; @@ -2962,7 +2953,6 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, loff_t lstart, loff_t lend); extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); -extern vm_fault_t ext4_filemap_fault(struct vm_fault *vmf); extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); extern void ext4_da_release_space(struct inode *inode, int to_free); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 77c84d6f1af6..194b8af2b31d 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4467,6 +4467,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, loff_t len, int mode) { struct inode *inode = file_inode(file); + struct address_space *mapping = file->f_mapping; handle_t *handle = NULL; unsigned int max_blocks; loff_t new_size = 0; @@ -4553,17 +4554,17 @@ static long ext4_zero_range(struct file *file, loff_t offset, * Prevent page faults from reinstantiating pages we have * released from page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } ret = ext4_update_disksize_before_punch(inode, offset, len); if (ret) { - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); goto out_mutex; } /* Now release the pages and zero block aligned part of pages */ @@ -4572,7 +4573,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags); - up_write(_I(inode)->i_mmap_sem); + filemap_invalidate_unlock(mapping); if (ret) goto out_mutex; } @@ -5214,6 +5215,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) { struct super_block *sb = inode->i_sb; + struct address_space *mapping = inode->i_mapping; ext4_lblk_t punch_start, punch_stop; handle_t *handle; unsigned int credits; @@ -5267,7 +5269,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Prevent page faults from reinstantiating pages we have released from * page cache. */ - down_write(_I(inode)->i_mmap_sem); + filemap_invalidate_lock(mapping); ret = ext4_break_layouts(inode); if (ret) @@ -5282,15 +5284,15 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) * Write tail of the last page before removed range since it will get * removed from the page cache below. */ - ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset); + ret = filemap_write_and_wait_range(mapping, ioffset, offset);