From: Christoph Hellwig Date: Tue, 8 Oct 2024 08:59:17 +0000 (+0200) Subject: xfs: IOMAP_ZERO and IOMAP_UNSHARE already hold invalidate_lock X-Git-Tag: v6.12-rc4~23^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=abd7d651ad2cd2ab1b8cd4dd31e80a8255196db3;p=thirdparty%2Flinux.git 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 Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 4fa4d66dc3776..17170d9b9ff78 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; }