diff mbox

[1/2] common: split XFS functions from common/rc

Message ID 20161129213233.8462-2-david@fromorbit.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Chinner Nov. 29, 2016, 9:32 p.m. UTC
From: Dave Chinner <dchinner@redhat.com>

common/rc has become a dumping ground for common functions that
don't have a specific topic file. It's getting huge and difficiult
to manage, and people are duplicating functionality because they
can't easily find existing functions in the mess.

Let's start to make it a little easier to manage by splitting out
the XFS specific functions into common/xfs and source that from
common/rc automatically.  Other filesytems can follow suit in
future, leaving us with only generic functionality in common/rc.

Signed-Off-By: Dave Chinner <dchinner@redhat.com>
---
 common/rc  | 623 +------------------------------------------------------------
 common/xfs | 618 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 624 insertions(+), 617 deletions(-)
 create mode 100644 common/xfs

Comments

Darrick J. Wong Nov. 29, 2016, 11:24 p.m. UTC | #1
On Wed, Nov 30, 2016 at 08:32:32AM +1100, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> common/rc has become a dumping ground for common functions that
> don't have a specific topic file. It's getting huge and difficiult
> to manage, and people are duplicating functionality because they
> can't easily find existing functions in the mess.
> 
> Let's start to make it a little easier to manage by splitting out
> the XFS specific functions into common/xfs and source that from
> common/rc automatically.  Other filesytems can follow suit in
> future, leaving us with only generic functionality in common/rc.
> 
> Signed-Off-By: Dave Chinner <dchinner@redhat.com>

Ye $deities, finally! common/rc is an unholy dumping ground. :)

