dd()
{
- if [ "$HOSTOS" == "Linux" ]
- then
command dd --help 2>&1 | grep noxfer >/dev/null
-
if [ "$?" -eq 0 ]
then
command dd status=noxfer $@
else
command dd $@
- fi
- else
- command dd $@
- fi
+ fi
}
# Prints the md5 checksum of a given file
9p)
;;
ceph)
+ . ./common/ceph
;;
glusterfs)
;;
stat -c %s "$1"
}
+# Get hugepagesize in bytes
+_get_hugepagesize()
+{
+ local hugepgsz=$(awk '/Hugepagesize/ {print $2}' /proc/meminfo)
+ # Call _notrun if $hugepgsz is not a number
+ echo "$hugepgsz" | egrep -q ^[0-9]+$ || \
+ _notrun "Cannot get the value of Hugepagesize"
+ echo $((hugepgsz * 1024))
+}
+
_mount()
{
$MOUNT_PROG `_mount_ops_filter $*`
_scratch_mkfs_ext4()
{
local mkfs_cmd="$MKFS_EXT4_PROG -F"
- local mkfs_filter="grep -v -e ^Warning: -e \"^mke2fs \""
+ local mkfs_filter="grep -v -e ^Warning: -e \"^mke2fs \" | grep -v \"^$\""
local tmp=`mktemp -u`
local mkfs_status
# _scratch_mkfs_sized <size in bytes> [optional blocksize]
_scratch_mkfs_sized()
{
- local fssize=$1
- local blocksize=$2
- local def_blksz
-
- case $FSTYP in
- xfs)
- def_blksz=`echo $MKFS_OPTIONS|sed -rn 's/.*-b ?size= ?+([0-9]+).*/\1/p'`
- ;;
- ext2|ext3|ext4|ext4dev|udf|btrfs|reiser4|ocfs2|reiserfs)
- def_blksz=`echo $MKFS_OPTIONS| sed -rn 's/.*-b ?+([0-9]+).*/\1/p'`
- ;;
- jfs)
- def_blksz=4096
- ;;
- esac
+ local fssize=$1
+ local blocksize=$2
+ local def_blksz
- [ -n "$def_blksz" ] && blocksize=$def_blksz
- [ -z "$blocksize" ] && blocksize=4096
+ case $FSTYP in
+ xfs)
+ def_blksz=`echo $MKFS_OPTIONS | sed -rn 's/.*-b ?size= ?+([0-9]+).*/\1/p'`
+ ;;
+ ext2|ext3|ext4|ext4dev|udf|btrfs|reiser4|ocfs2|reiserfs)
+ def_blksz=`echo $MKFS_OPTIONS | sed -rn 's/.*-b ?+([0-9]+).*/\1/p'`
+ ;;
+ jfs)
+ def_blksz=4096
+ ;;
+ esac
+ [ -n "$def_blksz" ] && blocksize=$def_blksz
+ [ -z "$blocksize" ] && blocksize=4096
- local re='^[0-9]+$'
- if ! [[ $fssize =~ $re ]] ; then
- _notrun "error: _scratch_mkfs_sized: fs size \"$fssize\" not an integer."
- fi
- if ! [[ $blocksize =~ $re ]] ; then
- _notrun "error: _scratch_mkfs_sized: block size \"$blocksize\" not an integer."
- fi
-
- local blocks=`expr $fssize / $blocksize`
+ local re='^[0-9]+$'
+ if ! [[ $fssize =~ $re ]] ; then
+ _notrun "error: _scratch_mkfs_sized: fs size \"$fssize\" not an integer."
+ fi
+ if ! [[ $blocksize =~ $re ]] ; then
+ _notrun "error: _scratch_mkfs_sized: block size \"$blocksize\" not an integer."
+ fi
- if [ "$HOSTOS" == "Linux" -a -b "$SCRATCH_DEV" ]; then
- local devsize=`blockdev --getsize64 $SCRATCH_DEV`
- [ "$fssize" -gt "$devsize" ] && _notrun "Scratch device too small"
- fi
+ local blocks=`expr $fssize / $blocksize`
- case $FSTYP in
- xfs)
- # don't override MKFS_OPTIONS that set a block size.
- echo $MKFS_OPTIONS |egrep -q "b?size="
- if [ $? -eq 0 ]; then
- _scratch_mkfs_xfs -d size=$fssize
- else
- _scratch_mkfs_xfs -d size=$fssize -b size=$blocksize
+ if [ -b "$SCRATCH_DEV" ]; then
+ local devsize=`blockdev --getsize64 $SCRATCH_DEV`
+ [ "$fssize" -gt "$devsize" ] && _notrun "Scratch device too small"
fi
- ;;
- ext2|ext3|ext4|ext4dev)
- ${MKFS_PROG}.$FSTYP -F $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
- ;;
- gfs2)
- # mkfs.gfs2 doesn't automatically shrink journal files on small
- # filesystems, so the journal files may end up being bigger than the
- # filesystem, which will cause mkfs.gfs2 to fail. Until that's fixed,
- # shrink the journal size to at most one eigth of the filesystem and at
- # least 8 MiB, the minimum size allowed.
- local min_journal_size=8
- local default_journal_size=128
- if (( fssize/8 / (1024*1024) < default_journal_size )); then
- local journal_size=$(( fssize/8 / (1024*1024) ))
- (( journal_size >= min_journal_size )) || journal_size=$min_journal_size
- MKFS_OPTIONS="-J $journal_size $MKFS_OPTIONS"
- fi
- ${MKFS_PROG}.$FSTYP $MKFS_OPTIONS -O -b $blocksize $SCRATCH_DEV $blocks
- ;;
- ocfs2)
- yes | ${MKFS_PROG}.$FSTYP -F $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
- ;;
- udf)
- $MKFS_UDF_PROG $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
- ;;
- btrfs)
- local mixed_opt=
- # minimum size that's needed without the mixed option.
- # Ref: btrfs-prog: btrfs_min_dev_size()
- # Non mixed mode is also the default option.
- (( fssize < $((256 * 1024 *1024)) )) && mixed_opt='--mixed'
- $MKFS_BTRFS_PROG $MKFS_OPTIONS $mixed_opt -b $fssize $SCRATCH_DEV
- ;;
- jfs)
- ${MKFS_PROG}.$FSTYP $MKFS_OPTIONS $SCRATCH_DEV $blocks
- ;;
- reiserfs)
- ${MKFS_PROG}.$FSTYP $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
- ;;
- reiser4)
- # mkfs.resier4 requires size in KB as input for creating filesystem
- $MKFS_REISER4_PROG $MKFS_OPTIONS -y -b $blocksize $SCRATCH_DEV \
- `expr $fssize / 1024`
- ;;
- f2fs)
- # mkfs.f2fs requires # of sectors as an input for the size
- local sector_size=`blockdev --getss $SCRATCH_DEV`
- $MKFS_F2FS_PROG $MKFS_OPTIONS $SCRATCH_DEV `expr $fssize / $sector_size`
- ;;
- tmpfs)
- local free_mem=`_free_memory_bytes`
- if [ "$free_mem" -lt "$fssize" ] ; then
- _notrun "Not enough memory ($free_mem) for tmpfs with $fssize bytes"
+
+ if [ "$FSTYP" = "xfs" ] && [ -b "$SCRATCH_RTDEV" ]; then
+ local rtdevsize=`blockdev --getsize64 $SCRATCH_RTDEV`
+ [ "$fssize" -gt "$rtdevsize" ] && _notrun "Scratch rt device too small"
+ rt_ops="-r size=$fssize"
fi
- export MOUNT_OPTIONS="-o size=$fssize $TMPFS_MOUNT_OPTIONS"
- ;;
- *)
- _notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized"
- ;;
- esac
+
+ case $FSTYP in
+ xfs)
+ # don't override MKFS_OPTIONS that set a block size.
+ echo $MKFS_OPTIONS |egrep -q "b?size="
+ if [ $? -eq 0 ]; then
+ _scratch_mkfs_xfs -d size=$fssize $rt_ops
+ else
+ _scratch_mkfs_xfs -d size=$fssize $rt_ops -b size=$blocksize
+ fi
+ ;;
+ ext2|ext3|ext4|ext4dev)
+ ${MKFS_PROG}.$FSTYP -F $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
+ ;;
+ gfs2)
+ # mkfs.gfs2 doesn't automatically shrink journal files on small
+ # filesystems, so the journal files may end up being bigger than the
+ # filesystem, which will cause mkfs.gfs2 to fail. Until that's fixed,
+ # shrink the journal size to at most one eigth of the filesystem and at
+ # least 8 MiB, the minimum size allowed.
+ local min_journal_size=8
+ local default_journal_size=128
+ if (( fssize/8 / (1024*1024) < default_journal_size )); then
+ local journal_size=$(( fssize/8 / (1024*1024) ))
+ (( journal_size >= min_journal_size )) || journal_size=$min_journal_size
+ MKFS_OPTIONS="-J $journal_size $MKFS_OPTIONS"
+ fi
+ ${MKFS_PROG}.$FSTYP $MKFS_OPTIONS -O -b $blocksize $SCRATCH_DEV $blocks
+ ;;
+ ocfs2)
+ yes | ${MKFS_PROG}.$FSTYP -F $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
+ ;;
+ udf)
+ $MKFS_UDF_PROG $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
+ ;;
+ btrfs)
+ local mixed_opt=
+ # minimum size that's needed without the mixed option.
+ # Ref: btrfs-prog: btrfs_min_dev_size()
+ # Non mixed mode is also the default option.
+ (( fssize < $((256 * 1024 *1024)) )) && mixed_opt='--mixed'
+ $MKFS_BTRFS_PROG $MKFS_OPTIONS $mixed_opt -b $fssize $SCRATCH_DEV
+ ;;
+ jfs)
+ ${MKFS_PROG}.$FSTYP $MKFS_OPTIONS $SCRATCH_DEV $blocks
+ ;;
+ reiserfs)
+ ${MKFS_PROG}.$FSTYP $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
+ ;;
+ reiser4)
+ # mkfs.resier4 requires size in KB as input for creating filesystem
+ $MKFS_REISER4_PROG $MKFS_OPTIONS -y -b $blocksize $SCRATCH_DEV \
+ `expr $fssize / 1024`
+ ;;
+ f2fs)
+ # mkfs.f2fs requires # of sectors as an input for the size
+ local sector_size=`blockdev --getss $SCRATCH_DEV`
+ $MKFS_F2FS_PROG $MKFS_OPTIONS $SCRATCH_DEV `expr $fssize / $sector_size`
+ ;;
+ tmpfs)
+ local free_mem=`_free_memory_bytes`
+ if [ "$free_mem" -lt "$fssize" ] ; then
+ _notrun "Not enough memory ($free_mem) for tmpfs with $fssize bytes"
+ fi
+ export MOUNT_OPTIONS="-o size=$fssize $TMPFS_MOUNT_OPTIONS"
+ ;;
+ *)
+ _notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized"
+ ;;
+ esac
}
# Emulate an N-data-disk stripe w/ various stripe units
case $FSTYP in
xfs)
- MKFS_OPTIONS+=" -b size=$blocksize, -d su=$sunit_bytes,sw=$swidth_mult"
+ if echo "$MKFS_OPTIONS" | egrep -q "b?size="; then
+ MKFS_OPTIONS=$(echo "$MKFS_OPTIONS" | sed -r "s/(b?size=)[0-9]+/\1$blocksize/")
+ else
+ MKFS_OPTIONS+=" -b size=$blocksize"
+ fi
+
+ if echo "$MKFS_OPTIONS" | egrep -q "(su|sunit|sw|swidth)="; then
+ MKFS_OPTIONS=$(echo "$MKFS_OPTIONS" | sed -r \
+ -e "s/(su|sunit)=[0-9kmg]+/su=$sunit_bytes/" \
+ -e "s/(sw|swidth)=[0-9kmg]+/sw=$swidth_mult/")
+ else
+ MKFS_OPTIONS+=" -d su=$sunit_bytes,sw=$swidth_mult"
+ fi
;;
ext4|ext4dev)
MKFS_OPTIONS+=" -b $blocksize -E stride=$sunit_blocks,stripe_width=$swidth_blocks"
_notrun "not suitable for this filesystem type: $FSTYP"
}
-
-# tests whether $FSTYP is one of the supported OSes for a test
-#
-_supported_os()
-{
- local h
-
- for h
- do
- if [ "$h" = "$HOSTOS" ]
- then
- return
- fi
- done
-
- _notrun "not suitable for this OS: $HOSTOS"
-}
-
# check if a FS on a device is mounted
# if so, verify that it is mounted on mount point
# if fstype is given as argument, verify that it is also
#
_require_loop()
{
- if [ "$HOSTOS" != "Linux" ]
- then
- _notrun "This test requires linux for loopback device support"
- fi
-
modprobe loop >/dev/null 2>&1
if grep loop /proc/devices >/dev/null 2>&1
then
#
_require_ext2()
{
- if [ "$HOSTOS" != "Linux" ]
- then
- _notrun "This test requires linux for ext2 filesystem support"
- fi
-
modprobe ext2 >/dev/null 2>&1
if grep ext2 /proc/filesystems >/dev/null 2>&1
then
_require_sane_bdev_flush $SCRATCH_DEV
_require_command "$DMSETUP_PROG" dmsetup
- echo $MOUNT_OPTIONS | grep -q dax
+ _normalize_mount_options | egrep -q "dax(=always| |$)"
if [ $? -eq 0 ]; then
case $target in
stripe|linear|log-writes)
local param="$*"
local param_checked=""
local opts=""
+ local attr_info=""
local testfile=$TEST_DIR/$$.xfs_io
local testio
case $command in
+ "lsattr")
+ # Test xfs_io lsattr support and filesystem FS_IOC_FSSETXATTR
+ # support.
+ testio=`$XFS_IO_PROG -F -f -c "lsattr $param" $testfile 2>&1`
+ param_checked="$param"
+ ;;
"chattr")
+ local testdir=$TEST_DIR/$$.attr_dir
+ mkdir $TEST_DIR/$$.attr_dir
if [ -z "$param" ]; then
param=s
fi
# Test xfs_io chattr support AND
# filesystem FS_IOC_FSSETXATTR support
- testio=`$XFS_IO_PROG -F -f -c "chattr +$param" $testfile 2>&1`
- $XFS_IO_PROG -F -f -r -c "chattr -$param" $testfile 2>&1
+ # 'tPnE' flags are only valid for a directory so check them on a directory.
+ if echo "$param" | egrep -q 't|P|n|E'; then
+ testio=`$XFS_IO_PROG -F -c "chattr +$param" $testdir 2>&1`
+ attr_info=`$XFS_IO_PROG -F -r -c "lsattr" $testdir | awk '{print $1}'`
+ $XFS_IO_PROG -F -r -c "chattr -$param" $testdir 2>&1
+ else
+ testio=`$XFS_IO_PROG -F -f -c "chattr +$param" $testfile 2>&1`
+ attr_info=`$XFS_IO_PROG -F -r -c "lsattr" $testfile | awk '{print $1}'`
+ $XFS_IO_PROG -F -r -c "chattr -$param" $testfile 2>&1
+ fi
param_checked="+$param"
+ rm -rf $testdir 2>&1 > /dev/null
;;
"chproj")
testio=`$XFS_IO_PROG -F -f -c "chproj 0" $testfile 2>&1`
_notrun "xfs_io $command $param_checked not supported on $FSTYP"
echo $testio | grep -q "Function not implemented" && \
_notrun "xfs_io $command $param_checked support is missing (missing syscall?)"
+ echo $testio | grep -q "unknown flag" && \
+ _notrun "xfs_io $command $param_checked support is missing (unknown flag)"
[ -n "$param" ] || return
echo $testio | grep -q "\(invalid option\|not supported\)" && \
_notrun "xfs_io $command doesn't support $param"
fi
+
+ # On XFS, ioctl(FSSETXATTR)(called by xfs_io -c "chattr") maskes off unsupported
+ # or invalid flags silently so need to check these flags by extra ioctl(FSGETXATTR)
+ # (called by xfs_io -c "lsattr").
+ # The following URL explains why we don't change the behavior of XFS.
+ # https://www.spinics.net/lists/linux-xfs/msg44725.html
+ if [ -n "$attr_info" -a "$FSTYP" = "xfs" ]; then
+ local num=${#param}
+ for i in $(seq 0 $((num-1))); do
+ echo $attr_info | grep -q "${param:$i:1}" || \
+ _notrun "xfs_io $command +${param:$i:1} support is missing (unknown flag in kernel)"
+ done
+ fi
}
# check that kernel and filesystem support direct I/O
_require_scratch
_require_command "$MKSWAP_PROG" "mkswap"
- _scratch_mkfs >/dev/null
+ _scratch_mkfs >/dev/null 2>&1
# With mounting SELinux context(e.g. system_u:object_r:root_t:s0),
# standard mkswap tried to reset the type of default context to
_scratch_unmount
}
-# Does dax mount option work on this dev/fs?
-_require_scratch_dax()
+_check_s_dax()
+{
+ local target=$1
+ local exp_s_dax=$2
+
+ local attributes=$($XFS_IO_PROG -c 'statx -r' $target | awk '/stat.attributes / { print $3 }')
+ if [ $exp_s_dax -eq 0 ]; then
+ (( attributes & 0x2000 )) && echo "$target has unexpected S_DAX flag"
+ else
+ (( attributes & 0x2000 )) || echo "$target doesn't have expected S_DAX flag"
+ fi
+}
+
+_check_xflag()
+{
+ local target=$1
+ local exp_xflag=$2
+
+ if [ $exp_xflag -eq 0 ]; then
+ _test_inode_flag dax $target && echo "$target has unexpected FS_XFLAG_DAX flag"
+ else
+ _test_inode_flag dax $target || echo "$target doesn't have expected FS_XFLAG_DAX flag"
+ fi
+}
+
+# Check if dax mount options are supported
+#
+# $1 can be either 'dax=always' or 'dax'
+#
+# dax=always
+# Check for the new dax options (dax=inode, dax=always or dax=never)
+# by passing "dax=always".
+# dax
+# Check for the old dax or new dax=always by passing "dax".
+#
+# This only accepts 'dax=always' because dax=always, dax=inode and
+# dax=never are always supported together. So if the other options are
+# required checking for 'dax=always' indicates support for the other 2.
+#
+# Return 0 if filesystem/device supports the specified dax option.
+# Return 1 if mount fails with the specified dax option.
+# Return 2 if /proc/mounts shows wrong dax option.
+_check_scratch_dax_mountopt()
{
+ local option=$1
+
_require_scratch
_scratch_mkfs > /dev/null 2>&1
- _try_scratch_mount -o dax || \
- _notrun "mount $SCRATCH_DEV with dax failed"
- # Check options to be sure. XFS ignores dax option
- # and goes on if dev underneath does not support dax.
- _fs_options $SCRATCH_DEV | grep -qw "dax" || \
- _notrun "$SCRATCH_DEV $FSTYP does not support -o dax"
- _scratch_unmount
+
+ _try_scratch_mount "-o $option" > /dev/null 2>&1 || return 1
+
+ if _fs_options $SCRATCH_DEV | egrep -q "dax(=always|,|$)"; then
+ _scratch_unmount
+ return 0
+ else
+ _scratch_unmount
+ return 2
+ fi
+}
+
+# Throw notrun if _check_scratch_dax_mountopt() returns a non-zero value.
+_require_scratch_dax_mountopt()
+{
+ local mountopt=$1
+
+ _check_scratch_dax_mountopt "$mountopt"
+ local res=$?
+
+ [ $res -eq 1 ] && _notrun "mount $SCRATCH_DEV with $mountopt failed"
+ [ $res -eq 2 ] && _notrun "$SCRATCH_DEV $FSTYP does not support -o $mountopt"
+}
+
+_require_dax_iflag()
+{
+ _require_xfs_io_command "chattr" "x"
}
# Does norecovery support by this fs?
}
# skip test if MOUNT_OPTIONS contains the given strings
+# Both dax and dax=always are excluded if dax or dax=always is passed
_exclude_scratch_mount_option()
{
local mnt_opts=$(_normalize_mount_options)
while [ $# -gt 0 ]; do
- if echo $mnt_opts | grep -qw "$1"; then
+ local pattern=$1
+ echo "$pattern" | egrep -q "dax(=always|$)" && \
+ pattern="dax(=always| |$)"
+ if echo $mnt_opts | egrep -q "$pattern"; then
_notrun "mount option \"$1\" not allowed in this test"
fi
shift
$ACCTON_PROG off >> $seqres.full
}
+_require_sysctl_variable()
+{
+ local name=$1
+ sysctl $name &>/dev/null || _notrun "$name sysctl unavailable"
+}
+
+_require_mknod()
+{
+ mknod $TEST_DIR/$seq.null c 1 3 \
+ || _notrun "$FSTYP does not support mknod/mkfifo"
+ rm -f $TEST_DIR/$seq.null
+}
+
+_getcap()
+{
+ $GETCAP_PROG "$@" | _filter_getcap
+ return ${PIPESTATUS[0]}
+}
+
init_rc
################################################################################