common/rc: not run swapfile test for DAX
[xfstests-dev.git] / common / rc
index fc1a7751ef2d7e36aa8ad0df2706e8b7ef3135a8..e53d1569eef732d8db9f0b45e0a3c636e1a253d7 100644 (file)
--- a/common/rc
+++ b/common/rc
@@ -342,6 +342,36 @@ _scratch_mount()
        _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
@@ -357,6 +387,11 @@ _scratch_unmount()
        esac
 }
 
+_scratch_umount_idmapped()
+{
+       $UMOUNT_PROG $SCRATCH_MNT
+}
+
 _scratch_remount()
 {
     local opts="$1"
@@ -1608,7 +1643,8 @@ _require_scratch_size_nocheck()
        [ $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
@@ -1766,26 +1802,13 @@ _require_loop()
     fi
 }
 
-# this test requires ext2 filesystem support
-#
-_require_ext2()
-{
-    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
+# this test requires kernel support for a secondary filesystem
 #
-_require_tmpfs()
+_require_extra_fs()
 {
-       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
@@ -1908,6 +1931,50 @@ _require_dm_target()
        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()
@@ -1993,6 +2060,40 @@ _require_io_uring()
        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)
 #
@@ -2067,7 +2168,7 @@ _filesystem_timestamp_range()
                echo "0 $u32max"
                ;;
        xfs)
-               echo "$s32min $s32max"
+               _xfs_timestamp_range "$device"
                ;;
        btrfs)
                echo "$s64min $s64max"
@@ -2128,6 +2229,40 @@ _require_user()
     [ "$?" == "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()
@@ -2364,7 +2499,15 @@ _format_swapfile() {
        # 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
@@ -2391,13 +2534,18 @@ _require_scratch_swapfile()
        # 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
                ;;
        *)
@@ -3261,6 +3409,7 @@ _check_s_dax()
 {
        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 }')
 
@@ -3281,10 +3430,17 @@ _check_s_dax()
        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()
@@ -3376,7 +3532,7 @@ _has_metadata_journaling()
        fi
 
        case "$FSTYP" in
-       ext2|vfat|msdos|udf|exfat)
+       ext2|vfat|msdos|udf|exfat|tmpfs)
                echo "$FSTYP does not support metadata journaling"
                return 1
                ;;
@@ -3790,7 +3946,7 @@ _get_available_space()
 # 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.
@@ -4074,6 +4230,16 @@ _get_block_size()
        stat -f -c %S $1
 }
 
+# Require that the fundamental allocation unit of a file is the same as the
+# filesystem block size.
+_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)