For the XFS parts only,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  common/rc  | 623 +------------------------------------------------------------
>  common/xfs | 618 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 624 insertions(+), 617 deletions(-)
>  create mode 100644 common/xfs
> 
> diff --git a/common/rc b/common/rc
> index 8c993066597c..00b53643f248 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -123,6 +123,9 @@ then
>      fi
>  fi
>  
> +# make sure we have a standard umask
> +umask 022
> +
>  # check for correct setup
>  case "$FSTYP" in
>      xfs)
> @@ -130,6 +133,9 @@ case "$FSTYP" in
>  	 [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found"
>  	 [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found"
>  	 [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found"
> +
> +	 #source the XFS specific functions now.
> +	 . ./common/xfs
>  	 ;;
>      udf)
>  	 [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found"
> @@ -156,9 +162,6 @@ case "$FSTYP" in
>  	 ;;
>  esac
>  
> -# make sure we have a standard umask
> -umask 022
> -
>  _mount()
>  {
>      $MOUNT_PROG `_mount_ops_filter $*`
> @@ -425,171 +428,6 @@ _scratch_metadump()
>  	xfs_metadump $options $SCRATCH_DEV $dumpfile
>  }
>  
> -_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" \
> -		-c "chattr +d" \
> -		$SCRATCH_MNT/.use_space 2>&1 > /dev/null
> -	export NUM_SPACE_FILES=1
> -	status=$?
> -	_scratch_unmount
> -	if [ $status -ne 0 ]; then
> -		echo "large file prealloc failed"
> -		cat $tmp_dir/mnt.err >&2
> -		return $status
> -	fi
> -	return 0
> -}
> -
> -_scratch_mkfs_xfs_opts()
> -{
> -	mkfs_opts=$*
> -
> -	# remove metadata related mkfs options if mkfs.xfs doesn't them
> -	if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then
> -		mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"`
> -	fi
> -
> -	_scratch_options mkfs
> -
> -	$MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
> -}
> -
> -
> -_scratch_mkfs_xfs_supported()
> -{
> -	local mkfs_opts=$*
> -
> -	_scratch_options mkfs
> -
> -	$MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
> -	local mkfs_status=$?
> -
> -	# a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and
> -	# $mkfs_opts, try again without $MKFS_OPTIONS
> -	if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then
> -		$MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
> -		mkfs_status=$?
> -	fi
> -	return $mkfs_status
> -}
> -
> -_scratch_mkfs_xfs()
> -{
> -	# extra mkfs options can be added by tests
> -	local extra_mkfs_options=$*
> -
> -	local tmp_dir=/tmp/
> -
> -	# save mkfs output in case conflict means we need to run again.
> -	# only the output for the mkfs that applies should be shown
> -	_scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \
> -		2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
> -	local mkfs_status=$?
> -
> -
> -	# a mkfs failure may be caused by conflicts between
> -	# $MKFS_OPTIONS and $extra_mkfs_options
> -	if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then
> -		(
> -		echo -n "** mkfs failed with extra mkfs options "
> -		echo "added to \"$MKFS_OPTIONS\" by test $seq **"
> -		echo -n "** attempting to mkfs using only test $seq "
> -		echo "options: $extra_mkfs_options **"
> -		) >> $seqres.full
> -
> -		# running mkfs again. overwrite previous mkfs output files
> -		_scratch_mkfs_xfs_opts $extra_mkfs_options \
> -			2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
> -		local 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, filtering unnecessary warnings from stderr
> -	cat $tmp_dir.mkfsstd
> -	cat $tmp_dir.mkfserr | sed \
> -		-e '/less than device physical sector/d' \
> -		-e '/switching to logical sector/d' \
> -		>&2
> -	rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd
> -
> -	return $mkfs_status
> -}
> -
> -# xfs_check script is planned to be deprecated. But, we want to
> -# be able to invoke "xfs_check" behavior in xfstests in order to
> -# maintain the current verification levels.
> -_xfs_check()
> -{
> -    OPTS=" "
> -    DBOPTS=" "
> -    USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special"
> -
> -    while getopts "b:fi:l:stvV" c
> -    do
> -        case $c in
> -            s) OPTS=$OPTS"-s ";;
> -            t) OPTS=$OPTS"-t ";;
> -            v) OPTS=$OPTS"-v ";;
> -            i) OPTS=$OPTS"-i "$OPTARG" ";;
> -            b) OPTS=$OPTS"-b "$OPTARG" ";;
> -            f) DBOPTS=$DBOPTS" -f";;
> -            l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
> -            V) $XFS_DB_PROG -p xfs_check -V
> -                return $?
> -                ;;
> -        esac
> -    done
> -    set -- extra $@
> -    shift $OPTIND
> -    case $# in
> -        1)    ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1
> -               status=$?
> -               ;;
> -        2)    echo $USAGE 1>&1
> -              status=2
> -              ;;
> -    esac
> -    return $status
> -}
> -
>  _setup_large_ext4_fs()
>  {
>  	fs_size=$1
> @@ -1113,55 +951,6 @@ _scratch_resvblks()
>  	esac
>  }
>  
> -_scratch_xfs_db_options()
> -{
> -    SCRATCH_OPTIONS=""
> -    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> -        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
> -    echo $SCRATCH_OPTIONS $* $SCRATCH_DEV
> -}
> -
> -_scratch_xfs_db()
> -{
> -	$XFS_DB_PROG "$@" $(_scratch_xfs_db_options)
> -}
> -
> -_scratch_xfs_logprint()
> -{
> -    SCRATCH_OPTIONS=""
> -    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> -        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
> -    $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
> -}
> -
> -_test_xfs_logprint()
> -{
> -	TEST_OPTIONS=""
> -	[ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
> -		TEST_OPTIONS="-l$TEST_LOGDEV"
> -	$XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV
> -}
> -
> -_scratch_xfs_check()
> -{
> -    SCRATCH_OPTIONS=""
> -    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> -        SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV"
> -    [ "$LARGE_SCRATCH_DEV" = yes ] && \
> -        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
> -    _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV
> -}
> -
> -_scratch_xfs_repair()
> -{
> -    SCRATCH_OPTIONS=""
> -    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> -        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
> -    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
> -        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV"
> -    [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
> -    $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
> -}
>  
>  # Repair scratch filesystem.  Returns 0 if the FS is good to go (either no
>  # errors found or errors were fixed) and nonzero otherwise; also spits out
> @@ -1794,38 +1583,6 @@ _require_dm_target()
>  	fi
>  }
>  
> -# this test requires the projid32bit feature to be available in mkfs.xfs.
> -#
> -_require_projid32bit()
> -{
> -       _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \
> -	   || _notrun "mkfs.xfs doesn't have projid32bit feature"
> -}
> -
> -_require_projid16bit()
> -{
> -	_scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \
> -	   || _notrun "16 bit project IDs not supported on $SCRATCH_DEV"
> -}
> -
> -# this test requires the crc feature to be available in mkfs.xfs
> -#
> -_require_xfs_mkfs_crc()
> -{
> -	_scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \
> -	   || _notrun "mkfs.xfs doesn't have crc feature"
> -}
> -
> -# this test requires the xfs kernel support crc feature
> -#
> -_require_xfs_crc()
> -{
> -	_scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1
> -	_scratch_mount >/dev/null 2>&1 \
> -	   || _notrun "Kernel doesn't support crc feature"
> -	_scratch_unmount
> -}
> -
>  # this test requires the ext4 kernel support crc feature on scratch device
>  #
>  _require_scratch_ext4_crc()
> @@ -1837,17 +1594,6 @@ _require_scratch_ext4_crc()
>  	_scratch_unmount
>  }
>  
> -# this test requires the xfs kernel support crc feature on scratch device
> -#
> -_require_scratch_xfs_crc()
> -{
> -	_scratch_mkfs_xfs >/dev/null 2>&1
> -	_scratch_mount >/dev/null 2>&1 \
> -	   || _notrun "Kernel doesn't support crc feature"
> -	xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem"
> -	_scratch_unmount
> -}
> -
>  # this test requires the bigalloc feature to be available in mkfs.ext4
>  #
>  _require_ext4_mkfs_bigalloc()
> @@ -1866,52 +1612,6 @@ _require_ext4_bigalloc()
>  	_scratch_unmount
>  }
>  
> -# this test requires the finobt feature to be available in mkfs.xfs
> -#
> -_require_xfs_mkfs_finobt()
> -{
> -	_scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \
> -	   || _notrun "mkfs.xfs doesn't have finobt feature"
> -}
> -
> -# this test requires the xfs kernel support finobt feature
> -#
> -_require_xfs_finobt()
> -{
> -	_scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1
> -	_scratch_mount >/dev/null 2>&1 \
> -	   || _notrun "Kernel doesn't support finobt feature"
> -	_scratch_unmount
> -}
> -
> -# this test requires xfs sysfs attribute support
> -#
> -_require_xfs_sysfs()
> -{
> -	attr=$1
> -	sysfsdir=/sys/fs/xfs
> -
> -	if [ ! -e $sysfsdir ]; then
> -		_notrun "no kernel support for XFS sysfs attributes"
> -	fi
> -
> -	if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then
> -		_notrun "sysfs attribute '$attr' is not supported"
> -	fi
> -}
> -
> -# this test requires the xfs sparse inode feature
> -#
> -_require_xfs_sparse_inodes()
> -{
> -	_scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \
> -		|| _notrun "mkfs.xfs does not support sparse inodes"
> -	_scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1
> -	_scratch_mount >/dev/null 2>&1 \
> -		|| _notrun "kernel does not support sparse inodes"
> -	_scratch_unmount
> -}
> -
>  # this test requires that external log/realtime devices are not in use
>  #
>  _require_nonexternal()
> @@ -2093,20 +1793,6 @@ _require_xfs_io_command()
>  		_notrun "xfs_io $command doesn't support $param"
>  }
>  
> -# check that xfs_db supports a specific command
> -_require_xfs_db_command()
> -{
> -	if [ $# -ne 1 ]
> -	then
> -		echo "Usage: _require_xfs_db_command command" 1>&2
> -		exit 1
> -	fi
> -	command=$1
> -
> -	_scratch_xfs_db -x -c "help" | grep $command > /dev/null || \
> -		_notrun "xfs_db $command support is missing"
> -}
> -
>  # check that kernel and filesystem support direct I/O
>  _require_odirect()
>  {
> @@ -2403,150 +2089,6 @@ _check_generic_filesystem()
>      return 0
>  }
>  
> -# run xfs_check and friends on a FS.
> -
> -_check_xfs_filesystem()
> -{
> -    if [ $# -ne 3 ]
> -    then
> -	echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2
> -	exit 1
> -    fi
> -
> -    extra_mount_options=""
> -    extra_log_options=""
> -    extra_options=""
> -    device=$1
> -    if [ -f $device ];then
> -       extra_options="-f"
> -    fi
> -
> -    if [ "$2" != "none" ]; then
> -	extra_log_options="-l$2"
> -        extra_mount_options="-ologdev=$2"
> -    fi
> -
> -    if [ "$3" != "none" ]; then
> -	extra_rt_options="-r$3"
> -        extra_mount_options=$extra_mount_options" -ortdev=$3"
> -    fi
> -    extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS"
> -
> -    [ "$FSTYP" != xfs ] && return 0
> -
> -    type=`_fs_type $device`
> -    ok=1
> -
> -    if [ "$type" = "xfs" ]
> -    then
> -        if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then
> -            "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full
> -            if [ $? -ne 0 ]; then
> -                echo "filesystem on $device failed scrub (see $seqres.full)"
> -                ok=0
> -            fi
> -        fi
> -        # mounted ...
> -        mountpoint=`_umount_or_remount_ro $device`
> -    fi
> -
> -    $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \
> -                | tee $tmp.logprint | grep -q "<CLEAN>"
> -    if [ $? -ne 0 -a "$HOSTOS" = "Linux" ]
> -    then
> -        echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)"
> -
> -        echo "_check_xfs_filesystem: filesystem on $device has dirty log"   >>$seqres.full
> -        echo "*** xfs_logprint -t output ***"	>>$seqres.full
> -        cat $tmp.logprint			>>$seqres.full
> -        echo "*** end xfs_logprint output"	>>$seqres.full
> -
> -        ok=0
> -    fi
> -
> -    # xfs_check runs out of memory on large files, so even providing the test
> -    # option (-t) to avoid indexing the free space trees doesn't make it pass on
> -    # large filesystems. Avoid it.
> -    if [ "$LARGE_SCRATCH_DEV" != yes ]; then
> -	    _xfs_check $extra_log_options $device 2>&1 |\
> -		 _fix_malloc >$tmp.fs_check
> -    fi
> -    if [ -s $tmp.fs_check ]
> -    then
> -        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)"
> -
> -        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
> -        echo "*** xfs_check output ***"		>>$seqres.full
> -        cat $tmp.fs_check			>>$seqres.full
> -        echo "*** end xfs_check output"		>>$seqres.full
> -
> -        ok=0
> -    fi
> -
> -    $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
> -    if [ $? -ne 0 ]
> -    then
> -        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)"
> -
> -        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
> -        echo "*** xfs_repair -n output ***"	>>$seqres.full
> -        cat $tmp.repair | _fix_malloc		>>$seqres.full
> -        echo "*** end xfs_repair output"	>>$seqres.full
> -
> -        ok=0
> -    fi
> -    rm -f $tmp.fs_check $tmp.logprint $tmp.repair
> -
> -    # Optionally test the index rebuilding behavior.
> -    if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then
> -        $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
> -        if [ $? -ne 0 ]; then
> -            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)"
> -
> -            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full
> -            echo "*** xfs_repair output ***"	>>$seqres.full
> -            cat $tmp.repair | _fix_malloc		>>$seqres.full
> -            echo "*** end xfs_repair output"	>>$seqres.full
> -
> -            ok=0
> -        fi
> -        rm -f $tmp.repair
> -
> -        $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
> -        if [ $? -ne 0 ]; then
> -            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)"
> -
> -            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full
> -            echo "*** xfs_repair -n output ***"	>>$seqres.full
> -            cat $tmp.repair | _fix_malloc		>>$seqres.full
> -            echo "*** end xfs_repair output"	>>$seqres.full
> -
> -            ok=0
> -        fi
> -        rm -f $tmp.repair
> -    fi
> -
> -    if [ $ok -eq 0 ]
> -    then
> -        echo "*** mount output ***"		>>$seqres.full
> -        _mount					>>$seqres.full
> -        echo "*** end mount output"		>>$seqres.full
> -    elif [ "$type" = "xfs" ]
> -    then
> -	_mount_or_remount_rw "$extra_mount_options" $device $mountpoint
> -    fi
> -
> -    if [ $ok -eq 0 ]; then
> -	status=1
> -	if [ "$iam" != "check" ]; then
> -		exit 1
> -	fi
> -	return 1
> -    fi
> -
> -    return 0
> -}
> -
>  # Filter the knowen errors the UDF Verifier reports.
>  _udf_test_known_error_filter()
>  {
> @@ -2590,26 +2132,6 @@ _check_udf_filesystem()
>      return 0
>  }
>  
> -_check_xfs_test_fs()
> -{
> -    TEST_LOG="none"
> -    TEST_RT="none"
> -    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
> -        TEST_LOG="$TEST_LOGDEV"
> -
> -    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
> -        TEST_RT="$TEST_RTDEV"
> -
> -    _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT
> -
> -    # check for ipath consistency
> -    if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then
> -	# errors go to stderr
> -	xfs_check_ipaths $TEST_DIR >/dev/null
> -	xfs_repair_ipaths -n $TEST_DIR >/dev/null
> -    fi
> -}
> -
>  _check_btrfs_filesystem()
>  {
>      device=$1
> @@ -3382,24 +2904,6 @@ _require_test_fcntl_advisory_locks()
>  		_notrun "Require fcntl advisory locks support"
>  }
>  
> -# XFS ability to change UUIDs on V5/CRC filesystems
> -#
> -_require_meta_uuid()
> -{
> -	# This will create a crc fs on $SCRATCH_DEV
> -	_require_xfs_crc
> -
> -	_scratch_xfs_db -x -c "uuid restore" 2>&1 \
> -	   | grep -q "invalid UUID\|supported on V5 fs" \
> -	   && _notrun "Userspace doesn't support meta_uuid feature"
> -
> -	_scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1
> -
> -	_scratch_mount >/dev/null 2>&1 \
> -	   || _notrun "Kernel doesn't support meta_uuid feature"
> -	_scratch_unmount
> -}
> -
>  _require_btrfs_dev_del_by_devid()
>  {
>  	$BTRFS_UTIL_PROG device delete --help | egrep devid > /dev/null 2>&1
> @@ -3416,47 +2920,6 @@ _require_test_lsattr()
>  		_notrun "lsattr not supported by test filesystem type: $FSTYP"
>  }
>  
> -_require_xfs_test_rmapbt()
> -{
> -	_require_test
> -
> -	if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then
> -		_notrun "rmapbt not supported by test filesystem type: $FSTYP"
> -	fi
> -}
> -
> -_require_xfs_scratch_rmapbt()
> -{
> -	_require_scratch
> -
> -	_scratch_mkfs > /dev/null
> -	_scratch_mount
> -	if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then
> -		_scratch_unmount
> -		_notrun "rmapbt not supported by scratch filesystem type: $FSTYP"
> -	fi
> -	_scratch_unmount
> -}
> -
> -_xfs_bmapx_find() {
> -	case "$1" in
> -	"attr")
> -		param="a"
> -		;;
> -	"cow")
> -		param="c"
> -		;;
> -	*)
> -		param="e"
> -		;;
> -	esac
> -	shift
> -	file="$1"
> -	shift
> -
> -	$XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@"
> -}
> -
>  _require_chattr()
>  {
>      attribute=$1
> @@ -3962,80 +3425,6 @@ _get_fs_sysfs_attr()
>  }
>  
>  
> -# Reset all xfs error handling attributes, set them to original
> -# status.
> -#
> -# Only one argument, and it's mandatory:
> -#  - dev: device name, e.g. $SCRATCH_DEV
> -#
> -# Note: this function only works for XFS
> -_reset_xfs_sysfs_error_handling()
> -{
> -	local dev=$1
> -
> -	if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then
> -		_fail "Usage: reset_xfs_sysfs_error_handling <device>"
> -	fi
> -
> -	_set_fs_sysfs_attr $dev error/fail_at_unmount 1
> -	echo -n "error/fail_at_unmount="
> -	_get_fs_sysfs_attr $dev error/fail_at_unmount
> -
> -	# Make sure all will be configured to retry forever by default, except
> -	# for ENODEV, which is an unrecoverable error, so it will be configured
> -	# to not retry on error by default.
> -	for e in default EIO ENOSPC; do
> -		_set_fs_sysfs_attr $dev \
> -				   error/metadata/${e}/max_retries -1
> -		echo -n "error/metadata/${e}/max_retries="
> -		_get_fs_sysfs_attr $dev error/metadata/${e}/max_retries
> -
> -		_set_fs_sysfs_attr $dev \
> -				   error/metadata/${e}/retry_timeout_seconds 0
> -		echo -n "error/metadata/${e}/retry_timeout_seconds="
> -		_get_fs_sysfs_attr $dev \
> -				   error/metadata/${e}/retry_timeout_seconds
> -	done
> -}
> -
> -# Skip if we are running an older binary without the stricter input checks.
> -# Make multiple checks to be sure that there is no regression on the one
> -# selected feature check, which would skew the result.
> -#
> -# At first, make a common function that runs the tests and returns
> -# number of failed cases.
> -_xfs_mkfs_validation_check()
> -{
> -	local tmpfile=`mktemp`
> -	local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g"
> -
> -	$cmd -s size=2s >/dev/null 2>&1
> -	local sum=$?
> -
> -	$cmd -l version=2,su=260k >/dev/null 2>&1
> -	sum=`expr $sum + $?`
> -
> -	rm -f $tmpfile
> -	return $sum
> -}
> -
> -# Skip the test if all calls passed - mkfs accepts invalid input
> -_require_xfs_mkfs_validation()
> -{
> -	_xfs_mkfs_validation_check
> -	if [ "$?" -eq 0 ]; then
> -		_notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7."
> -	fi
> -}
> -
> -# The oposite of _require_xfs_mkfs_validation.
> -_require_xfs_mkfs_without_validation()
> -{
> -	_xfs_mkfs_validation_check
> -	if [ "$?" -ne 0 ]; then
> -		_notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5."
> -	fi
> -}
>  
>  init_rc
>  
> diff --git a/common/xfs b/common/xfs
> new file mode 100644
> index 000000000000..0dde83f26518
> --- /dev/null
> +++ b/common/xfs
> @@ -0,0 +1,618 @@
> +#
> +# XFS specific common functions.
> +#
> +
> +_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" \
> +		-c "chattr +d" \
> +		$SCRATCH_MNT/.use_space 2>&1 > /dev/null
> +	export NUM_SPACE_FILES=1
> +	status=$?
> +	_scratch_unmount
> +	if [ $status -ne 0 ]; then
> +		echo "large file prealloc failed"
> +		cat $tmp_dir/mnt.err >&2
> +		return $status
> +	fi
> +	return 0
> +}
> +
> +_scratch_mkfs_xfs_opts()
> +{
> +	mkfs_opts=$*
> +
> +	# remove metadata related mkfs options if mkfs.xfs doesn't them
> +	if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then
> +		mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"`
> +	fi
> +
> +	_scratch_options mkfs
> +
> +	$MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
> +}
> +
> +
> +_scratch_mkfs_xfs_supported()
> +{
> +	local mkfs_opts=$*
> +
> +	_scratch_options mkfs
> +
> +	$MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
> +	local mkfs_status=$?
> +
> +	# a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and
> +	# $mkfs_opts, try again without $MKFS_OPTIONS
> +	if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then
> +		$MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
> +		mkfs_status=$?
> +	fi
> +	return $mkfs_status
> +}
> +
> +_scratch_mkfs_xfs()
> +{
> +	# extra mkfs options can be added by tests
> +	local extra_mkfs_options=$*
> +
> +	local tmp_dir=/tmp/
> +
> +	# save mkfs output in case conflict means we need to run again.
> +	# only the output for the mkfs that applies should be shown
> +	_scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \
> +		2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
> +	local mkfs_status=$?
> +
> +
> +	# a mkfs failure may be caused by conflicts between
> +	# $MKFS_OPTIONS and $extra_mkfs_options
> +	if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then
> +		(
> +		echo -n "** mkfs failed with extra mkfs options "
> +		echo "added to \"$MKFS_OPTIONS\" by test $seq **"
> +		echo -n "** attempting to mkfs using only test $seq "
> +		echo "options: $extra_mkfs_options **"
> +		) >> $seqres.full
> +
> +		# running mkfs again. overwrite previous mkfs output files
> +		_scratch_mkfs_xfs_opts $extra_mkfs_options \
> +			2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
> +		local 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, filtering unnecessary warnings from stderr
> +	cat $tmp_dir.mkfsstd
> +	cat $tmp_dir.mkfserr | sed \
> +		-e '/less than device physical sector/d' \
> +		-e '/switching to logical sector/d' \
> +		>&2
> +	rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd
> +
> +	return $mkfs_status
> +}
> +
> +# xfs_check script is planned to be deprecated. But, we want to
> +# be able to invoke "xfs_check" behavior in xfstests in order to
> +# maintain the current verification levels.
> +_xfs_check()
> +{
> +    OPTS=" "
> +    DBOPTS=" "
> +    USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special"
> +
> +    while getopts "b:fi:l:stvV" c
> +    do
> +        case $c in
> +            s) OPTS=$OPTS"-s ";;
> +            t) OPTS=$OPTS"-t ";;
> +            v) OPTS=$OPTS"-v ";;
> +            i) OPTS=$OPTS"-i "$OPTARG" ";;
> +            b) OPTS=$OPTS"-b "$OPTARG" ";;
> +            f) DBOPTS=$DBOPTS" -f";;
> +            l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
> +            V) $XFS_DB_PROG -p xfs_check -V
> +                return $?
> +                ;;
> +        esac
> +    done
> +    set -- extra $@
> +    shift $OPTIND
> +    case $# in
> +        1)    ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1
> +               status=$?
> +               ;;
> +        2)    echo $USAGE 1>&1
> +              status=2
> +              ;;
> +    esac
> +    return $status
> +}
> +
> +_scratch_xfs_db_options()
> +{
> +    SCRATCH_OPTIONS=""
> +    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> +        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
> +    echo $SCRATCH_OPTIONS $* $SCRATCH_DEV
> +}
> +
> +_scratch_xfs_db()
> +{
> +	$XFS_DB_PROG "$@" $(_scratch_xfs_db_options)
> +}
> +
> +_scratch_xfs_logprint()
> +{
> +    SCRATCH_OPTIONS=""
> +    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> +        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
> +    $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
> +}
> +
> +_test_xfs_logprint()
> +{
> +	TEST_OPTIONS=""
> +	[ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
> +		TEST_OPTIONS="-l$TEST_LOGDEV"
> +	$XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV
> +}
> +
> +_scratch_xfs_check()
> +{
> +    SCRATCH_OPTIONS=""
> +    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> +        SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV"
> +    [ "$LARGE_SCRATCH_DEV" = yes ] && \
> +        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
> +    _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV
> +}
> +
> +_scratch_xfs_repair()
> +{
> +    SCRATCH_OPTIONS=""
> +    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
> +        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
> +    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
> +        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV"
> +    [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
> +    $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
> +}
> +
> +# this test requires the projid32bit feature to be available in mkfs.xfs.
> +#
> +_require_projid32bit()
> +{
> +       _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \
> +	   || _notrun "mkfs.xfs doesn't have projid32bit feature"
> +}
> +
> +_require_projid16bit()
> +{
> +	_scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \
> +	   || _notrun "16 bit project IDs not supported on $SCRATCH_DEV"
> +}
> +
> +# this test requires the crc feature to be available in mkfs.xfs
> +#
> +_require_xfs_mkfs_crc()
> +{
> +	_scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \
> +	   || _notrun "mkfs.xfs doesn't have crc feature"
> +}
> +
> +# this test requires the xfs kernel support crc feature
> +#
> +_require_xfs_crc()
> +{
> +	_scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1
> +	_scratch_mount >/dev/null 2>&1 \
> +	   || _notrun "Kernel doesn't support crc feature"
> +	_scratch_unmount
> +}
> +
> +# this test requires the xfs kernel support crc feature on scratch device
> +#
> +_require_scratch_xfs_crc()
> +{
> +	_scratch_mkfs_xfs >/dev/null 2>&1
> +	_scratch_mount >/dev/null 2>&1 \
> +	   || _notrun "Kernel doesn't support crc feature"
> +	xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem"
> +	_scratch_unmount
> +}
> +
> +# this test requires the finobt feature to be available in mkfs.xfs
> +#
> +_require_xfs_mkfs_finobt()
> +{
> +	_scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \
> +	   || _notrun "mkfs.xfs doesn't have finobt feature"
> +}
> +
> +# this test requires the xfs kernel support finobt feature
> +#
> +_require_xfs_finobt()
> +{
> +	_scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1
> +	_scratch_mount >/dev/null 2>&1 \
> +	   || _notrun "Kernel doesn't support finobt feature"
> +	_scratch_unmount
> +}
> +
> +# this test requires xfs sysfs attribute support
> +#
> +_require_xfs_sysfs()
> +{
> +	attr=$1
> +	sysfsdir=/sys/fs/xfs
> +
> +	if [ ! -e $sysfsdir ]; then
> +		_notrun "no kernel support for XFS sysfs attributes"
> +	fi
> +
> +	if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then
> +		_notrun "sysfs attribute '$attr' is not supported"
> +	fi
> +}
> +
> +# this test requires the xfs sparse inode feature
> +#
> +_require_xfs_sparse_inodes()
> +{
> +	_scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \
> +		|| _notrun "mkfs.xfs does not support sparse inodes"
> +	_scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1
> +	_scratch_mount >/dev/null 2>&1 \
> +		|| _notrun "kernel does not support sparse inodes"
> +	_scratch_unmount
> +}
> +
> +# check that xfs_db supports a specific command
> +_require_xfs_db_command()
> +{
> +	if [ $# -ne 1 ]
> +	then
> +		echo "Usage: _require_xfs_db_command command" 1>&2
> +		exit 1
> +	fi
> +	command=$1
> +
> +	_scratch_xfs_db -x -c "help" | grep $command > /dev/null || \
> +		_notrun "xfs_db $command support is missing"
> +}
> +
> +# run xfs_check and friends on a FS.
> +_check_xfs_filesystem()
> +{
> +    if [ $# -ne 3 ]
> +    then
> +	echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2
> +	exit 1
> +    fi
> +
> +    extra_mount_options=""
> +    extra_log_options=""
> +    extra_options=""
> +    device=$1
> +    if [ -f $device ];then
> +       extra_options="-f"
> +    fi
> +
> +    if [ "$2" != "none" ]; then
> +	extra_log_options="-l$2"
> +        extra_mount_options="-ologdev=$2"
> +    fi
> +
> +    if [ "$3" != "none" ]; then
> +	extra_rt_options="-r$3"
> +        extra_mount_options=$extra_mount_options" -ortdev=$3"
> +    fi
> +    extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS"
> +
> +    [ "$FSTYP" != xfs ] && return 0
> +
> +    type=`_fs_type $device`
> +    ok=1
> +
> +    if [ "$type" = "xfs" ]
> +    then
> +        if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then
> +            "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full
> +            if [ $? -ne 0 ]; then
> +                echo "filesystem on $device failed scrub (see $seqres.full)"
> +                ok=0
> +            fi
> +        fi
> +        # mounted ...
> +        mountpoint=`_umount_or_remount_ro $device`
> +    fi
> +
> +    $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \
> +                | tee $tmp.logprint | grep -q "<CLEAN>"
> +    if [ $? -ne 0 -a "$HOSTOS" = "Linux" ]
> +    then
> +        echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)"
> +
> +        echo "_check_xfs_filesystem: filesystem on $device has dirty log"   >>$seqres.full
> +        echo "*** xfs_logprint -t output ***"	>>$seqres.full
> +        cat $tmp.logprint			>>$seqres.full
> +        echo "*** end xfs_logprint output"	>>$seqres.full
> +
> +        ok=0
> +    fi
> +
> +    # xfs_check runs out of memory on large files, so even providing the test
> +    # option (-t) to avoid indexing the free space trees doesn't make it pass on
> +    # large filesystems. Avoid it.
> +    if [ "$LARGE_SCRATCH_DEV" != yes ]; then
> +	    _xfs_check $extra_log_options $device 2>&1 |\
> +		 _fix_malloc >$tmp.fs_check
> +    fi
> +    if [ -s $tmp.fs_check ]
> +    then
> +        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)"
> +
> +        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
> +        echo "*** xfs_check output ***"		>>$seqres.full
> +        cat $tmp.fs_check			>>$seqres.full
> +        echo "*** end xfs_check output"		>>$seqres.full
> +
> +        ok=0
> +    fi
> +
> +    $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
> +    if [ $? -ne 0 ]
> +    then
> +        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)"
> +
> +        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
> +        echo "*** xfs_repair -n output ***"	>>$seqres.full
> +        cat $tmp.repair | _fix_malloc		>>$seqres.full
> +        echo "*** end xfs_repair output"	>>$seqres.full
> +
> +        ok=0
> +    fi
> +    rm -f $tmp.fs_check $tmp.logprint $tmp.repair
> +
> +    # Optionally test the index rebuilding behavior.
> +    if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then
> +        $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
> +        if [ $? -ne 0 ]; then
> +            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)"
> +
> +            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full
> +            echo "*** xfs_repair output ***"	>>$seqres.full
> +            cat $tmp.repair | _fix_malloc		>>$seqres.full
> +            echo "*** end xfs_repair output"	>>$seqres.full
> +
> +            ok=0
> +        fi
> +        rm -f $tmp.repair
> +
> +        $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
> +        if [ $? -ne 0 ]; then
> +            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)"
> +
> +            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full
> +            echo "*** xfs_repair -n output ***"	>>$seqres.full
> +            cat $tmp.repair | _fix_malloc		>>$seqres.full
> +            echo "*** end xfs_repair output"	>>$seqres.full
> +
> +            ok=0
> +        fi
> +        rm -f $tmp.repair
> +    fi
> +
> +    if [ $ok -eq 0 ]
> +    then
> +        echo "*** mount output ***"		>>$seqres.full
> +        _mount					>>$seqres.full
> +        echo "*** end mount output"		>>$seqres.full
> +    elif [ "$type" = "xfs" ]
> +    then
> +	_mount_or_remount_rw "$extra_mount_options" $device $mountpoint
> +    fi
> +
> +    if [ $ok -eq 0 ]; then
> +	status=1
> +	if [ "$iam" != "check" ]; then
> +		exit 1
> +	fi
> +	return 1
> +    fi
> +
> +    return 0
> +}
> +
> +_check_xfs_test_fs()
> +{
> +    TEST_LOG="none"
> +    TEST_RT="none"
> +    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
> +        TEST_LOG="$TEST_LOGDEV"
> +
> +    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
> +        TEST_RT="$TEST_RTDEV"
> +
> +    _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT
> +
> +    # check for ipath consistency
> +    if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then
> +	# errors go to stderr
> +	xfs_check_ipaths $TEST_DIR >/dev/null
> +	xfs_repair_ipaths -n $TEST_DIR >/dev/null
> +    fi
> +}
> +
> +_require_xfs_test_rmapbt()
> +{
> +	_require_test
> +
> +	if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then
> +		_notrun "rmapbt not supported by test filesystem type: $FSTYP"
> +	fi
> +}
> +
> +_require_xfs_scratch_rmapbt()
> +{
> +	_require_scratch
> +
> +	_scratch_mkfs > /dev/null
> +	_scratch_mount
> +	if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then
> +		_scratch_unmount
> +		_notrun "rmapbt not supported by scratch filesystem type: $FSTYP"
> +	fi
> +	_scratch_unmount
> +}
> +
> +_xfs_bmapx_find() {
> +	case "$1" in
> +	"attr")
> +		param="a"
> +		;;
> +	"cow")
> +		param="c"
> +		;;
> +	*)
> +		param="e"
> +		;;
> +	esac
> +	shift
> +	file="$1"
> +	shift
> +
> +	$XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@"
> +}
> +
> +# Reset all xfs error handling attributes, set them to original
> +# status.
> +#
> +# Only one argument, and it's mandatory:
> +#  - dev: device name, e.g. $SCRATCH_DEV
> +#
> +# Note: this function only works for XFS
> +_reset_xfs_sysfs_error_handling()
> +{
> +	local dev=$1
> +
> +	if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then
> +		_fail "Usage: reset_xfs_sysfs_error_handling <device>"
> +	fi
> +
> +	_set_fs_sysfs_attr $dev error/fail_at_unmount 1
> +	echo -n "error/fail_at_unmount="
> +	_get_fs_sysfs_attr $dev error/fail_at_unmount
> +
> +	# Make sure all will be configured to retry forever by default, except
> +	# for ENODEV, which is an unrecoverable error, so it will be configured
> +	# to not retry on error by default.
> +	for e in default EIO ENOSPC; do
> +		_set_fs_sysfs_attr $dev \
> +				   error/metadata/${e}/max_retries -1
> +		echo -n "error/metadata/${e}/max_retries="
> +		_get_fs_sysfs_attr $dev error/metadata/${e}/max_retries
> +
> +		_set_fs_sysfs_attr $dev \
> +				   error/metadata/${e}/retry_timeout_seconds 0
> +		echo -n "error/metadata/${e}/retry_timeout_seconds="
> +		_get_fs_sysfs_attr $dev \
> +				   error/metadata/${e}/retry_timeout_seconds
> +	done
> +}
> +
> +# Skip if we are running an older binary without the stricter input checks.
> +# Make multiple checks to be sure that there is no regression on the one
> +# selected feature check, which would skew the result.
> +#
> +# At first, make a common function that runs the tests and returns
> +# number of failed cases.
> +_xfs_mkfs_validation_check()
> +{
> +	local tmpfile=`mktemp`
> +	local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g"
> +
> +	$cmd -s size=2s >/dev/null 2>&1
> +	local sum=$?
> +
> +	$cmd -l version=2,su=260k >/dev/null 2>&1
> +	sum=`expr $sum + $?`
> +
> +	rm -f $tmpfile
> +	return $sum
> +}
> +
> +# Skip the test if all calls passed - mkfs accepts invalid input
> +_require_xfs_mkfs_validation()
> +{
> +	_xfs_mkfs_validation_check
> +	if [ "$?" -eq 0 ]; then
> +		_notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7."
> +	fi
> +}
> +
> +# The opposite of _require_xfs_mkfs_validation.
> +_require_xfs_mkfs_without_validation()
> +{
> +	_xfs_mkfs_validation_check
> +	if [ "$?" -ne 0 ]; then
> +		_notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5."
> +	fi
> +}
> +
> +# XFS ability to change UUIDs on V5/CRC filesystems
> +#
> +_require_meta_uuid()
> +{
> +	# This will create a crc fs on $SCRATCH_DEV
> +	_require_xfs_crc
> +
> +	_scratch_xfs_db -x -c "uuid restore" 2>&1 \
> +	   | grep -q "invalid UUID\|supported on V5 fs" \
> +	   && _notrun "Userspace doesn't support meta_uuid feature"
> +
> +	_scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1
> +
> +	_scratch_mount >/dev/null 2>&1 \
> +	   || _notrun "Kernel doesn't support meta_uuid feature"
> +	_scratch_unmount
> +}
> -- 
> 2.10.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe fstests" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe fstests" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/common/rc b/common/rc
index 8c993066597c..00b53643f248 100644
--- a/common/rc
+++ b/common/rc
@@ -123,6 +123,9 @@  then
     fi
 fi
 
