[PATCH 2/2] xfs: convert extents in place for ZERO_RANGE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Rather than completely removing and re-allocating a range
during ZERO_RANGE fallocate calls, convert whole blocks in the
range using xfs_alloc_file_space(XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)
and then zero the edges with xfs_zero_range()

(Note that this changes the rounding direction of the
xfs_alloc_file_space range, because we only want to hit whole
blocks within the range.)

Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx>
---

<currently running fsx ad infinitum, so far so good>

diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 0a96c4d1718e..eae202bfe134 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1164,23 +1164,25 @@ xfs_zero_file_space(
 
 	blksize = 1 << mp->m_sb.sb_blocklog;
 
+	error = xfs_flush_unmap_range(ip, offset, len);
+	if (error)
+		return error;
 	/*
-	 * Punch a hole and prealloc the range. We use hole punch rather than
-	 * unwritten extent conversion for two reasons:
-	 *
-	 * 1.) Hole punch handles partial block zeroing for us.
-	 *
-	 * 2.) If prealloc returns ENOSPC, the file range is still zero-valued
-	 * by virtue of the hole punch.
+	 * Convert whole blocks in the range to unwritten, then call iomap
+	 * via xfs_zero_range to zero the range.  iomap will skip holes and
+	 * unwritten extents, and just zero the edges if needed.  If conversion
+	 * fails, iomap will simply write zeros to the whole range.
+	 * nb: always_cow doesn't support unwritten extents.
 	 */
-	error = xfs_free_file_space(ip, offset, len);
-	if (error || xfs_is_always_cow_inode(ip))
-		return error;
+	if (!xfs_is_always_cow_inode(ip))
+		xfs_alloc_file_space(ip, round_up(offset, blksize),
+				     round_down(offset + len, blksize) -
+				     round_up(offset, blksize),
+				     XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT);
 
-	return xfs_alloc_file_space(ip, round_down(offset, blksize),
-				     round_up(offset + len, blksize) -
-				     round_down(offset, blksize),
-				     XFS_BMAPI_PREALLOC);
+	error = xfs_zero_range(ip, offset, len);
+
+	return error;
 }
 
 static int




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux