_try_scratch_mount $* || _fail "mount failed"
}
+_scratch_mount_idmapped()
+{
+ local type="$1"
+ local id="$2"
+
+ if [ "$type" = "u" ]; then
+ # This means root will be able to create files as uid %id in
+ # the underlying filesystem by going through the idmapped mount.
+ $here/src/idmapped-mounts/mount-idmapped --map-mount u:0:$id:1 \
+ --map-mount u:$id:0:1 \
+ --map-mount g:0:0:1 \
+ "$SCRATCH_MNT" "$SCRATCH_MNT" || _fail "mount-idmapped failed"
+ elif [ "$type" = "g" ]; then
+ # This means root will be able to create files as gid %id in
+ # the underlying filesystem by going through the idmapped mount.
+ $here/src/idmapped-mounts/mount-idmapped --map-mount g:0:$id:1 \
+ --map-mount g:$id:0:1 \
+ --map-mount u:0:0:1 \
+ "$SCRATCH_MNT" "$SCRATCH_MNT" || _fail "mount-idmapped failed"
+ elif [ "$type" = "b" ]; then
+ # This means root will be able to create files as uid and gid
+ # %id in the underlying filesystem by going through the idmapped mount.
+ $here/src/idmapped-mounts/mount-idmapped --map-mount b:0:$id:1 \
+ --map-mount b:$id:0:1 \
+ "$SCRATCH_MNT" "$SCRATCH_MNT" || _fail "mount-idmapped failed"
+ else
+ _fail "usage: either \"u\" (uid), \"g\" (gid), or \"b\" (uid and gid) must be specified "
+ fi
+}
+
_scratch_unmount()
{
case "$FSTYP" in
esac
}
+_scratch_umount_idmapped()
+{
+ $UMOUNT_PROG $SCRATCH_MNT
+}
+
_scratch_remount()
{
local opts="$1"
test -n "$E2IMAGE_PROG" || _fail "e2image not installed"
$E2IMAGE_PROG -Q "$device" "$dumpfile"
[ "$compressopt" = "compress" ] && [ -n "$DUMP_COMPRESSOR" ] &&
- $DUMP_COMPRESSOR "$dumpfile" &>> "$seqres.full"
+ $DUMP_COMPRESSOR -f "$dumpfile" &>> "$seqres.full"
}
_test_mkfs()
fi
export MOUNT_OPTIONS="-o size=$fssize $TMPFS_MOUNT_OPTIONS"
;;
+ bcachefs)
+ $MKFS_PROG -t $FSTYP -- $MKFS_OPTIONS --fs_size=$fssize --block_size=$blocksize $SCRATCH_DEV
+ ;;
*)
_notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized"
;;
# _scratch_mkfs_blocksized blocksize
_scratch_mkfs_blocksized()
{
- local blocksize=$1
+ local blocksize=$1
- local re='^[0-9]+$'
- if ! [[ $blocksize =~ $re ]] ; then
- _notrun "error: _scratch_mkfs_sized: block size \"$blocksize\" not an integer."
- fi
+ local re='^[0-9]+$'
+ if ! [[ $blocksize =~ $re ]] ; then
+ _notrun "error: _scratch_mkfs_sized: block size \"$blocksize\" not an integer."
+ fi
- case $FSTYP in
- xfs)
- _scratch_mkfs_xfs $MKFS_OPTIONS -b size=$blocksize
- ;;
- ext2|ext3|ext4)
- ${MKFS_PROG} -t $FSTYP -F $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV
- ;;
- gfs2)
- ${MKFS_PROG} -t $FSTYP $MKFS_OPTIONS -O -b $blocksize $SCRATCH_DEV
- ;;
- ocfs2)
- yes | ${MKFS_PROG} -t $FSTYP -F $MKFS_OPTIONS -b $blocksize -C $blocksize $SCRATCH_DEV
- ;;
- *)
- _notrun "Filesystem $FSTYP not supported in _scratch_mkfs_blocksized"
- ;;
- esac
+ case $FSTYP in
+ btrfs)
+ test -f /sys/fs/btrfs/features/supported_sectorsizes || \
+ _notrun "Subpage sectorsize support is not found in $FSTYP"
+
+ grep -wq $blocksize /sys/fs/btrfs/features/supported_sectorsizes || \
+ _notrun "$FSTYP does not support sectorsize=$blocksize yet"
+
+ _scratch_mkfs --sectorsize=$blocksize
+ ;;
+ xfs)
+ _scratch_mkfs_xfs $MKFS_OPTIONS -b size=$blocksize
+ ;;
+ ext2|ext3|ext4)
+ ${MKFS_PROG} -t $FSTYP -F $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV
+ ;;
+ gfs2)
+ ${MKFS_PROG} -t $FSTYP $MKFS_OPTIONS -O -b $blocksize $SCRATCH_DEV
+ ;;
+ ocfs2)
+ yes | ${MKFS_PROG} -t $FSTYP -F $MKFS_OPTIONS -b $blocksize \
+ -C $blocksize $SCRATCH_DEV
+ ;;
+ bcachefs)
+ ${MKFS_PROG} -t $FSTYP $MKFS_OPTIONS --block_size=$blocksize \
+ $SCRATCH_DEV
+ ;;
+ *)
+ _notrun "Filesystem $FSTYP not supported in _scratch_mkfs_blocksized"
+ ;;
+ esac
}
_scratch_resvblks()
fi
return $res
;;
+ bcachefs)
+ # With bcachefs, if fsck detects any errors we consider it a bug and we
+ # want the test to fail:
+ _check_scratch_fs
+ ;;
*)
local dev=$SCRATCH_DEV
local fstyp=$FSTYP
[ $devsize -lt $1 ] && _notrun "scratch dev too small"
}
-# require scratch fs which supports >16T of filesystem size.
+# Require scratch fs which supports >16T of filesystem size.
+# _require_scratch must be called before this function is called.
_require_scratch_16T_support()
{
case $FSTYP in
fi
}
-# this test requires ext2 filesystem support
+# this test requires kernel support for a secondary filesystem
#
-_require_ext2()
+_require_extra_fs()
{
- modprobe ext2 >/dev/null 2>&1
- if grep ext2 /proc/filesystems >/dev/null 2>&1
- then
- :
- else
- _notrun "This test requires ext2 filesystem support"
- fi
-}
-
-# this test requires tmpfs filesystem support
-#
-_require_tmpfs()
-{
- modprobe tmpfs >/dev/null 2>&1
- grep -q tmpfs /proc/filesystems ||
- _notrun "this test requires tmpfs support"
+ modprobe "$1" >/dev/null 2>&1
+ grep -q -w "$1" /proc/filesystems ||
+ _notrun "this test requires $1 support"
}
# this test requires that (large) loopback device files are not in use
fi
}
+_zone_type()
+{
+ local target=$1
+ if [ -z $target ]; then
+ echo "Usage: _zone_type <device>"
+ exit 1
+ fi
+ local sdev=`_short_dev $target`
+
+ if [ -e /sys/block/${sdev}/queue/zoned ]; then
+ cat /sys/block/${sdev}/queue/zoned
+ else
+ echo none
+ fi
+}
+
+_require_zoned_device()
+{
+ local target=$1
+ if [ -z $target ]; then
+ echo "Usage: _require_zoned_device <device>"
+ exit 1
+ fi
+
+ local type=`_zone_type ${target}`
+ if [ "${type}" = "none" ]; then
+ _notrun "this test require zoned block device"
+ fi
+}
+
+_require_non_zoned_device()
+{
+ local target=$1
+ if [ -z $target ]; then
+ echo "Usage: _require_non_zoned_device <device>"
+ exit 1
+ fi
+
+ local type=`_zone_type ${target}`
+ if [ "${type}" != "none" ]; then
+ _notrun "this test require non-zoned block device"
+ fi
+}
+
# this test requires the ext4 kernel support crc feature on scratch device
#
_require_scratch_ext4_crc()
esac
}
+# test whether the mount_setattr syscall is available
+_require_mount_setattr()
+{
+ $here/src/feature -r
+ case $? in
+ 0)
+ ;;
+ 1)
+ _notrun "kernel does not support mount_setattr syscall"
+ ;;
+ *)
+ _fail "unexpected error testing for mount_setattr support"
+ ;;
+ esac
+}
+
+# test whether idmapped mounts are supported
+_require_idmapped_mounts()
+{
+ IDMAPPED_MOUNTS_TEST=$here/src/idmapped-mounts/idmapped-mounts
+ [ -x $IDMAPPED_MOUNTS_TEST ] || _notrun "idmapped-mounts utilities required"
+
+ _require_mount_setattr
+
+ $here/src/idmapped-mounts/idmapped-mounts --supported \
+ --device "$TEST_DEV" \
+ --mount "$TEST_DIR" \
+ --fstype "$FSTYP"
+
+ if [ $? -ne 0 ]; then
+ _notrun "idmapped-mounts not support by $FSTYP"
+ fi
+}
+
# this test requires that a test program exists under src/
# $1 - command (require)
#
echo "0 $u32max"
;;
xfs)
- echo "$s32min $s32max"
+ _xfs_timestamp_range "$device"
;;
btrfs)
echo "$s64min $s64max"
[ "$?" == "0" ] || _notrun "$qa_user cannot execute commands."
}
+# check for a chown support
+#
+_require_chown()
+{
+ local rnd_uid=4242
+ local file="$TEST_DIR/chown_testfile"
+
+ rm -f $file
+ touch $file
+ chown ${rnd_uid}:${rnd_uid} $file >/dev/null 2>&1 \
+ || _notrun "chown is not supported ${FSTYP}"
+}
+
+
+# check for a chmod support
+# Since chmod sometimes fails silently actual functionality test is done
+#
+_require_chmod()
+{
+ local file="$TEST_DIR/chmod_testfile"
+
+ rm -f $file
+ touch $file
+
+ # get original file mode
+ local mode=`stat --format="0%a" $file`
+ # flip the user's read bit
+ let mode^=0400
+ chmod `printf '%o' "$mode"` $file
+ # check that the chmod actually flipped the bit
+ [ `stat --format="0%a" $file` == `printf '0%o' "$mode"` ] \
+ || _notrun "chmod is not supported ${FSTYP}"
+}
+
# check for a group on the machine, fsgqa as default
#
_require_group()
# Swap files must be nocow on Btrfs.
$CHATTR_PROG +C "$fname" > /dev/null 2>&1
_pwrite_byte 0x61 0 "$sz" "$fname" >> $seqres.full
- $MKSWAP_PROG "$fname" >> $seqres.full
+ # Ignore permission complaints on filesystems that don't support perms
+ $MKSWAP_PROG "$fname" 2> >(grep -v 'insecure permission' >&2) >> $seqres.full
+}
+
+_swapon_file() {
+ local fname="$1"
+
+ # Ignore permission complaints on filesystems that don't support perms
+ swapon "$fname" 2> >(grep -v "insecure permissions" >&2)
}
# Check that the filesystem supports swapfiles
# Minimum size for mkswap is 10 pages
_format_swapfile "$SCRATCH_MNT/swap" $(($(get_page_size) * 10))
- # ext* and xfs have supported all variants of swap files since their
+ # ext* has supported all variants of swap files since their
# introduction, so swapon should not fail.
case "$FSTYP" in
- ext2|ext3|ext4|xfs)
+ ext2|ext3|ext4)
if ! swapon "$SCRATCH_MNT/swap" >/dev/null 2>&1; then
- _scratch_unmount
- _fail "swapon failed for $FSTYP"
+ if _check_s_dax "$SCRATCH_MNT/swap" 1 >/dev/null; then
+ _scratch_unmount
+ _notrun "swapfiles are not supported"
+ else
+ _scratch_unmount
+ _fail "swapon failed for $FSTYP"
+ fi
fi
;;
*)
{
local target=$1
local exp_s_dax=$2
+ local ret=0
local attributes=$($XFS_IO_PROG -c 'statx -r' $target | awk '/stat.attributes / { print $3 }')
fi
if [ $exp_s_dax -eq 0 ]; then
- (( attributes & 0x00200000 )) && echo "$target has unexpected S_DAX flag"
+ if (( attributes & 0x00200000 )); then
+ echo "$target has unexpected S_DAX flag"
+ ret=1
+ fi
else
- (( attributes & 0x00200000 )) || echo "$target doesn't have expected S_DAX flag"
+ if ! (( attributes & 0x00200000 )); then
+ echo "$target doesn't have expected S_DAX flag"
+ ret=2
+ fi
fi
+ return $ret
}
_check_xflag()
fi
case "$FSTYP" in
- ext2|vfat|msdos|udf|exfat)
+ ext2|vfat|msdos|udf|exfat|tmpfs)
echo "$FSTYP does not support metadata journaling"
return 1
;;
# return device size in kb
_get_device_size()
{
- grep -w `_short_dev $1` /proc/partitions | awk '{print $3}'
+ echo $(($(blockdev --getsz $1) >> 1))
}
# Make sure we actually have dmesg checking set up.
stat -f -c %S $1
}
+# Require that the fundamental allocation unit of a file is the same as the
+# filesystem block size. The sole parameter must be the root dir of a
+# filesystem.
+_require_file_block_size_equals_fs_block_size()
+{
+ local file_alloc_unit="$(_get_file_block_size $1)"
+ local fs_block_size="$(_get_block_size $1)"
+ test "$file_alloc_unit" != "$fs_block_size" && \
+ _notrun "File allocation unit is larger than a filesystem block"
+}
+
get_page_size()
{
echo $(getconf PAGE_SIZE)