+# make sure we have a standard umask
+umask 022
+
 # check for correct setup
 case "$FSTYP" in
     xfs)
@@ -130,6 +133,9 @@  case "$FSTYP" in
 	 [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found"
 	 [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found"
 	 [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found"
+
+	 #source the XFS specific functions now.
+	 . ./common/xfs
 	 ;;
     udf)
 	 [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found"
@@ -156,9 +162,6 @@  case "$FSTYP" in
 	 ;;
 esac
 
-# make sure we have a standard umask
-umask 022
-
 _mount()
 {
     $MOUNT_PROG `_mount_ops_filter $*`
@@ -425,171 +428,6 @@  _scratch_metadump()
 	xfs_metadump $options $SCRATCH_DEV $dumpfile
 }
 
-_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" \
-		-c "chattr +d" \
-		$SCRATCH_MNT/.use_space 2>&1 > /dev/null
-	export NUM_SPACE_FILES=1
-	status=$?
-	_scratch_unmount
-	if [ $status -ne 0 ]; then
-		echo "large file prealloc failed"
-		cat $tmp_dir/mnt.err >&2
-		return $status
-	fi
-	return 0
-}
-
-_scratch_mkfs_xfs_opts()
-{
-	mkfs_opts=$*
-
-	# remove metadata related mkfs options if mkfs.xfs doesn't them
-	if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then
-		mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"`
-	fi
-
-	_scratch_options mkfs
-
-	$MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
-}
-
-
-_scratch_mkfs_xfs_supported()
-{
-	local mkfs_opts=$*
-
-	_scratch_options mkfs
-
-	$MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
-	local mkfs_status=$?
-
-	# a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and
-	# $mkfs_opts, try again without $MKFS_OPTIONS
-	if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then
-		$MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
-		mkfs_status=$?
-	fi
-	return $mkfs_status
-}
-
-_scratch_mkfs_xfs()
-{
-	# extra mkfs options can be added by tests
-	local extra_mkfs_options=$*
-
-	local tmp_dir=/tmp/
-
-	# save mkfs output in case conflict means we need to run again.
-	# only the output for the mkfs that applies should be shown
-	_scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \
-		2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
-	local mkfs_status=$?
-
-
-	# a mkfs failure may be caused by conflicts between
-	# $MKFS_OPTIONS and $extra_mkfs_options
-	if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then
-		(
-		echo -n "** mkfs failed with extra mkfs options "
-		echo "added to \"$MKFS_OPTIONS\" by test $seq **"
-		echo -n "** attempting to mkfs using only test $seq "
-		echo "options: $extra_mkfs_options **"
-		) >> $seqres.full
-
-		# running mkfs again. overwrite previous mkfs output files
-		_scratch_mkfs_xfs_opts $extra_mkfs_options \
-			2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
-		local 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, filtering unnecessary warnings from stderr
-	cat $tmp_dir.mkfsstd
-	cat $tmp_dir.mkfserr | sed \
-		-e '/less than device physical sector/d' \
-		-e '/switching to logical sector/d' \
-		>&2
-	rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd
-
-	return $mkfs_status
-}
-
-# xfs_check script is planned to be deprecated. But, we want to
-# be able to invoke "xfs_check" behavior in xfstests in order to
-# maintain the current verification levels.
-_xfs_check()
-{
-    OPTS=" "
-    DBOPTS=" "
-    USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special"
-
-    while getopts "b:fi:l:stvV" c
-    do
-        case $c in
-            s) OPTS=$OPTS"-s ";;
-            t) OPTS=$OPTS"-t ";;
-            v) OPTS=$OPTS"-v ";;
-            i) OPTS=$OPTS"-i "$OPTARG" ";;
-            b) OPTS=$OPTS"-b "$OPTARG" ";;
-            f) DBOPTS=$DBOPTS" -f";;
-            l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
-            V) $XFS_DB_PROG -p xfs_check -V
-                return $?
-                ;;
-        esac
-    done
-    set -- extra $@
-    shift $OPTIND
-    case $# in
-        1)    ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1
-               status=$?
-               ;;
-        2)    echo $USAGE 1>&1
-              status=2
-              ;;
-    esac
-    return $status
-}
-
 _setup_large_ext4_fs()
 {
 	fs_size=$1
@@ -1113,55 +951,6 @@  _scratch_resvblks()
 	esac
 }
 
