diff mbox series

[06/10] xfs: IOMAP_ZERO and IOMAP_UNSHARE already hold invalidate_lock

Message ID 20241008085939.266014-7-hch@lst.de (mailing list archive)
State Queued
Headers show
Series [01/10] iomap: factor out a iomap_last_written_block helper | expand

Commit Message

Christoph Hellwig Oct. 8, 2024, 8:59 a.m. UTC
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>
---
 fs/xfs/xfs_iomap.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

Comments

Darrick J. Wong Oct. 8, 2024, 5:39 p.m. UTC | #1
On Tue, Oct 08, 2024 at 10:59:17AM +0200, Christoph Hellwig wrote:
> 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>

Thanks for fixing the bug I reported,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/xfs_iomap.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 4fa4d66dc37761..17170d9b9ff78a 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;
>  }
>  
> -- 
> 2.45.2
> 
>
diff mbox series

Patch

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 4fa4d66dc37761..17170d9b9ff78a 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;
 }