From: Darrick J. Wong <djwong@xxxxxxxxxx> For files on the XFS realtime volume, it's possible that the file allocation unit (aka the minimum size we have to punch to deallocate file blocks) could be greater than a single fs block. This utility assumed that it's always possible to punch a single fs block, but for these types of files, all that does is zeroes the page cache. While that's what most *user applications* want, fstests uses punching to fragment file mapping metadata and/or fragment free space, so adapt this test for that purpose by detecting realtime files. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- src/punch-alternating.c | 28 +++++++++++++++++++++++++++- tests/xfs/114 | 4 ++++ tests/xfs/146 | 2 +- tests/xfs/187 | 3 ++- tests/xfs/341 | 4 ++-- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/punch-alternating.c b/src/punch-alternating.c index 18dd215197db2b..d2bb4b6a2276c9 100644 --- a/src/punch-alternating.c +++ b/src/punch-alternating.c @@ -20,6 +20,28 @@ void usage(char *cmd) exit(1); } +/* Compute the file allocation unit size for an XFS file. */ +static int detect_xfs_alloc_unit(int fd) +{ + struct fsxattr fsx; + struct xfs_fsop_geom fsgeom; + int ret; + + ret = ioctl(fd, XFS_IOC_FSGEOMETRY, &fsgeom); + if (ret) + return -1; + + ret = ioctl(fd, XFS_IOC_FSGETXATTR, &fsx); + if (ret) + return -1; + + ret = fsgeom.blocksize; + if (fsx.fsx_xflags & XFS_XFLAG_REALTIME) + ret *= fsgeom.rtextsize; + + return ret; +} + int main(int argc, char *argv[]) { struct stat s; @@ -82,7 +104,11 @@ int main(int argc, char *argv[]) goto err; sz = s.st_size; - blksz = sf.f_bsize; + c = detect_xfs_alloc_unit(fd); + if (c > 0) + blksz = c; + else + blksz = sf.f_bsize; mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE; for (offset = start_offset * blksz; diff --git a/tests/xfs/114 b/tests/xfs/114 index 510d31a4028598..f764cad73babb7 100755 --- a/tests/xfs/114 +++ b/tests/xfs/114 @@ -47,6 +47,10 @@ $XFS_IO_PROG -f \ -c "pwrite -S 0x68 -b 1048576 0 $len2" \ $SCRATCH_MNT/f2 >> $seqres.full +# The arguments to punch-alternating must be specified in units of file +# allocation units, so we divide the argument by $file_blksz. We already +# verified that $blksz is congruent with $file_blksz, so the fpunch parameters +# will always align with the file allocation unit. $here/src/punch-alternating -o $((16 * blksz / file_blksz)) \ -s $((blksz / file_blksz)) \ -i $((blksz * 2 / file_blksz)) \ diff --git a/tests/xfs/146 b/tests/xfs/146 index b6f4c2bd093d45..1cd7076d2426ee 100755 --- a/tests/xfs/146 +++ b/tests/xfs/146 @@ -67,7 +67,7 @@ _xfs_force_bdev realtime $SCRATCH_MNT # Allocate some stuff at the start, to force the first falloc of the ouch file # to happen somewhere in the middle of the rt volume $XFS_IO_PROG -f -c 'falloc 0 64m' "$SCRATCH_MNT/b" -$here/src/punch-alternating -i $((rextblks * 2)) -s $((rextblks)) "$SCRATCH_MNT/b" +$here/src/punch-alternating "$SCRATCH_MNT/b" avail="$(df -P "$SCRATCH_MNT" | awk 'END {print $4}')"1 toobig="$((avail * 2))" diff --git a/tests/xfs/187 b/tests/xfs/187 index 56a9adc164eab2..1d32d702f629c9 100755 --- a/tests/xfs/187 +++ b/tests/xfs/187 @@ -130,7 +130,8 @@ $XFS_IO_PROG -f -c "truncate $required_sz" -c "falloc 0 $remap_sz" $SCRATCH_MNT/ # Punch out every other extent of the last two sections, to fragment free space. frag_sz=$((remap_sz * 3)) punch_off=$((bigfile_sz - frag_sz)) -$here/src/punch-alternating $SCRATCH_MNT/bigfile -o $((punch_off / fsbsize)) -i $((rtextsize_blks * 2)) -s $rtextsize_blks +rtextsize_bytes=$((fsbsize * rtextsize_blks)) +$here/src/punch-alternating $SCRATCH_MNT/bigfile -o $((punch_off / rtextsize_bytes)) # Make sure we have some free rtextents. free_rtx=$(_xfs_statfs_field "$SCRATCH_MNT" statfs.f_bavail) diff --git a/tests/xfs/341 b/tests/xfs/341 index 6e25549b2b3d08..9b12febf8d5c49 100755 --- a/tests/xfs/341 +++ b/tests/xfs/341 @@ -41,8 +41,8 @@ len=$((blocks * rtextsz)) echo "Create some files" $XFS_IO_PROG -f -R -c "falloc 0 $len" -c "pwrite -S 0x68 -b 1048576 0 $len" $SCRATCH_MNT/f1 >> $seqres.full $XFS_IO_PROG -f -R -c "falloc 0 $len" -c "pwrite -S 0x68 -b 1048576 0 $len" $SCRATCH_MNT/f2 >> $seqres.full -$here/src/punch-alternating -i $((2 * rtextsz_blks)) -s $rtextsz_blks $SCRATCH_MNT/f1 >> "$seqres.full" -$here/src/punch-alternating -i $((2 * rtextsz_blks)) -s $rtextsz_blks $SCRATCH_MNT/f2 >> "$seqres.full" +$here/src/punch-alternating $SCRATCH_MNT/f1 >> "$seqres.full" +$here/src/punch-alternating $SCRATCH_MNT/f2 >> "$seqres.full" echo garbage > $SCRATCH_MNT/f3 ino=$(stat -c '%i' $SCRATCH_MNT/f3) _scratch_unmount