-_scratch_xfs_db_options()
-{
-    SCRATCH_OPTIONS=""
-    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
-        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
-    echo $SCRATCH_OPTIONS $* $SCRATCH_DEV
-}
-
-_scratch_xfs_db()
-{
-	$XFS_DB_PROG "$@" $(_scratch_xfs_db_options)
-}
-
-_scratch_xfs_logprint()
-{
-    SCRATCH_OPTIONS=""
-    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
-        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
-    $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
-}
-
-_test_xfs_logprint()
-{
-	TEST_OPTIONS=""
-	[ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
-		TEST_OPTIONS="-l$TEST_LOGDEV"
-	$XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV
-}
-
-_scratch_xfs_check()
-{
-    SCRATCH_OPTIONS=""
-    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
-        SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV"
-    [ "$LARGE_SCRATCH_DEV" = yes ] && \
-        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
-    _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV
-}
-
-_scratch_xfs_repair()
-{
-    SCRATCH_OPTIONS=""
-    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
-        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
-    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
-        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV"
-    [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
-    $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
-}
 
 # Repair scratch filesystem.  Returns 0 if the FS is good to go (either no
 # errors found or errors were fixed) and nonzero otherwise; also spits out
@@ -1794,38 +1583,6 @@  _require_dm_target()
 	fi
 }
 
-# this test requires the projid32bit feature to be available in mkfs.xfs.
-#
-_require_projid32bit()
-{
-       _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \
-	   || _notrun "mkfs.xfs doesn't have projid32bit feature"
-}
-
-_require_projid16bit()
-{
-	_scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \
-	   || _notrun "16 bit project IDs not supported on $SCRATCH_DEV"
-}
-
-# this test requires the crc feature to be available in mkfs.xfs
-#
-_require_xfs_mkfs_crc()
-{
-	_scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \
-	   || _notrun "mkfs.xfs doesn't have crc feature"
-}
-
-# this test requires the xfs kernel support crc feature
-#
-_require_xfs_crc()
-{
-	_scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1
-	_scratch_mount >/dev/null 2>&1 \
-	   || _notrun "Kernel doesn't support crc feature"
-	_scratch_unmount
-}
-
 # this test requires the ext4 kernel support crc feature on scratch device
 #
 _require_scratch_ext4_crc()
@@ -1837,17 +1594,6 @@  _require_scratch_ext4_crc()
 	_scratch_unmount
 }
 
