summaryrefslogtreecommitdiff
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2024-10-08 10:59:17 +0200
committerCarlos Maiolino <cem@kernel.org>2024-10-15 11:37:42 +0200
commitabd7d651ad2cd2ab1b8cd4dd31e80a8255196db3 (patch)
treed1d5622a1f2e215af11a5a88ce7578e0b0c9df2f /fs/xfs
parentacfbac776496f2093e9facf7876b4015ef8c3d1d (diff)
xfs: IOMAP_ZERO and IOMAP_UNSHARE already hold invalidate_lock
All XFS callers of iomap_zero_range and iomap_file_unshare already hold invalidate_lock, so we can't take it again in iomap_file_buffered_write_punch_delalloc. Use the passed in flags argument to detect if we're called from a zero or unshare operation and don't take the lock again in this case. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_iomap.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 4fa4d66dc377..17170d9b9ff7 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1239,10 +1239,18 @@ xfs_buffered_write_iomap_end(
if (start_byte >= end_byte)
return 0;
- filemap_invalidate_lock(inode->i_mapping);
- iomap_write_delalloc_release(inode, start_byte, end_byte, flags, iomap,
- xfs_buffered_write_delalloc_punch);
- filemap_invalidate_unlock(inode->i_mapping);
+ /* For zeroing operations the callers already hold invalidate_lock. */
+ if (flags & (IOMAP_UNSHARE | IOMAP_ZERO)) {
+ rwsem_assert_held_write(&inode->i_mapping->invalidate_lock);
+ iomap_write_delalloc_release(inode, start_byte, end_byte, flags,
+ iomap, xfs_buffered_write_delalloc_punch);
+ } else {
+ filemap_invalidate_lock(inode->i_mapping);
+ iomap_write_delalloc_release(inode, start_byte, end_byte, flags,
+ iomap, xfs_buffered_write_delalloc_punch);
+ filemap_invalidate_unlock(inode->i_mapping);
+ }
+
return 0;
}