From e3e9647d617ec9deb95c00128a78d44ef773369a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 15 Mar 2013 11:53:23 +0000 Subject: [PATCH] xfstests: use preallocation for ag-wiper To enable sane testing of large scale filesystems, the --large-fs test option uses xfs_db magic to mark AGs full without doing any IO. This leaves only a small amount of free space left in the filesystem to stress the high AGs of the filesystem rather than the low AGs. This method requires us to have special filesystem check options to avoid free space checking in xfs_check, and we cannot current run xfs_repair on such a filesystem at all. As it is, free space checking on xfs_check does not scale, so we still need to avoid this checking regardless of how we fill the filesystem. We can achieve exactly the same fill behavior by preallocating a single large file in the filesystem immediately after creating it. This is a filesystem independent manner of filling the filesystem, and allows us to do large filesystem testing on more than just XFS. Further, this preallocation method effectively adds a new "very large file" test. It also enables us to run an unmodified xfs_repair or filesystem specific fsck program to check the filesystem for sanity, so we can now do full sanity checking of such large filesystems. Signed-off-by: Dave Chinner Reviewed-by: Rich Johnston Signed-off-by: Rich Johnston --- common.rc | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/common.rc b/common.rc index 42d2ddcf..d221be11 100644 --- a/common.rc +++ b/common.rc @@ -276,6 +276,47 @@ _scratch_mkfs_options() echo $SCRATCH_OPTIONS $MKFS_OPTIONS $* $SCRATCH_DEV } + +_setup_large_xfs_fs() +{ + fs_size=$1 + local tmp_dir=/tmp/ + + [ "$LARGE_SCRATCH_DEV" != yes ] && return 0 + [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0 + [ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0 + + # calculate the size of the file we need to allocate. + # Default free space in the FS is 50GB, but you can specify more via + # SCRATCH_DEV_EMPTY_SPACE + file_size=$(($fs_size - 50*1024*1024*1024)) + file_size=$(($file_size - $SCRATCH_DEV_EMPTY_SPACE)) + + # mount the filesystem, create the file, unmount it + _scratch_mount 2>&1 >$tmp_dir/mnt.err + local status=$? + if [ $status -ne 0 ]; then + echo "mount failed" + cat $tmp_dir/mnt.err >&2 + rm -f $tmp_dir/mnt.err + return $status + fi + rm -f $tmp_dir/mnt.err + + xfs_io -F -f \ + -c "truncate $file_size" \ + -c "falloc -k 0 $file_size" \ + $SCRATCH_MNT/.use_space 2>&1 > /dev/null + status=$? + umount $SCRATCH_MNT + if [ $status -ne 0 ]; then + echo "large file prealloc failed" + cat $tmp_dir/mnt.err >&2 + return $status + fi + return 0 +} + _scratch_mkfs_xfs() { # extra mkfs options can be added by tests @@ -305,16 +346,23 @@ _scratch_mkfs_xfs() mkfs_status=$? fi + if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then + # manually parse the mkfs output to get the fs size in bytes + local fs_size + fs_size=`cat $tmp_dir.mkfsstd | perl -ne ' + if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+)/) { + my $size = $1 * $2; + print STDOUT "$size\n"; + }'` + _setup_large_xfs_fs $fs_size + mkfs_status=$? + fi + # output stored mkfs output cat $tmp_dir.mkfserr >&2 cat $tmp_dir.mkfsstd rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd - if [ "$LARGE_SCRATCH_DEV" = yes ]; then - [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0 - ./tools/ag-wipe -q -r $SCRATCH_DEV_EMPTY_SPACE $SCRATCH_DEV - fi - return $mkfs_status } -- 2.39.5