-# this test requires the xfs kernel support crc feature on scratch device
-#
-_require_scratch_xfs_crc()
-{
-	_scratch_mkfs_xfs >/dev/null 2>&1
-	_scratch_mount >/dev/null 2>&1 \
-	   || _notrun "Kernel doesn't support crc feature"
-	xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem"
-	_scratch_unmount
-}
-
 # this test requires the bigalloc feature to be available in mkfs.ext4
 #
 _require_ext4_mkfs_bigalloc()
@@ -1866,52 +1612,6 @@  _require_ext4_bigalloc()
 	_scratch_unmount
 }
 
-# this test requires the finobt feature to be available in mkfs.xfs
-#
-_require_xfs_mkfs_finobt()
-{
-	_scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \
-	   || _notrun "mkfs.xfs doesn't have finobt feature"
-}
-
-# this test requires the xfs kernel support finobt feature
-#
-_require_xfs_finobt()
-{
-	_scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1
-	_scratch_mount >/dev/null 2>&1 \
-	   || _notrun "Kernel doesn't support finobt feature"
-	_scratch_unmount
-}
-
-# this test requires xfs sysfs attribute support
-#
-_require_xfs_sysfs()
-{
-	attr=$1
-	sysfsdir=/sys/fs/xfs
-
-	if [ ! -e $sysfsdir ]; then
-		_notrun "no kernel support for XFS sysfs attributes"
-	fi
-
-	if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then
-		_notrun "sysfs attribute '$attr' is not supported"
-	fi
-}
-
-# this test requires the xfs sparse inode feature
-#
-_require_xfs_sparse_inodes()
-{
-	_scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \
-		|| _notrun "mkfs.xfs does not support sparse inodes"
-	_scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1
-	_scratch_mount >/dev/null 2>&1 \
-		|| _notrun "kernel does not support sparse inodes"
-	_scratch_unmount
-}
-
 # this test requires that external log/realtime devices are not in use
 #
 _require_nonexternal()
@@ -2093,20 +1793,6 @@  _require_xfs_io_command()
 		_notrun "xfs_io $command doesn't support $param"
 }
 
-# check that xfs_db supports a specific command
-_require_xfs_db_command()
-{
-	if [ $# -ne 1 ]
-	then
-		echo "Usage: _require_xfs_db_command command" 1>&2
-		exit 1
-	fi
-	command=$1
-
-	_scratch_xfs_db -x -c "help" | grep $command > /dev/null || \
-		_notrun "xfs_db $command support is missing"
-}
-
 # check that kernel and filesystem support direct I/O
 _require_odirect()
 {
@@ -2403,150 +2089,6 @@  _check_generic_filesystem()
     return 0
 }
 
-# run xfs_check and friends on a FS.
-
-_check_xfs_filesystem()
-{
-    if [ $# -ne 3 ]
-    then
-	echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2
-	exit 1
-    fi
-
-    extra_mount_options=""
-    extra_log_options=""
-    extra_options=""
-    device=$1
-    if [ -f $device ];then
-       extra_options="-f"
-    fi
-
-    if [ "$2" != "none" ]; then
-	extra_log_options="-l$2"
-        extra_mount_options="-ologdev=$2"
-    fi
-
-    if [ "$3" != "none" ]; then
-	extra_rt_options="-r$3"
-        extra_mount_options=$extra_mount_options" -ortdev=$3"
-    fi
-    extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS"
-
-    [ "$FSTYP" != xfs ] && return 0
-
-    type=`_fs_type $device`
-    ok=1
-
-    if [ "$type" = "xfs" ]
-    then
-        if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then
-            "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full
-            if [ $? -ne 0 ]; then
-                echo "filesystem on $device failed scrub (see $seqres.full)"
-                ok=0
-            fi
-        fi
-        # mounted ...
-        mountpoint=`_umount_or_remount_ro $device`
-    fi
-
-    $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \
-                | tee $tmp.logprint | grep -q "<CLEAN>"
-    if [ $? -ne 0 -a "$HOSTOS" = "Linux" ]
-    then
-        echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)"
-
-        echo "_check_xfs_filesystem: filesystem on $device has dirty log"   >>$seqres.full
-        echo "*** xfs_logprint -t output ***"	>>$seqres.full
-        cat $tmp.logprint			>>$seqres.full
-        echo "*** end xfs_logprint output"	>>$seqres.full
-
-        ok=0
-    fi
-
-    # xfs_check runs out of memory on large files, so even providing the test
-    # option (-t) to avoid indexing the free space trees doesn't make it pass on
-    # large filesystems. Avoid it.
-    if [ "$LARGE_SCRATCH_DEV" != yes ]; then
-	    _xfs_check $extra_log_options $device 2>&1 |\
-		 _fix_malloc >$tmp.fs_check
-    fi
-    if [ -s $tmp.fs_check ]
-    then
-        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)"
-
-        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
-        echo "*** xfs_check output ***"		>>$seqres.full
-        cat $tmp.fs_check			>>$seqres.full
-        echo "*** end xfs_check output"		>>$seqres.full
-
-        ok=0
-    fi
-
-    $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
-    if [ $? -ne 0 ]
-    then
-        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)"
-
-        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
-        echo "*** xfs_repair -n output ***"	>>$seqres.full
-        cat $tmp.repair | _fix_malloc		>>$seqres.full
-        echo "*** end xfs_repair output"	>>$seqres.full
-
-        ok=0
-    fi
-    rm -f $tmp.fs_check $tmp.logprint $tmp.repair
-
-    # Optionally test the index rebuilding behavior.
-    if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then
-        $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
-        if [ $? -ne 0 ]; then
-            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)"
-
-            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full
-            echo "*** xfs_repair output ***"	>>$seqres.full
-            cat $tmp.repair | _fix_malloc		>>$seqres.full
-            echo "*** end xfs_repair output"	>>$seqres.full
-
-            ok=0
-        fi
-        rm -f $tmp.repair
-
-        $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
-        if [ $? -ne 0 ]; then
-            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)"
-
-            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full
-            echo "*** xfs_repair -n output ***"	>>$seqres.full
-            cat $tmp.repair | _fix_malloc		>>$seqres.full
-            echo "*** end xfs_repair output"	>>$seqres.full
-
-            ok=0
-        fi
-        rm -f $tmp.repair
-    fi
-
-    if [ $ok -eq 0 ]
-    then
-        echo "*** mount output ***"		>>$seqres.full
-        _mount					>>$seqres.full
-        echo "*** end mount output"		>>$seqres.full
-    elif [ "$type" = "xfs" ]
-    then
-	_mount_or_remount_rw "$extra_mount_options" $device $mountpoint
-    fi
-
-    if [ $ok -eq 0 ]; then
-	status=1
-	if [ "$iam" != "check" ]; then
-		exit 1
-	fi
-	return 1
-    fi
-
-    return 0
-}
-
 # Filter the knowen errors the UDF Verifier reports.
 _udf_test_known_error_filter()
 {
@@ -2590,26 +2132,6 @@  _check_udf_filesystem()
     return 0
 }
 
-_check_xfs_test_fs()
-{
-    TEST_LOG="none"
-    TEST_RT="none"
-    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
-        TEST_LOG="$TEST_LOGDEV"
-
-    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
-        TEST_RT="$TEST_RTDEV"
-
-    _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT
-
-    # check for ipath consistency
-    if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then
-	# errors go to stderr
-	xfs_check_ipaths $TEST_DIR >/dev/null
-	xfs_repair_ipaths -n $TEST_DIR >/dev/null
-    fi
-}
-
 _check_btrfs_filesystem()
 {
     device=$1
@@ -3382,24 +2904,6 @@  _require_test_fcntl_advisory_locks()
 		_notrun "Require fcntl advisory locks support"
 }
 
-# XFS ability to change UUIDs on V5/CRC filesystems
-#
-_require_meta_uuid()
-{
-	# This will create a crc fs on $SCRATCH_DEV
-	_require_xfs_crc
-
-	_scratch_xfs_db -x -c "uuid restore" 2>&1 \
-	   | grep -q "invalid UUID\|supported on V5 fs" \
-	   && _notrun "Userspace doesn't support meta_uuid feature"
-
-	_scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1
-
-	_scratch_mount >/dev/null 2>&1 \
-	   || _notrun "Kernel doesn't support meta_uuid feature"
-	_scratch_unmount
-}
-
 _require_btrfs_dev_del_by_devid()
 {
 	$BTRFS_UTIL_PROG device delete --help | egrep devid > /dev/null 2>&1
@@ -3416,47 +2920,6 @@  _require_test_lsattr()
 		_notrun "lsattr not supported by test filesystem type: $FSTYP"
 }
 
-_require_xfs_test_rmapbt()
-{
-	_require_test
-
-	if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then
-		_notrun "rmapbt not supported by test filesystem type: $FSTYP"
-	fi
-}
-
-_require_xfs_scratch_rmapbt()
-{
-	_require_scratch
-
-	_scratch_mkfs > /dev/null
-	_scratch_mount
-	if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then
-		_scratch_unmount
-		_notrun "rmapbt not supported by scratch filesystem type: $FSTYP"
-	fi
-	_scratch_unmount
-}
-
-_xfs_bmapx_find() {
-	case "$1" in
-	"attr")
-		param="a"
-		;;
-	"cow")
-		param="c"
-		;;
-	*)
-		param="e"
-		;;
-	esac
-	shift
-	file="$1"
-	shift
-
-	$XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@"
-}
-
 _require_chattr()
 {
     attribute=$1
@@ -3962,80 +3425,6 @@  _get_fs_sysfs_attr()
 }
 
 
-# Reset all xfs error handling attributes, set them to original
-# status.
-#
-# Only one argument, and it's mandatory:
-#  - dev: device name, e.g. $SCRATCH_DEV
-#
-# Note: this function only works for XFS
-_reset_xfs_sysfs_error_handling()
-{
-	local dev=$1
-
-	if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then
-		_fail "Usage: reset_xfs_sysfs_error_handling <device>"
-	fi
-
-	_set_fs_sysfs_attr $dev error/fail_at_unmount 1
-	echo -n "error/fail_at_unmount="
-	_get_fs_sysfs_attr $dev error/fail_at_unmount
-
-	# Make sure all will be configured to retry forever by default, except
-	# for ENODEV, which is an unrecoverable error, so it will be configured
-	# to not retry on error by default.
-	for e in default EIO ENOSPC; do
-		_set_fs_sysfs_attr $dev \
-				   error/metadata/${e}/max_retries -1
-		echo -n "error/metadata/${e}/max_retries="
-		_get_fs_sysfs_attr $dev error/metadata/${e}/max_retries
-
-		_set_fs_sysfs_attr $dev \
-				   error/metadata/${e}/retry_timeout_seconds 0
-		echo -n "error/metadata/${e}/retry_timeout_seconds="
-		_get_fs_sysfs_attr $dev \
-				   error/metadata/${e}/retry_timeout_seconds
-	done
-}
-
-# Skip if we are running an older binary without the stricter input checks.
-# Make multiple checks to be sure that there is no regression on the one
-# selected feature check, which would skew the result.
-#
-# At first, make a common function that runs the tests and returns
-# number of failed cases.
-_xfs_mkfs_validation_check()
-{
-	local tmpfile=`mktemp`
-	local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g"
-
-	$cmd -s size=2s >/dev/null 2>&1
-	local sum=$?
-
-	$cmd -l version=2,su=260k >/dev/null 2>&1
-	sum=`expr $sum + $?`
-
-	rm -f $tmpfile
-	return $sum
-}
-
-# Skip the test if all calls passed - mkfs accepts invalid input
-_require_xfs_mkfs_validation()
-{
-	_xfs_mkfs_validation_check
-	if [ "$?" -eq 0 ]; then
-		_notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7."
-	fi
-}
-
-# The oposite of _require_xfs_mkfs_validation.
-_require_xfs_mkfs_without_validation()
-{
-	_xfs_mkfs_validation_check
-	if [ "$?" -ne 0 ]; then
-		_notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5."
-	fi
-}
 
 init_rc
 
diff --git a/common/xfs b/common/xfs
new file mode 100644
index 000000000000..0dde83f26518
--- /dev/null
+++ b/common/xfs
@@ -0,0 +1,618 @@ 
+#
+# XFS specific common functions.
+#
+
+_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" \
+		-c "chattr +d" \
+		$SCRATCH_MNT/.use_space 2>&1 > /dev/null
+	export NUM_SPACE_FILES=1
+	status=$?
+	_scratch_unmount
+	if [ $status -ne 0 ]; then
+		echo "large file prealloc failed"
+		cat $tmp_dir/mnt.err >&2
+		return $status
+	fi
+	return 0
+}
+
+_scratch_mkfs_xfs_opts()
+{
+	mkfs_opts=$*
+
+	# remove metadata related mkfs options if mkfs.xfs doesn't them
+	if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then
+		mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"`
+	fi
+
+	_scratch_options mkfs
+
+	$MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
+}
+
+
+_scratch_mkfs_xfs_supported()
+{
+	local mkfs_opts=$*
+
+	_scratch_options mkfs
+
+	$MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
+	local mkfs_status=$?
+
+	# a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and
+	# $mkfs_opts, try again without $MKFS_OPTIONS
+	if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then
+		$MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
+		mkfs_status=$?
+	fi
+	return $mkfs_status
+}
+
+_scratch_mkfs_xfs()
+{
+	# extra mkfs options can be added by tests
+	local extra_mkfs_options=$*
+
+	local tmp_dir=/tmp/
+
+	# save mkfs output in case conflict means we need to run again.
+	# only the output for the mkfs that applies should be shown
+	_scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \
+		2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
+	local mkfs_status=$?
+
+
+	# a mkfs failure may be caused by conflicts between
+	# $MKFS_OPTIONS and $extra_mkfs_options
+	if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then
+		(
+		echo -n "** mkfs failed with extra mkfs options "
+		echo "added to \"$MKFS_OPTIONS\" by test $seq **"
+		echo -n "** attempting to mkfs using only test $seq "
+		echo "options: $extra_mkfs_options **"
+		) >> $seqres.full
+
+		# running mkfs again. overwrite previous mkfs output files
+		_scratch_mkfs_xfs_opts $extra_mkfs_options \
+			2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
+		local 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, filtering unnecessary warnings from stderr
+	cat $tmp_dir.mkfsstd
+	cat $tmp_dir.mkfserr | sed \
+		-e '/less than device physical sector/d' \
+		-e '/switching to logical sector/d' \
+		>&2
+	rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd
+
+	return $mkfs_status
+}
+
+# xfs_check script is planned to be deprecated. But, we want to
+# be able to invoke "xfs_check" behavior in xfstests in order to
+# maintain the current verification levels.
+_xfs_check()
+{
+    OPTS=" "
+    DBOPTS=" "
+    USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special"
+
+    while getopts "b:fi:l:stvV" c
+    do
+        case $c in
+            s) OPTS=$OPTS"-s ";;
+            t) OPTS=$OPTS"-t ";;
+            v) OPTS=$OPTS"-v ";;
+            i) OPTS=$OPTS"-i "$OPTARG" ";;
+            b) OPTS=$OPTS"-b "$OPTARG" ";;
+            f) DBOPTS=$DBOPTS" -f";;
+            l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
+            V) $XFS_DB_PROG -p xfs_check -V
+                return $?
+                ;;
+        esac
+    done
+    set -- extra $@
+    shift $OPTIND
+    case $# in
+        1)    ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1
+               status=$?
+               ;;
+        2)    echo $USAGE 1>&1
+              status=2
+              ;;
+    esac
+    return $status
+}
+
+_scratch_xfs_db_options()
+{
+    SCRATCH_OPTIONS=""
+    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
+    echo $SCRATCH_OPTIONS $* $SCRATCH_DEV
+}
+
+_scratch_xfs_db()
+{
+	$XFS_DB_PROG "$@" $(_scratch_xfs_db_options)
+}
+
+_scratch_xfs_logprint()
+{
+    SCRATCH_OPTIONS=""
+    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
+    $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
+}
+
+_test_xfs_logprint()
+{
+	TEST_OPTIONS=""
+	[ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
+		TEST_OPTIONS="-l$TEST_LOGDEV"
+	$XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV
+}
+
+_scratch_xfs_check()
+{
+    SCRATCH_OPTIONS=""
+    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+        SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV"
+    [ "$LARGE_SCRATCH_DEV" = yes ] && \
+        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
+    _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV
+}
+
+_scratch_xfs_repair()
+{
+    SCRATCH_OPTIONS=""
+    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+        SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
+    [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
+        SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV"
+    [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
+    $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
+}
+
+# this test requires the projid32bit feature to be available in mkfs.xfs.
+#
+_require_projid32bit()
+{
+       _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \
+	   || _notrun "mkfs.xfs doesn't have projid32bit feature"
+}
+
+_require_projid16bit()
+{
+	_scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \
+	   || _notrun "16 bit project IDs not supported on $SCRATCH_DEV"
+}
+
+# this test requires the crc feature to be available in mkfs.xfs
+#
+_require_xfs_mkfs_crc()
+{
+	_scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \
+	   || _notrun "mkfs.xfs doesn't have crc feature"
+}
+
+# this test requires the xfs kernel support crc feature
+#
+_require_xfs_crc()
+{
+	_scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1
+	_scratch_mount >/dev/null 2>&1 \
+	   || _notrun "Kernel doesn't support crc feature"
+	_scratch_unmount
+}
+
+# this test requires the xfs kernel support crc feature on scratch device
+#
+_require_scratch_xfs_crc()
+{
+	_scratch_mkfs_xfs >/dev/null 2>&1
+	_scratch_mount >/dev/null 2>&1 \
+	   || _notrun "Kernel doesn't support crc feature"
+	xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem"
+	_scratch_unmount
+}
+
+# this test requires the finobt feature to be available in mkfs.xfs
+#
+_require_xfs_mkfs_finobt()
+{
+	_scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \
+	   || _notrun "mkfs.xfs doesn't have finobt feature"
+}
+
+# this test requires the xfs kernel support finobt feature
+#
+_require_xfs_finobt()
+{
+	_scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1
+	_scratch_mount >/dev/null 2>&1 \
+	   || _notrun "Kernel doesn't support finobt feature"
+	_scratch_unmount
+}
+
+# this test requires xfs sysfs attribute support
+#
+_require_xfs_sysfs()
+{
+	attr=$1
+	sysfsdir=/sys/fs/xfs
+
+	if [ ! -e $sysfsdir ]; then
+		_notrun "no kernel support for XFS sysfs attributes"
+	fi
+
+	if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then
+		_notrun "sysfs attribute '$attr' is not supported"
+	fi
+}
+
+# this test requires the xfs sparse inode feature
+#
+_require_xfs_sparse_inodes()
+{
+	_scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \
+		|| _notrun "mkfs.xfs does not support sparse inodes"
+	_scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1
+	_scratch_mount >/dev/null 2>&1 \
+		|| _notrun "kernel does not support sparse inodes"
+	_scratch_unmount
+}
+
+# check that xfs_db supports a specific command
+_require_xfs_db_command()
+{
+	if [ $# -ne 1 ]
+	then
+		echo "Usage: _require_xfs_db_command command" 1>&2
+		exit 1
+	fi
+	command=$1
+
+	_scratch_xfs_db -x -c "help" | grep $command > /dev/null || \
+		_notrun "xfs_db $command support is missing"
+}
+
+# run xfs_check and friends on a FS.
+_check_xfs_filesystem()
+{
+    if [ $# -ne 3 ]
+    then
+	echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2
+	exit 1
+    fi
+
+    extra_mount_options=""
+    extra_log_options=""
+    extra_options=""
+    device=$1
+    if [ -f $device ];then
+       extra_options="-f"
+    fi
+
+    if [ "$2" != "none" ]; then
+	extra_log_options="-l$2"
+        extra_mount_options="-ologdev=$2"
+    fi
+
+    if [ "$3" != "none" ]; then
+	extra_rt_options="-r$3"
+        extra_mount_options=$extra_mount_options" -ortdev=$3"
+    fi
+    extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS"
+
+    [ "$FSTYP" != xfs ] && return 0
+
+    type=`_fs_type $device`
+    ok=1
+
+    if [ "$type" = "xfs" ]
+    then
+        if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then
+            "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full
+            if [ $? -ne 0 ]; then
+                echo "filesystem on $device failed scrub (see $seqres.full)"
+                ok=0
+            fi
+        fi
+        # mounted ...
+        mountpoint=`_umount_or_remount_ro $device`
+    fi
+
+    $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \
+                | tee $tmp.logprint | grep -q "<CLEAN>"
+    if [ $? -ne 0 -a "$HOSTOS" = "Linux" ]
+    then
+        echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)"
+
+        echo "_check_xfs_filesystem: filesystem on $device has dirty log"   >>$seqres.full
+        echo "*** xfs_logprint -t output ***"	>>$seqres.full
+        cat $tmp.logprint			>>$seqres.full
+        echo "*** end xfs_logprint output"	>>$seqres.full
+
+        ok=0
+    fi
+
+    # xfs_check runs out of memory on large files, so even providing the test
+    # option (-t) to avoid indexing the free space trees doesn't make it pass on
+    # large filesystems. Avoid it.
+    if [ "$LARGE_SCRATCH_DEV" != yes ]; then
+	    _xfs_check $extra_log_options $device 2>&1 |\
+		 _fix_malloc >$tmp.fs_check
+    fi
+    if [ -s $tmp.fs_check ]
+    then
+        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)"
+
+        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
+        echo "*** xfs_check output ***"		>>$seqres.full
+        cat $tmp.fs_check			>>$seqres.full
+        echo "*** end xfs_check output"		>>$seqres.full
+
+        ok=0
+    fi
+
+    $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
+    if [ $? -ne 0 ]
+    then
+        echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)"
+
+        echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
+        echo "*** xfs_repair -n output ***"	>>$seqres.full
+        cat $tmp.repair | _fix_malloc		>>$seqres.full
+        echo "*** end xfs_repair output"	>>$seqres.full
+
+        ok=0
+    fi
+    rm -f $tmp.fs_check $tmp.logprint $tmp.repair
+
+    # Optionally test the index rebuilding behavior.
+    if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then
+        $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
+        if [ $? -ne 0 ]; then
+            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)"
+
+            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full
+            echo "*** xfs_repair output ***"	>>$seqres.full
+            cat $tmp.repair | _fix_malloc		>>$seqres.full
+            echo "*** end xfs_repair output"	>>$seqres.full
+
+            ok=0
+        fi
+        rm -f $tmp.repair
+
+        $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
+        if [ $? -ne 0 ]; then
+            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)"
+
+            echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full
+            echo "*** xfs_repair -n output ***"	>>$seqres.full
+            cat $tmp.repair | _fix_malloc		>>$seqres.full
+            echo "*** end xfs_repair output"	>>$seqres.full
+
+            ok=0
+        fi
+        rm -f $tmp.repair
+    fi
+
+    if [ $ok -eq 0 ]
+    then
+        echo "*** mount output ***"		>>$seqres.full
+        _mount					>>$seqres.full
+        echo "*** end mount output"		>>$seqres.full
+    elif [ "$type" = "xfs" ]
+    then
+	_mount_or_remount_rw "$extra_mount_options" $device $mountpoint
+    fi
+
+    if [ $ok -eq 0 ]; then
+	status=1
+	if [ "$iam" != "check" ]; then
+		exit 1
+	fi
+	return 1
+    fi
+
+    return 0
+}
+
+_check_xfs_test_fs()
+{
+    TEST_LOG="none"
+    TEST_RT="none"
+    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
+        TEST_LOG="$TEST_LOGDEV"
+
+    [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
+        TEST_RT="$TEST_RTDEV"
+
+    _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT
+
+    # check for ipath consistency
+    if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then
+	# errors go to stderr
+	xfs_check_ipaths $TEST_DIR >/dev/null
+	xfs_repair_ipaths -n $TEST_DIR >/dev/null
+    fi
+}
+
+_require_xfs_test_rmapbt()
+{
+	_require_test
+
+	if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then
+		_notrun "rmapbt not supported by test filesystem type: $FSTYP"
+	fi
+}
+
+_require_xfs_scratch_rmapbt()
+{
+	_require_scratch
+
+	_scratch_mkfs > /dev/null
+	_scratch_mount
+	if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then
+		_scratch_unmount
+		_notrun "rmapbt not supported by scratch filesystem type: $FSTYP"
+	fi
+	_scratch_unmount
+}
+
+_xfs_bmapx_find() {
+	case "$1" in
+	"attr")
+		param="a"
+		;;
+	"cow")
+		param="c"
+		;;
+	*)
+		param="e"
+		;;
+	esac
+	shift
+	file="$1"
+	shift
+
+	$XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@"
+}
+
+# Reset all xfs error handling attributes, set them to original
+# status.
+#
+# Only one argument, and it's mandatory:
+#  - dev: device name, e.g. $SCRATCH_DEV
+#
+# Note: this function only works for XFS
+_reset_xfs_sysfs_error_handling()
+{
+	local dev=$1
+
+	if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then
+		_fail "Usage: reset_xfs_sysfs_error_handling <device>"
+	fi
+
+	_set_fs_sysfs_attr $dev error/fail_at_unmount 1
+	echo -n "error/fail_at_unmount="
+	_get_fs_sysfs_attr $dev error/fail_at_unmount
+
+	# Make sure all will be configured to retry forever by default, except
+	# for ENODEV, which is an unrecoverable error, so it will be configured
+	# to not retry on error by default.
+	for e in default EIO ENOSPC; do
+		_set_fs_sysfs_attr $dev \
+				   error/metadata/${e}/max_retries -1
+		echo -n "error/metadata/${e}/max_retries="
+		_get_fs_sysfs_attr $dev error/metadata/${e}/max_retries
+
+		_set_fs_sysfs_attr $dev \
+				   error/metadata/${e}/retry_timeout_seconds 0
+		echo -n "error/metadata/${e}/retry_timeout_seconds="
+		_get_fs_sysfs_attr $dev \
+				   error/metadata/${e}/retry_timeout_seconds
+	done
+}
+
+# Skip if we are running an older binary without the stricter input checks.
+# Make multiple checks to be sure that there is no regression on the one
+# selected feature check, which would skew the result.
+#
+# At first, make a common function that runs the tests and returns
+# number of failed cases.
+_xfs_mkfs_validation_check()
+{
+	local tmpfile=`mktemp`
+	local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g"
+
+	$cmd -s size=2s >/dev/null 2>&1
+	local sum=$?
+
+	$cmd -l version=2,su=260k >/dev/null 2>&1
+	sum=`expr $sum + $?`
+
+	rm -f $tmpfile
+	return $sum
+}
+
+# Skip the test if all calls passed - mkfs accepts invalid input
+_require_xfs_mkfs_validation()
+{
+	_xfs_mkfs_validation_check
+	if [ "$?" -eq 0 ]; then
+		_notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7."
+	fi
+}
+
+# The opposite of _require_xfs_mkfs_validation.
+_require_xfs_mkfs_without_validation()
+{
+	_xfs_mkfs_validation_check
+	if [ "$?" -ne 0 ]; then
+		_notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5."
+	fi
+}
+
+# XFS ability to change UUIDs on V5/CRC filesystems
+#
+_require_meta_uuid()
+{
+	# This will create a crc fs on $SCRATCH_DEV
+	_require_xfs_crc
+
+	_scratch_xfs_db -x -c "uuid restore" 2>&1 \
+	   | grep -q "invalid UUID\|supported on V5 fs" \
+	   && _notrun "Userspace doesn't support meta_uuid feature"
+
+	_scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1
+
+	_scratch_mount >/dev/null 2>&1 \
+	   || _notrun "Kernel doesn't support meta_uuid feature"
+	_scratch_unmount
+}