All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ext4: ext4 mount sanity test
@ 2020-04-22 15:20 Lukas Czerner
  2020-04-22 17:42 ` Ira Weiny
  2020-04-23 11:18 ` [PATCH v2] " Lukas Czerner
  0 siblings, 2 replies; 10+ messages in thread
From: Lukas Czerner @ 2020-04-22 15:20 UTC (permalink / raw)
  To: fstests

Add test to validate that the ext4 mount options are properly recognized,
validated and applied to avoid regression as ext4 moves to the new mount
API.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
 tests/ext4/002     | 478 +++++++++++++++++++++++++++++++++++++++++++++
 tests/ext4/002.out |   2 +
 tests/ext4/group   |   1 +
 3 files changed, 481 insertions(+)
 create mode 100755 tests/ext4/002
 create mode 100644 tests/ext4/002.out

diff --git a/tests/ext4/002 b/tests/ext4/002
new file mode 100755
index 00000000..868386e7
--- /dev/null
+++ b/tests/ext4/002
@@ -0,0 +1,478 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
+#
+# FS QA Test 002
+#
+# Sanity check of ext4 mount options
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	cd /
+	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+	if [ -n "$LOOP_LOGDEV" ];then
+		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
+	fi
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/quota
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+echo "Silence is golden."
+
+_supported_fs generic
+_supported_os Linux
+_require_scratch
+_require_quota
+_require_loop
+
+LOG=""
+print_log() {
+	LOG="$LOG $@"
+}
+
+KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
+kernel_gte() {
+	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
+	[ $gte -eq 1 ] && return 0
+	return 1
+}
+
+# This test is only relevant for the newer kernel
+kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 5.7 and higher"
+
+IGNORED="remount,defaults,ignored,removed"
+CHECK_MINFO="lazytime"
+ERR=0
+
+test_mnt() {
+	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
+	[ $? -ne 0 ] && return $?
+
+	if [ $# -eq 1 ]; then
+		OPTS=$1
+	elif [ $# -eq 2 ]; then
+		OPTS=$2
+	else
+		return 0
+	fi
+
+	print_log "checking \"$OPTS\" "
+	# test options in /proc/fs/ext4/dev/options
+	(
+	ret=0
+	IFS=','
+	for option in $OPTS; do
+		if echo $IGNORED | grep -w $option; then
+			continue
+		fi
+
+		[ $option = "noload" ] && option="norecovery"
+
+		if [[ $option = ^* ]]; then
+			expected=1
+		else
+			expected=0
+		fi
+		option=${option#^}
+
+		if echo $CHECK_MINFO | grep -w $option; then
+			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
+			ret=$?
+		else
+			grep $option /proc/fs/ext4/$(basename $SCRATCH_DEV)/options
+			ret=$?
+		fi
+
+		if [ $ret -ne $expected ]; then
+			exit 1
+		fi
+	done
+	) > /dev/null 2>&1
+	return $?
+}
+
+fail() {
+	print_log "   FAILED"
+	ERR=$((ERR+1))
+	echo $LOG | tee -a $seqres.full
+	LOG=""
+}
+
+ok() {
+	print_log "   OK"
+	echo $LOG >> $seqres.full
+	LOG=""
+}
+
+simple_mount() {
+	_mount $* >> $seqres.full 2>&1
+}
+
+# $1 - can hold -n option, if it does argumetns are shifted
+# $1 - options to test
+# $2 - if provided it's the option string to check for
+do_mnt() {
+	device=$SCRATCH_DEV
+	# If -n argument is provided do not specify $SCRATCH_DEV
+	# usefull for remount
+	if [ "$1" == "-n" ]; then
+		unset device
+		shift
+	fi
+
+	if [ -z "$1" ]; then
+		simple_mount $device $SCRATCH_MNT
+		ret=$?
+	else
+		simple_mount -o $1 $device $SCRATCH_MNT
+		ret=$?
+	fi
+	if [ $ret -eq 0 ]; then
+		test_mnt $1 $2
+		ret=$?
+		[ $ret -ne 0 ] && print_log "(not found)"
+	else
+		print_log "(failed mount)"
+	fi
+
+	return $ret
+}
+
+not_mnt() {
+	print_log "SHOULD FAIL mounting \"$1\" "
+	do_mnt $@
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+_mnt() {
+	print_log "mounting \"$1\" "
+	do_mnt $@
+	if [ $? -ne 0 ]; then
+		fail
+	else
+		ok
+	fi
+}
+
+mnt() {
+	_mnt $*
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+# $1 - options to mount with
+# $2 - options to remount with
+remount() {
+	# First do this specifying both dev and mnt
+	print_log "mounting \"$1\" "
+	do_mnt $1
+	[ $? -ne 0 ] && fail && return
+	print_log "remounting \"$2\" "
+	do_mnt remount,$2 $3
+	if [ $? -ne 0 ]; then
+		fail
+		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+		return
+	else
+		ok
+	fi
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+
+	# Now just specify mnt
+	print_log "mounting \"$1\" "
+	do_mnt $1
+	[ $? -ne 0 ] && fail && return
+	print_log "remounting (MNT ONLY) \"$2\" "
+	do_mnt -n remount,$2 $3
+	if [ $? -ne 0 ]; then
+		fail
+	else
+		ok
+	fi
+
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+# $1 - options to mount with, or -r argument
+# $2 - options to remount with
+_not_remount() {
+	remount_only=0
+	# If -r is specified we're going to do remount only
+	if [ "$1" == "-r" ]; then
+		remount_only=1
+		# Dont need shift since first argument would
+		# have been consumed by mount anyway
+	fi
+
+	if [ $remount_only -eq 0 ]; then
+		print_log "mounting \"$1\" "
+		do_mnt $1
+		[ $? -ne 0 ] && fail && return
+	fi
+	print_log "SHOULD FAIL remounting \"$2\" "
+	do_mnt remount,$2 $3
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+
+	# Now just specify mnt
+	print_log "SHOULD FAIL remounting (MNT ONLY) \"$2\" "
+	do_mnt -n remount,$2 $3
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+}
+
+not_remount() {
+	_not_remount $*
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+
+do_mkfs() {
+	$MKFS_EXT4_PROG -Fq $* >> $seqres.full 2>&1 ||
+	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
+}
+
+$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
+
+do_mkfs $SCRATCH_DEV
+
+not_mnt failme
+mnt
+mnt bsddf
+mnt minixdf
+mnt grpid
+mnt bsdgroups grpid
+mnt nogrpid
+mnt sysvgroups nogrpid
+mnt resgid=1001
+mnt resuid=1001
+mnt sb=131072
+mnt errors=continue
+mnt errors=panic
+mnt errors=remount-ro
+mnt nouid32
+mnt debug
+mnt oldalloc removed
+mnt orlov removed
+mnt user_xattr
+mnt nouser_xattr
+mnt noload norecovery
+mnt bh removed
+mnt nobh removed
+mnt commit=7
+mnt min_batch_time=200
+mnt max_batch_time=10000
+mnt journal_checksum
+mnt nojournal_checksum
+mnt journal_async_commit,data=writeback
+mnt abort ignored
+mnt data=journal
+mnt data=ordered
+mnt data=writeback
+mnt data_err=abort
+mnt data_err=ignore ignored
+mnt usrjquota=aquota.user,jqfmt=vfsv0
+not_mnt usrjquota=aquota.user		# should fail
+mnt usrjquota= ignored
+mnt grpjquota=aquota.group,jqfmt=vfsv0
+not_mnt grpjquota=aquota.group		# should fail
+mnt grpjquota= ignored
+mnt jqfmt=vfsold
+mnt jqfmt=vfsv0
+mnt jqfmt=vfsv1
+mnt grpquota
+mnt quota
+mnt noquota
+mnt usrquota
+mnt grpquota
+mnt barrier
+mnt barrier=0 nobarrier
+mnt barrier=1 barrier
+mnt barrier=99 barrier
+mnt nobarrier
+mnt i_version
+#mnt dax
+mnt stripe=512
+mnt delalloc
+mnt nodelalloc
+mnt warn_on_error
+mnt nowarn_on_error
+mnt lazytime
+mnt nolazytime ^lazytime
+not_mnt debug_want_extra_isize=512
+mnt debug_want_extra_isize=32 ignored
+mnt mblk_io_submit removed
+mnt nomblk_io_submit removed
+mnt block_validity
+mnt noblock_validity
+mnt inode_readahead_blks=16
+mnt journal_ioprio=6 ignored
+mnt auto_da_alloc=0 noauto_da_alloc
+mnt auto_da_alloc=1 auto_da_alloc
+mnt auto_da_alloc=95 auto_da_alloc
+mnt auto_da_alloc
+mnt noauto_da_alloc
+mnt dioread_nolock
+kernel_gte 5.6 && mnt nodioread_nolock
+kernel_gte 5.6 && mnt dioread_lock nodioread_nolock
+mnt discard
+mnt nodiscard
+mnt init_itable=20
+mnt init_itable
+mnt init_itable=0
+mnt noinit_itable
+mnt max_dir_size_kb=4096
+mnt test_dummy_encryption
+mnt nombcache
+mnt no_mbcache nombcache
+mnt check=none removed
+mnt nocheck removed
+mnt reservation removed
+mnt noreservation removed
+not_mnt journal=20
+not_mnt nonsenseoption
+not_mnt nonsenseoption=value
+
+# generic remount check
+remount barrier nobarrier
+remount nobarrier barrier
+remount discard nodiscard
+remount nodiscard discard
+
+# Quota remount check
+remount grpquota usrquota
+remount usrquota quota
+remount usrquota usrjquota=q.u,jqfmt=vfsv0
+remount grpquota grpjquota=q.g,jqfmt=vfsv0
+
+not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
+not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
+
+remount quota usrjquota=q.u,jqfmt=vfsv0
+not_remount quota grpjquota=q.g,jqfmt=vfsv0
+
+remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
+not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
+not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
+
+remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
+remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
+not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
+not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
+
+remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
+remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
+remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
+
+remount jqfmt=vfsv0 grpjquota=q.g
+remount jqfmt=vfsv0 usrjquota=q.u
+
+remount noload data=journal norecovery
+not_remount data=ordered data=journal
+not_remount data=journal data=writeback
+not_remount data=writeback data=ordered
+
+# Create logdev for external journal
+LOOP_IMG=$tmp.logdev
+truncate -s 100M $LOOP_IMG
+LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
+majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
+LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
+
+do_mkfs -O journal_dev $LOOP_LOGDEV
+do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV
+mnt defaults
+mnt journal_path=$LOOP_LOGDEV ignored
+mnt journal_dev=$LOGDEV_DEVNUM ignored
+not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
+not_mnt journal_dev=123456 ignored
+not_mnt journal_dev=999999999999999 ignored
+
+do_mkfs -E quotatype=prjquota $SCRATCH_DEV
+mnt prjquota
+
+# test clearing/changing journalled quota when enabled
+echo "== Testing active journalled quota" >> $seqres.full
+_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
+
+# Prepare and enable quota
+#quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
+quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
+quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
+
+_not_remount -r grpjquota=
+_not_remount -r usrjquota=aaquota.user
+_not_remount -r grpjquota=aaquota.group
+_not_remount -r jqfmt=vfsv1
+_not_remount -r noquota
+_mnt remount,usrquota,grpquota ^usrquota,^grpquota
+$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+
+# test clearing/changing quota when enabled
+do_mkfs -E quotatype=^prjquota $SCRATCH_DEV
+not_mnt prjquota
+echo "== Testing active non-journalled quota" >> $seqres.full
+_mnt grpquota,usrquota
+
+# Prepare and enable quota
+#quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
+quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
+quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
+
+_not_remount -r noquota
+_not_remount -r usrjquota=aquota.user
+_not_remount -r grpjquota=aquota.group
+_not_remount -r jqfmt=vfsv1
+_mnt remount,grpjquota= grpquota,^grpjquota
+_mnt remount,usrjquota= usrquota,^usrjquota
+_mnt remount,usrquota,grpquota usrquota,grpquota
+quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
+_mnt remount,noquota ^usrquota,^grpquota,quota
+$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+
+# Quota feature
+echo "== Testing quota feature " >> $seqres.full
+do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV
+mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
+mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
+mnt jqfmt=vfsv1 ^jqfmt=
+mnt prjquota
+mnt usrquota
+mnt grpquota
+not_remount defaults usrjquota=aquota.user
+not_remount defaults grpjquota=aquota.user
+not_remount defaults jqfmt=vfsv1
+remount defaults grpjquota=,usrjquota= ignored
+
+$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+echo "$ERR errors encountered" >> $seqres.full
+
+status=$ERR
+exit
diff --git a/tests/ext4/002.out b/tests/ext4/002.out
new file mode 100644
index 00000000..c1642bfd
--- /dev/null
+++ b/tests/ext4/002.out
@@ -0,0 +1,2 @@
+QA output created by 002
+Silence is golden.
diff --git a/tests/ext4/group b/tests/ext4/group
index a1adc553..b0aa781a 100644
--- a/tests/ext4/group
+++ b/tests/ext4/group
@@ -4,6 +4,7 @@
 # - comment line before each group is "new" description
 #
 001 auto prealloc quick zero
+002 auto mount
 003 auto quick
 004 auto dump
 005 auto quick metadata ioctl rw
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] ext4: ext4 mount sanity test
  2020-04-22 15:20 [PATCH] ext4: ext4 mount sanity test Lukas Czerner
@ 2020-04-22 17:42 ` Ira Weiny
  2020-04-22 19:39   ` Lukas Czerner
  2020-04-23 11:18 ` [PATCH v2] " Lukas Czerner
  1 sibling, 1 reply; 10+ messages in thread
From: Ira Weiny @ 2020-04-22 17:42 UTC (permalink / raw)
  To: Lukas Czerner; +Cc: fstests

On Wed, Apr 22, 2020 at 05:20:12PM +0200, Lukas Czerner wrote:
> Add test to validate that the ext4 mount options are properly recognized,
> validated and applied to avoid regression as ext4 moves to the new mount
> API.

When is the new mount API work slated to be done?  I must have missed the patch
set.

Ira


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ext4: ext4 mount sanity test
  2020-04-22 17:42 ` Ira Weiny
@ 2020-04-22 19:39   ` Lukas Czerner
  0 siblings, 0 replies; 10+ messages in thread
From: Lukas Czerner @ 2020-04-22 19:39 UTC (permalink / raw)
  To: Ira Weiny; +Cc: fstests

On Wed, Apr 22, 2020 at 10:42:12AM -0700, Ira Weiny wrote:
> On Wed, Apr 22, 2020 at 05:20:12PM +0200, Lukas Czerner wrote:
> > Add test to validate that the ext4 mount options are properly recognized,
> > validated and applied to avoid regression as ext4 moves to the new mount
> > API.
> 
> When is the new mount API work slated to be done?  I must have missed the patch
> set.
> 
> Ira

I'll be sending the new patchset soon - probably tomorrow.

-Lukas


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] ext4: ext4 mount sanity test
  2020-04-22 15:20 [PATCH] ext4: ext4 mount sanity test Lukas Czerner
  2020-04-22 17:42 ` Ira Weiny
@ 2020-04-23 11:18 ` Lukas Czerner
  2020-04-27  9:48   ` Zorro Lang
                     ` (2 more replies)
  1 sibling, 3 replies; 10+ messages in thread
From: Lukas Czerner @ 2020-04-23 11:18 UTC (permalink / raw)
  To: fstests

Add test to validate that the ext4 mount options are properly recognized,
validated and applied to avoid regression as ext4 moves to the new mount
API.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
v2: ext4 driver can support ext3 and ext2 as well so check the
    compatibility for those fs as well

 tests/ext4/002     | 509 +++++++++++++++++++++++++++++++++++++++++++++
 tests/ext4/002.out |   2 +
 tests/ext4/group   |   1 +
 3 files changed, 512 insertions(+)
 create mode 100755 tests/ext4/002
 create mode 100644 tests/ext4/002.out

diff --git a/tests/ext4/002 b/tests/ext4/002
new file mode 100755
index 00000000..eda4a2dd
--- /dev/null
+++ b/tests/ext4/002
@@ -0,0 +1,509 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
+#
+# FS QA Test 002
+#
+# Sanity check of ext4 mount options
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	cd /
+	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+	if [ -n "$LOOP_LOGDEV" ];then
+		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
+	fi
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/quota
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+echo "Silence is golden."
+
+_supported_fs ext2 ext3 ext4
+_supported_os Linux
+_require_scratch
+_require_quota
+_require_loop
+
+LOG=""
+print_log() {
+	LOG="$LOG $@"
+}
+
+KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
+kernel_gte() {
+	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
+	[ $gte -eq 1 ] && return 0
+	return 1
+}
+
+# This test is only relevant for the newer kernel
+kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 5.7 and higher"
+
+IGNORED="remount,defaults,ignored,removed"
+CHECK_MINFO="lazytime"
+ERR=0
+
+test_mnt() {
+	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
+	[ $? -ne 0 ] && return $?
+
+	if [ $# -eq 1 ]; then
+		OPTS=$1
+	elif [ $# -eq 2 ]; then
+		OPTS=$2
+	else
+		return 0
+	fi
+
+	print_log "checking \"$OPTS\" "
+	# test options in /proc/fs/ext4/dev/options
+	(
+	ret=0
+	IFS=','
+	for option in $OPTS; do
+		if echo $IGNORED | grep -w $option; then
+			continue
+		fi
+
+		[ $option = "noload" ] && option="norecovery"
+
+		if [[ $option = ^* ]]; then
+			expected=1
+		else
+			expected=0
+		fi
+		option=${option#^}
+
+		if echo $CHECK_MINFO | grep -w $option; then
+			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
+			ret=$?
+		else
+			grep $option /proc/fs/ext4/$(basename $SCRATCH_DEV)/options
+			ret=$?
+		fi
+
+		if [ $ret -ne $expected ]; then
+			exit 1
+		fi
+	done
+	) > /dev/null 2>&1
+	return $?
+}
+
+fail() {
+	print_log "   FAILED"
+	ERR=$((ERR+1))
+	echo $LOG | tee -a $seqres.full
+	LOG=""
+}
+
+ok() {
+	print_log "   OK"
+	echo $LOG >> $seqres.full
+	LOG=""
+}
+
+simple_mount() {
+	_mount $* >> $seqres.full 2>&1
+}
+
+# $1 - can hold -n option, if it does argumetns are shifted
+# $1 - options to test
+# $2 - if provided it's the option string to check for
+do_mnt() {
+	device=$SCRATCH_DEV
+	# If -n argument is provided do not specify $SCRATCH_DEV
+	# usefull for remount
+	if [ "$1" == "-n" ]; then
+		unset device
+		shift
+	fi
+
+	if [ -z "$1" ]; then
+		simple_mount $device $SCRATCH_MNT
+		ret=$?
+	else
+		simple_mount -o $1 $device $SCRATCH_MNT
+		ret=$?
+	fi
+	if [ $ret -eq 0 ]; then
+		test_mnt $1 $2
+		ret=$?
+		[ $ret -ne 0 ] && print_log "(not found)"
+	else
+		print_log "(failed mount)"
+	fi
+
+	return $ret
+}
+
+not_mnt() {
+	print_log "SHOULD FAIL mounting $fstype \"$1\" "
+	do_mnt $@
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+_mnt() {
+	print_log "mounting $fstype \"$1\" "
+	do_mnt $@
+	if [ $? -ne 0 ]; then
+		fail
+	else
+		ok
+	fi
+}
+
+mnt() {
+	_mnt $*
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+# $1 - options to mount with
+# $2 - options to remount with
+remount() {
+	# First do this specifying both dev and mnt
+	print_log "mounting $fstype \"$1\" "
+	do_mnt $1
+	[ $? -ne 0 ] && fail && return
+	print_log "remounting \"$2\" "
+	do_mnt remount,$2 $3
+	if [ $? -ne 0 ]; then
+		fail
+		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+		return
+	else
+		ok
+	fi
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+
+	# Now just specify mnt
+	print_log "mounting $fstype \"$1\" "
+	do_mnt $1
+	[ $? -ne 0 ] && fail && return
+	print_log "remounting (MNT ONLY) \"$2\" "
+	do_mnt -n remount,$2 $3
+	if [ $? -ne 0 ]; then
+		fail
+	else
+		ok
+	fi
+
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+# $1 - options to mount with, or -r argument
+# $2 - options to remount with
+_not_remount() {
+	remount_only=0
+	# If -r is specified we're going to do remount only
+	if [ "$1" == "-r" ]; then
+		remount_only=1
+		# Dont need shift since first argument would
+		# have been consumed by mount anyway
+	fi
+
+	if [ $remount_only -eq 0 ]; then
+		print_log "mounting $fstype \"$1\" "
+		do_mnt $1
+		[ $? -ne 0 ] && fail && return
+	fi
+	print_log "SHOULD FAIL remounting $fstype \"$2\" "
+	do_mnt remount,$2 $3
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+
+	# Now just specify mnt
+	print_log "SHOULD FAIL remounting $fstype (MNT ONLY) \"$2\" "
+	do_mnt -n remount,$2 $3
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+}
+
+not_remount() {
+	_not_remount $*
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+
+do_mkfs() {
+	mke2fs -T $fstype -Fq $* >> $seqres.full 2>&1 ||
+	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
+}
+
+not_ext2() {
+	if [[ $fstype == "ext2" ]]; then
+		not_$*
+	else
+		$*
+	fi
+}
+
+only_ext4() {
+	if [[ $fstype == "ext4" ]]; then
+		$*
+	else
+		not_$*
+	fi
+}
+
+# Create logdev for external journal
+LOOP_IMG=$tmp.logdev
+truncate -s 100M $LOOP_IMG
+LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
+majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
+LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
+
+# Test all the extN file system supported by ext4 driver
+fstype=
+for fstype in ext2 ext3 ext4; do
+
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+	$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
+
+	do_mkfs $SCRATCH_DEV
+
+	# do we have fstype support ?
+	do_mnt
+	if [ $? -ne 0 ]; then
+		print_log "$fstype not supported. Skipping..."
+		ok
+		continue
+	fi
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+
+	not_mnt failme
+	mnt
+	mnt bsddf
+	mnt minixdf
+	mnt grpid
+	mnt bsdgroups grpid
+	mnt nogrpid
+	mnt sysvgroups nogrpid
+	mnt resgid=1001
+	mnt resuid=1001
+	mnt sb=131072
+	mnt errors=continue
+	mnt errors=panic
+	mnt errors=remount-ro
+	mnt nouid32
+	mnt debug
+	mnt oldalloc removed
+	mnt orlov removed
+	mnt user_xattr
+	mnt nouser_xattr
+	not_ext2 mnt noload norecovery
+	mnt bh removed
+	mnt nobh removed
+	not_ext2 mnt commit=7
+	mnt min_batch_time=200
+	mnt max_batch_time=10000
+	only_ext4 mnt journal_checksum
+	only_ext4 mnt nojournal_checksum
+	only_ext4 mnt journal_async_commit,data=writeback
+	mnt abort ignored
+	not_ext2 mnt data=journal
+	not_ext2 mnt data=ordered
+	not_ext2 mnt data=writeback
+	not_ext2 mnt data_err=abort
+	not_ext2 mnt data_err=ignore ignored
+	mnt usrjquota=aquota.user,jqfmt=vfsv0
+	not_mnt usrjquota=aquota.user
+	mnt usrjquota= ignored
+	mnt grpjquota=aquota.group,jqfmt=vfsv0
+	not_mnt grpjquota=aquota.group
+	mnt grpjquota= ignored
+	mnt jqfmt=vfsold
+	mnt jqfmt=vfsv0
+	mnt jqfmt=vfsv1
+	mnt grpquota
+	mnt quota
+	mnt noquota
+	mnt usrquota
+	mnt grpquota
+	mnt barrier
+	mnt barrier=0 nobarrier
+	mnt barrier=1 barrier
+	mnt barrier=99 barrier
+	mnt nobarrier
+	mnt i_version
+	#mnt dax
+	mnt stripe=512
+	only_ext4 mnt delalloc
+	only_ext4 mnt nodelalloc
+	mnt warn_on_error
+	mnt nowarn_on_error
+	mnt lazytime
+	mnt nolazytime ^lazytime
+	not_mnt debug_want_extra_isize=512
+	mnt debug_want_extra_isize=32 ignored
+	mnt mblk_io_submit removed
+	mnt nomblk_io_submit removed
+	mnt block_validity
+	mnt noblock_validity
+	mnt inode_readahead_blks=16
+	not_ext2 mnt journal_ioprio=6 ignored
+	mnt auto_da_alloc=0 noauto_da_alloc
+	mnt auto_da_alloc=1 auto_da_alloc
+	mnt auto_da_alloc=95 auto_da_alloc
+	mnt auto_da_alloc
+	mnt noauto_da_alloc
+	only_ext4 mnt dioread_nolock
+	kernel_gte 5.6 && only_ext4 mnt nodioread_nolock
+	kernel_gte 5.6 && only_ext4 mnt dioread_lock nodioread_nolock
+	mnt discard
+	mnt nodiscard
+	mnt init_itable=20
+	mnt init_itable
+	mnt init_itable=0
+	mnt noinit_itable
+	mnt max_dir_size_kb=4096
+	mnt test_dummy_encryption
+	mnt nombcache
+	mnt no_mbcache nombcache
+	mnt check=none removed
+	mnt nocheck removed
+	mnt reservation removed
+	mnt noreservation removed
+	not_mnt journal=20
+	not_mnt nonsenseoption
+	not_mnt nonsenseoption=value
+
+	# generic remount check
+	remount barrier nobarrier
+	remount nobarrier barrier
+	remount discard nodiscard
+	remount nodiscard discard
+
+	# Quota remount check
+	remount grpquota usrquota
+	remount usrquota quota
+	remount usrquota usrjquota=q.u,jqfmt=vfsv0
+	remount grpquota grpjquota=q.g,jqfmt=vfsv0
+
+	not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
+	not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
+
+	remount quota usrjquota=q.u,jqfmt=vfsv0
+	not_remount quota grpjquota=q.g,jqfmt=vfsv0
+
+	remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
+	not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
+	not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
+
+	remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
+	remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
+	not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
+	not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
+
+	remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
+	remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
+	remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
+
+	remount jqfmt=vfsv0 grpjquota=q.g
+	remount jqfmt=vfsv0 usrjquota=q.u
+
+	if [[ $fstype != "ext2" ]]; then
+		remount noload data=journal norecovery
+		not_remount data=ordered data=journal
+		not_remount data=journal data=writeback
+		not_remount data=writeback data=ordered
+	fi
+
+	do_mkfs -O journal_dev $LOOP_LOGDEV
+	do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV
+	mnt defaults
+	mnt journal_path=$LOOP_LOGDEV ignored
+	mnt journal_dev=$LOGDEV_DEVNUM ignored
+	not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
+	not_mnt journal_dev=123456 ignored
+	not_mnt journal_dev=999999999999999 ignored
+
+	do_mkfs -E quotatype=prjquota $SCRATCH_DEV
+	mnt prjquota
+
+	# test clearing/changing journalled quota when enabled
+	echo "== Testing active journalled quota" >> $seqres.full
+	_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
+
+	# Prepare and enable quota
+	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
+	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
+
+	_not_remount -r grpjquota=
+	_not_remount -r usrjquota=aaquota.user
+	_not_remount -r grpjquota=aaquota.group
+	_not_remount -r jqfmt=vfsv1
+	_not_remount -r noquota
+	_mnt remount,usrquota,grpquota ^usrquota,^grpquota
+	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+
+	# test clearing/changing quota when enabled
+	do_mkfs -E quotatype=^prjquota $SCRATCH_DEV
+	not_mnt prjquota
+	echo "== Testing active non-journalled quota" >> $seqres.full
+	_mnt grpquota,usrquota
+
+	# Prepare and enable quota
+	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
+	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
+
+	_not_remount -r noquota
+	_not_remount -r usrjquota=aquota.user
+	_not_remount -r grpjquota=aquota.group
+	_not_remount -r jqfmt=vfsv1
+	_mnt remount,grpjquota= grpquota,^grpjquota
+	_mnt remount,usrjquota= usrquota,^usrjquota
+	_mnt remount,usrquota,grpquota usrquota,grpquota
+	quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
+	_mnt remount,noquota ^usrquota,^grpquota,quota
+	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+
+	# Quota feature
+	echo "== Testing quota feature " >> $seqres.full
+	do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV
+	mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
+	mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
+	mnt jqfmt=vfsv1 ^jqfmt=
+	mnt prjquota
+	mnt usrquota
+	mnt grpquota
+	not_remount defaults usrjquota=aquota.user
+	not_remount defaults grpjquota=aquota.user
+	not_remount defaults jqfmt=vfsv1
+	remount defaults grpjquota=,usrjquota= ignored
+
+done #for fstype in ext2 ext3 ext4; do
+
+$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+echo "$ERR errors encountered" >> $seqres.full
+
+status=$ERR
+exit
diff --git a/tests/ext4/002.out b/tests/ext4/002.out
new file mode 100644
index 00000000..c1642bfd
--- /dev/null
+++ b/tests/ext4/002.out
@@ -0,0 +1,2 @@
+QA output created by 002
+Silence is golden.
diff --git a/tests/ext4/group b/tests/ext4/group
index a1adc553..b0aa781a 100644
--- a/tests/ext4/group
+++ b/tests/ext4/group
@@ -4,6 +4,7 @@
 # - comment line before each group is "new" description
 #
 001 auto prealloc quick zero
+002 auto mount
 003 auto quick
 004 auto dump
 005 auto quick metadata ioctl rw
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] ext4: ext4 mount sanity test
  2020-04-23 11:18 ` [PATCH v2] " Lukas Czerner
@ 2020-04-27  9:48   ` Zorro Lang
  2020-04-27 10:57     ` Lukas Czerner
  2020-05-17 15:02   ` Eryu Guan
  2020-05-18  8:52   ` [PATCH v3] " Lukas Czerner
  2 siblings, 1 reply; 10+ messages in thread
From: Zorro Lang @ 2020-04-27  9:48 UTC (permalink / raw)
  To: Lukas Czerner; +Cc: fstests

On Thu, Apr 23, 2020 at 01:18:29PM +0200, Lukas Czerner wrote:
> Add test to validate that the ext4 mount options are properly recognized,
> validated and applied to avoid regression as ext4 moves to the new mount
> API.
> 
> Signed-off-by: Lukas Czerner <lczerner@redhat.com>
> ---

Hi Lukas,

How can I make this test run pass. I always get many errors[1] on upstream kernel
5.6. Is there a stable way to make it passed on most kernel version? I think an
important thing is making sure the test case stable.

Thanks,
Zorro

[1]
# ./check ext4/002
FSTYP         -- ext4
PLATFORM      -- Linux/x86_64 xxx-xxxxx-xx 5.6.0-rc5-xfs
MKFS_OPTIONS  -- /dev/mapper/testvg-scratchdev
MOUNT_OPTIONS -- -o acl,user_xattr -o context=system_u:object_r:root_t:s0 /dev/mapper/testvg-scratchdev /mnt/scratch                                                                          
                                                                                                                                                                                              
ext4/002        [failed, exit status 1]- output mismatch (see /root/git/xfstests-dev/results//ext4/002.out.bad)                                                                               
    --- tests/ext4/002.out      2020-04-26 13:43:33.867689308 +0800                                                                                                                           
    +++ /root/git/xfstests-dev/results//ext4/002.out.bad        2020-04-26 13:44:22.670986282 +0800                                                                                           
    @@ -1,2 +1,83 @@
     QA output created by 002
     Silence is golden.                                                                                                                                                                       
    +mounting ext2 "bsddf" checking "bsddf" (not found) FAILED
    +mounting ext2 "minixdf" checking "minixdf" (not found) FAILED
    +mounting ext2 "grpid" checking "grpid" (not found) FAILED
    +mounting ext2 "bsdgroups" checking "grpid" (not found) FAILED
    +mounting ext2 "nogrpid" checking "nogrpid" (not found) FAILED
    ...
    (Run 'diff -u /root/git/xfstests-dev/tests/ext4/002.out /root/git/xfstests-dev/results//ext4/002.out.bad'  to see the entire diff)                                                        
Ran: ext4/002
Failures: ext4/002
Failed 1 of 1 tests

> v2: ext4 driver can support ext3 and ext2 as well so check the
>     compatibility for those fs as well
> 
>  tests/ext4/002     | 509 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/ext4/002.out |   2 +
>  tests/ext4/group   |   1 +
>  3 files changed, 512 insertions(+)
>  create mode 100755 tests/ext4/002
>  create mode 100644 tests/ext4/002.out
> 
> diff --git a/tests/ext4/002 b/tests/ext4/002
> new file mode 100755
> index 00000000..eda4a2dd
> --- /dev/null
> +++ b/tests/ext4/002
> @@ -0,0 +1,509 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
> +#
> +# FS QA Test 002
> +#
> +# Sanity check of ext4 mount options
> +#
> +seq=`basename $0`
> +seqres=$RESULT_DIR/$seq
> +echo "QA output created by $seq"
> +
> +here=`pwd`
> +tmp=/tmp/$$
> +status=1	# failure is the default!
> +trap "_cleanup; exit \$status" 0 1 2 3 15
> +
> +_cleanup()
> +{
> +	cd /
> +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +	if [ -n "$LOOP_LOGDEV" ];then
> +		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
> +	fi
> +	rm -f $tmp.*
> +}
> +
> +# get standard environment, filters and checks
> +. ./common/rc
> +. ./common/filter
> +. ./common/quota
> +
> +# remove previous $seqres.full before test
> +rm -f $seqres.full
> +
> +echo "Silence is golden."
> +
> +_supported_fs ext2 ext3 ext4
> +_supported_os Linux
> +_require_scratch
> +_require_quota
> +_require_loop
> +
> +LOG=""
> +print_log() {
> +	LOG="$LOG $@"
> +}
> +
> +KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
> +kernel_gte() {
> +	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
> +	[ $gte -eq 1 ] && return 0
> +	return 1
> +}
> +
> +# This test is only relevant for the newer kernel
> +kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 5.7 and higher"
> +
> +IGNORED="remount,defaults,ignored,removed"
> +CHECK_MINFO="lazytime"
> +ERR=0
> +
> +test_mnt() {
> +	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
> +	[ $? -ne 0 ] && return $?
> +
> +	if [ $# -eq 1 ]; then
> +		OPTS=$1
> +	elif [ $# -eq 2 ]; then
> +		OPTS=$2
> +	else
> +		return 0
> +	fi
> +
> +	print_log "checking \"$OPTS\" "
> +	# test options in /proc/fs/ext4/dev/options
> +	(
> +	ret=0
> +	IFS=','
> +	for option in $OPTS; do
> +		if echo $IGNORED | grep -w $option; then
> +			continue
> +		fi
> +
> +		[ $option = "noload" ] && option="norecovery"
> +
> +		if [[ $option = ^* ]]; then
> +			expected=1
> +		else
> +			expected=0
> +		fi
> +		option=${option#^}
> +
> +		if echo $CHECK_MINFO | grep -w $option; then
> +			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
> +			ret=$?
> +		else
> +			grep $option /proc/fs/ext4/$(basename $SCRATCH_DEV)/options
> +			ret=$?
> +		fi
> +
> +		if [ $ret -ne $expected ]; then
> +			exit 1
> +		fi
> +	done
> +	) > /dev/null 2>&1
> +	return $?
> +}
> +
> +fail() {
> +	print_log "   FAILED"
> +	ERR=$((ERR+1))
> +	echo $LOG | tee -a $seqres.full
> +	LOG=""
> +}
> +
> +ok() {
> +	print_log "   OK"
> +	echo $LOG >> $seqres.full
> +	LOG=""
> +}
> +
> +simple_mount() {
> +	_mount $* >> $seqres.full 2>&1
> +}
> +
> +# $1 - can hold -n option, if it does argumetns are shifted
> +# $1 - options to test
> +# $2 - if provided it's the option string to check for
> +do_mnt() {
> +	device=$SCRATCH_DEV
> +	# If -n argument is provided do not specify $SCRATCH_DEV
> +	# usefull for remount
> +	if [ "$1" == "-n" ]; then
> +		unset device
> +		shift
> +	fi
> +
> +	if [ -z "$1" ]; then
> +		simple_mount $device $SCRATCH_MNT
> +		ret=$?
> +	else
> +		simple_mount -o $1 $device $SCRATCH_MNT
> +		ret=$?
> +	fi
> +	if [ $ret -eq 0 ]; then
> +		test_mnt $1 $2
> +		ret=$?
> +		[ $ret -ne 0 ] && print_log "(not found)"
> +	else
> +		print_log "(failed mount)"
> +	fi
> +
> +	return $ret
> +}
> +
> +not_mnt() {
> +	print_log "SHOULD FAIL mounting $fstype \"$1\" "
> +	do_mnt $@
> +	if [ $? -eq 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +_mnt() {
> +	print_log "mounting $fstype \"$1\" "
> +	do_mnt $@
> +	if [ $? -ne 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +}
> +
> +mnt() {
> +	_mnt $*
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +# $1 - options to mount with
> +# $2 - options to remount with
> +remount() {
> +	# First do this specifying both dev and mnt
> +	print_log "mounting $fstype \"$1\" "
> +	do_mnt $1
> +	[ $? -ne 0 ] && fail && return
> +	print_log "remounting \"$2\" "
> +	do_mnt remount,$2 $3
> +	if [ $? -ne 0 ]; then
> +		fail
> +		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +		return
> +	else
> +		ok
> +	fi
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +
> +	# Now just specify mnt
> +	print_log "mounting $fstype \"$1\" "
> +	do_mnt $1
> +	[ $? -ne 0 ] && fail && return
> +	print_log "remounting (MNT ONLY) \"$2\" "
> +	do_mnt -n remount,$2 $3
> +	if [ $? -ne 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +# $1 - options to mount with, or -r argument
> +# $2 - options to remount with
> +_not_remount() {
> +	remount_only=0
> +	# If -r is specified we're going to do remount only
> +	if [ "$1" == "-r" ]; then
> +		remount_only=1
> +		# Dont need shift since first argument would
> +		# have been consumed by mount anyway
> +	fi
> +
> +	if [ $remount_only -eq 0 ]; then
> +		print_log "mounting $fstype \"$1\" "
> +		do_mnt $1
> +		[ $? -ne 0 ] && fail && return
> +	fi
> +	print_log "SHOULD FAIL remounting $fstype \"$2\" "
> +	do_mnt remount,$2 $3
> +	if [ $? -eq 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +
> +	# Now just specify mnt
> +	print_log "SHOULD FAIL remounting $fstype (MNT ONLY) \"$2\" "
> +	do_mnt -n remount,$2 $3
> +	if [ $? -eq 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +}
> +
> +not_remount() {
> +	_not_remount $*
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +
> +do_mkfs() {
> +	mke2fs -T $fstype -Fq $* >> $seqres.full 2>&1 ||
> +	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
> +}
> +
> +not_ext2() {
> +	if [[ $fstype == "ext2" ]]; then
> +		not_$*
> +	else
> +		$*
> +	fi
> +}
> +
> +only_ext4() {
> +	if [[ $fstype == "ext4" ]]; then
> +		$*
> +	else
> +		not_$*
> +	fi
> +}
> +
> +# Create logdev for external journal
> +LOOP_IMG=$tmp.logdev
> +truncate -s 100M $LOOP_IMG
> +LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
> +majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
> +LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
> +
> +# Test all the extN file system supported by ext4 driver
> +fstype=
> +for fstype in ext2 ext3 ext4; do
> +
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +	$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
> +
> +	do_mkfs $SCRATCH_DEV
> +
> +	# do we have fstype support ?
> +	do_mnt
> +	if [ $? -ne 0 ]; then
> +		print_log "$fstype not supported. Skipping..."
> +		ok
> +		continue
> +	fi
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +
> +	not_mnt failme
> +	mnt
> +	mnt bsddf
> +	mnt minixdf
> +	mnt grpid
> +	mnt bsdgroups grpid
> +	mnt nogrpid
> +	mnt sysvgroups nogrpid
> +	mnt resgid=1001
> +	mnt resuid=1001
> +	mnt sb=131072
> +	mnt errors=continue
> +	mnt errors=panic
> +	mnt errors=remount-ro
> +	mnt nouid32
> +	mnt debug
> +	mnt oldalloc removed
> +	mnt orlov removed
> +	mnt user_xattr
> +	mnt nouser_xattr
> +	not_ext2 mnt noload norecovery
> +	mnt bh removed
> +	mnt nobh removed
> +	not_ext2 mnt commit=7
> +	mnt min_batch_time=200
> +	mnt max_batch_time=10000
> +	only_ext4 mnt journal_checksum
> +	only_ext4 mnt nojournal_checksum
> +	only_ext4 mnt journal_async_commit,data=writeback
> +	mnt abort ignored
> +	not_ext2 mnt data=journal
> +	not_ext2 mnt data=ordered
> +	not_ext2 mnt data=writeback
> +	not_ext2 mnt data_err=abort
> +	not_ext2 mnt data_err=ignore ignored
> +	mnt usrjquota=aquota.user,jqfmt=vfsv0
> +	not_mnt usrjquota=aquota.user
> +	mnt usrjquota= ignored
> +	mnt grpjquota=aquota.group,jqfmt=vfsv0
> +	not_mnt grpjquota=aquota.group
> +	mnt grpjquota= ignored
> +	mnt jqfmt=vfsold
> +	mnt jqfmt=vfsv0
> +	mnt jqfmt=vfsv1
> +	mnt grpquota
> +	mnt quota
> +	mnt noquota
> +	mnt usrquota
> +	mnt grpquota
> +	mnt barrier
> +	mnt barrier=0 nobarrier
> +	mnt barrier=1 barrier
> +	mnt barrier=99 barrier
> +	mnt nobarrier
> +	mnt i_version
> +	#mnt dax
> +	mnt stripe=512
> +	only_ext4 mnt delalloc
> +	only_ext4 mnt nodelalloc
> +	mnt warn_on_error
> +	mnt nowarn_on_error
> +	mnt lazytime
> +	mnt nolazytime ^lazytime
> +	not_mnt debug_want_extra_isize=512
> +	mnt debug_want_extra_isize=32 ignored
> +	mnt mblk_io_submit removed
> +	mnt nomblk_io_submit removed
> +	mnt block_validity
> +	mnt noblock_validity
> +	mnt inode_readahead_blks=16
> +	not_ext2 mnt journal_ioprio=6 ignored
> +	mnt auto_da_alloc=0 noauto_da_alloc
> +	mnt auto_da_alloc=1 auto_da_alloc
> +	mnt auto_da_alloc=95 auto_da_alloc
> +	mnt auto_da_alloc
> +	mnt noauto_da_alloc
> +	only_ext4 mnt dioread_nolock
> +	kernel_gte 5.6 && only_ext4 mnt nodioread_nolock
> +	kernel_gte 5.6 && only_ext4 mnt dioread_lock nodioread_nolock
> +	mnt discard
> +	mnt nodiscard
> +	mnt init_itable=20
> +	mnt init_itable
> +	mnt init_itable=0
> +	mnt noinit_itable
> +	mnt max_dir_size_kb=4096
> +	mnt test_dummy_encryption
> +	mnt nombcache
> +	mnt no_mbcache nombcache
> +	mnt check=none removed
> +	mnt nocheck removed
> +	mnt reservation removed
> +	mnt noreservation removed
> +	not_mnt journal=20
> +	not_mnt nonsenseoption
> +	not_mnt nonsenseoption=value
> +
> +	# generic remount check
> +	remount barrier nobarrier
> +	remount nobarrier barrier
> +	remount discard nodiscard
> +	remount nodiscard discard
> +
> +	# Quota remount check
> +	remount grpquota usrquota
> +	remount usrquota quota
> +	remount usrquota usrjquota=q.u,jqfmt=vfsv0
> +	remount grpquota grpjquota=q.g,jqfmt=vfsv0
> +
> +	not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
> +	not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
> +
> +	remount quota usrjquota=q.u,jqfmt=vfsv0
> +	not_remount quota grpjquota=q.g,jqfmt=vfsv0
> +
> +	remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
> +	not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
> +	not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
> +
> +	remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
> +	remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
> +	not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
> +	not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
> +
> +	remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
> +	remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
> +	remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
> +
> +	remount jqfmt=vfsv0 grpjquota=q.g
> +	remount jqfmt=vfsv0 usrjquota=q.u
> +
> +	if [[ $fstype != "ext2" ]]; then
> +		remount noload data=journal norecovery
> +		not_remount data=ordered data=journal
> +		not_remount data=journal data=writeback
> +		not_remount data=writeback data=ordered
> +	fi
> +
> +	do_mkfs -O journal_dev $LOOP_LOGDEV
> +	do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV
> +	mnt defaults
> +	mnt journal_path=$LOOP_LOGDEV ignored
> +	mnt journal_dev=$LOGDEV_DEVNUM ignored
> +	not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
> +	not_mnt journal_dev=123456 ignored
> +	not_mnt journal_dev=999999999999999 ignored
> +
> +	do_mkfs -E quotatype=prjquota $SCRATCH_DEV
> +	mnt prjquota
> +
> +	# test clearing/changing journalled quota when enabled
> +	echo "== Testing active journalled quota" >> $seqres.full
> +	_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
> +
> +	# Prepare and enable quota
> +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> +
> +	_not_remount -r grpjquota=
> +	_not_remount -r usrjquota=aaquota.user
> +	_not_remount -r grpjquota=aaquota.group
> +	_not_remount -r jqfmt=vfsv1
> +	_not_remount -r noquota
> +	_mnt remount,usrquota,grpquota ^usrquota,^grpquota
> +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +
> +	# test clearing/changing quota when enabled
> +	do_mkfs -E quotatype=^prjquota $SCRATCH_DEV
> +	not_mnt prjquota
> +	echo "== Testing active non-journalled quota" >> $seqres.full
> +	_mnt grpquota,usrquota
> +
> +	# Prepare and enable quota
> +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> +
> +	_not_remount -r noquota
> +	_not_remount -r usrjquota=aquota.user
> +	_not_remount -r grpjquota=aquota.group
> +	_not_remount -r jqfmt=vfsv1
> +	_mnt remount,grpjquota= grpquota,^grpjquota
> +	_mnt remount,usrjquota= usrquota,^usrjquota
> +	_mnt remount,usrquota,grpquota usrquota,grpquota
> +	quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
> +	_mnt remount,noquota ^usrquota,^grpquota,quota
> +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +
> +	# Quota feature
> +	echo "== Testing quota feature " >> $seqres.full
> +	do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV
> +	mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
> +	mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
> +	mnt jqfmt=vfsv1 ^jqfmt=
> +	mnt prjquota
> +	mnt usrquota
> +	mnt grpquota
> +	not_remount defaults usrjquota=aquota.user
> +	not_remount defaults grpjquota=aquota.user
> +	not_remount defaults jqfmt=vfsv1
> +	remount defaults grpjquota=,usrjquota= ignored
> +
> +done #for fstype in ext2 ext3 ext4; do
> +
> +$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +echo "$ERR errors encountered" >> $seqres.full
> +
> +status=$ERR
> +exit
> diff --git a/tests/ext4/002.out b/tests/ext4/002.out
> new file mode 100644
> index 00000000..c1642bfd
> --- /dev/null
> +++ b/tests/ext4/002.out
> @@ -0,0 +1,2 @@
> +QA output created by 002
> +Silence is golden.
> diff --git a/tests/ext4/group b/tests/ext4/group
> index a1adc553..b0aa781a 100644
> --- a/tests/ext4/group
> +++ b/tests/ext4/group
> @@ -4,6 +4,7 @@
>  # - comment line before each group is "new" description
>  #
>  001 auto prealloc quick zero
> +002 auto mount
>  003 auto quick
>  004 auto dump
>  005 auto quick metadata ioctl rw
> -- 
> 2.21.1
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] ext4: ext4 mount sanity test
  2020-04-27  9:48   ` Zorro Lang
@ 2020-04-27 10:57     ` Lukas Czerner
  2020-04-27 14:25       ` Lukas Czerner
  0 siblings, 1 reply; 10+ messages in thread
From: Lukas Czerner @ 2020-04-27 10:57 UTC (permalink / raw)
  To: fstests

On Mon, Apr 27, 2020 at 05:48:02PM +0800, Zorro Lang wrote:
> On Thu, Apr 23, 2020 at 01:18:29PM +0200, Lukas Czerner wrote:
> > Add test to validate that the ext4 mount options are properly recognized,
> > validated and applied to avoid regression as ext4 moves to the new mount
> > API.
> > 
> > Signed-off-by: Lukas Czerner <lczerner@redhat.com>
> > ---
> 
> Hi Lukas,
> 
> How can I make this test run pass. I always get many errors[1] on upstream kernel
> 5.6. Is there a stable way to make it passed on most kernel version? I think an
> important thing is making sure the test case stable.

Hi,

can you show me the full output and the dmesg ?

Maybe you're using ext2 driver ?
What I want to test here is ext4 driver, not just ext4 file system. I guess
I have to rule out the situation where ext3 or ext2 driver is used,
checking for existence of /proc/fs/ext4/<device> should do the trick I
think.

-Lukas

> 
> Thanks,
> Zorro
> 
> [1]
> # ./check ext4/002
> FSTYP         -- ext4
> PLATFORM      -- Linux/x86_64 xxx-xxxxx-xx 5.6.0-rc5-xfs
> MKFS_OPTIONS  -- /dev/mapper/testvg-scratchdev
> MOUNT_OPTIONS -- -o acl,user_xattr -o context=system_u:object_r:root_t:s0 /dev/mapper/testvg-scratchdev /mnt/scratch                                                                          
>                                                                                                                                                                                               
> ext4/002        [failed, exit status 1]- output mismatch (see /root/git/xfstests-dev/results//ext4/002.out.bad)                                                                               
>     --- tests/ext4/002.out      2020-04-26 13:43:33.867689308 +0800                                                                                                                           
>     +++ /root/git/xfstests-dev/results//ext4/002.out.bad        2020-04-26 13:44:22.670986282 +0800                                                                                           
>     @@ -1,2 +1,83 @@
>      QA output created by 002
>      Silence is golden.                                                                                                                                                                       
>     +mounting ext2 "bsddf" checking "bsddf" (not found) FAILED
>     +mounting ext2 "minixdf" checking "minixdf" (not found) FAILED
>     +mounting ext2 "grpid" checking "grpid" (not found) FAILED
>     +mounting ext2 "bsdgroups" checking "grpid" (not found) FAILED
>     +mounting ext2 "nogrpid" checking "nogrpid" (not found) FAILED
>     ...
>     (Run 'diff -u /root/git/xfstests-dev/tests/ext4/002.out /root/git/xfstests-dev/results//ext4/002.out.bad'  to see the entire diff)                                                        
> Ran: ext4/002
> Failures: ext4/002
> Failed 1 of 1 tests
> 
> > v2: ext4 driver can support ext3 and ext2 as well so check the
> >     compatibility for those fs as well
> > 
> >  tests/ext4/002     | 509 +++++++++++++++++++++++++++++++++++++++++++++
> >  tests/ext4/002.out |   2 +
> >  tests/ext4/group   |   1 +
> >  3 files changed, 512 insertions(+)
> >  create mode 100755 tests/ext4/002
> >  create mode 100644 tests/ext4/002.out
> > 
> > diff --git a/tests/ext4/002 b/tests/ext4/002
> > new file mode 100755
> > index 00000000..eda4a2dd
> > --- /dev/null
> > +++ b/tests/ext4/002
> > @@ -0,0 +1,509 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
> > +#
> > +# FS QA Test 002
> > +#
> > +# Sanity check of ext4 mount options
> > +#
> > +seq=`basename $0`
> > +seqres=$RESULT_DIR/$seq
> > +echo "QA output created by $seq"
> > +
> > +here=`pwd`
> > +tmp=/tmp/$$
> > +status=1	# failure is the default!
> > +trap "_cleanup; exit \$status" 0 1 2 3 15
> > +
> > +_cleanup()
> > +{
> > +	cd /
> > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +	if [ -n "$LOOP_LOGDEV" ];then
> > +		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
> > +	fi
> > +	rm -f $tmp.*
> > +}
> > +
> > +# get standard environment, filters and checks
> > +. ./common/rc
> > +. ./common/filter
> > +. ./common/quota
> > +
> > +# remove previous $seqres.full before test
> > +rm -f $seqres.full
> > +
> > +echo "Silence is golden."
> > +
> > +_supported_fs ext2 ext3 ext4
> > +_supported_os Linux
> > +_require_scratch
> > +_require_quota
> > +_require_loop
> > +
> > +LOG=""
> > +print_log() {
> > +	LOG="$LOG $@"
> > +}
> > +
> > +KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
> > +kernel_gte() {
> > +	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
> > +	[ $gte -eq 1 ] && return 0
> > +	return 1
> > +}
> > +
> > +# This test is only relevant for the newer kernel
> > +kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 5.7 and higher"
> > +
> > +IGNORED="remount,defaults,ignored,removed"
> > +CHECK_MINFO="lazytime"
> > +ERR=0
> > +
> > +test_mnt() {
> > +	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
> > +	[ $? -ne 0 ] && return $?
> > +
> > +	if [ $# -eq 1 ]; then
> > +		OPTS=$1
> > +	elif [ $# -eq 2 ]; then
> > +		OPTS=$2
> > +	else
> > +		return 0
> > +	fi
> > +
> > +	print_log "checking \"$OPTS\" "
> > +	# test options in /proc/fs/ext4/dev/options
> > +	(
> > +	ret=0
> > +	IFS=','
> > +	for option in $OPTS; do
> > +		if echo $IGNORED | grep -w $option; then
> > +			continue
> > +		fi
> > +
> > +		[ $option = "noload" ] && option="norecovery"
> > +
> > +		if [[ $option = ^* ]]; then
> > +			expected=1
> > +		else
> > +			expected=0
> > +		fi
> > +		option=${option#^}
> > +
> > +		if echo $CHECK_MINFO | grep -w $option; then
> > +			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
> > +			ret=$?
> > +		else
> > +			grep $option /proc/fs/ext4/$(basename $SCRATCH_DEV)/options
> > +			ret=$?
> > +		fi
> > +
> > +		if [ $ret -ne $expected ]; then
> > +			exit 1
> > +		fi
> > +	done
> > +	) > /dev/null 2>&1
> > +	return $?
> > +}
> > +
> > +fail() {
> > +	print_log "   FAILED"
> > +	ERR=$((ERR+1))
> > +	echo $LOG | tee -a $seqres.full
> > +	LOG=""
> > +}
> > +
> > +ok() {
> > +	print_log "   OK"
> > +	echo $LOG >> $seqres.full
> > +	LOG=""
> > +}
> > +
> > +simple_mount() {
> > +	_mount $* >> $seqres.full 2>&1
> > +}
> > +
> > +# $1 - can hold -n option, if it does argumetns are shifted
> > +# $1 - options to test
> > +# $2 - if provided it's the option string to check for
> > +do_mnt() {
> > +	device=$SCRATCH_DEV
> > +	# If -n argument is provided do not specify $SCRATCH_DEV
> > +	# usefull for remount
> > +	if [ "$1" == "-n" ]; then
> > +		unset device
> > +		shift
> > +	fi
> > +
> > +	if [ -z "$1" ]; then
> > +		simple_mount $device $SCRATCH_MNT
> > +		ret=$?
> > +	else
> > +		simple_mount -o $1 $device $SCRATCH_MNT
> > +		ret=$?
> > +	fi
> > +	if [ $ret -eq 0 ]; then
> > +		test_mnt $1 $2
> > +		ret=$?
> > +		[ $ret -ne 0 ] && print_log "(not found)"
> > +	else
> > +		print_log "(failed mount)"
> > +	fi
> > +
> > +	return $ret
> > +}
> > +
> > +not_mnt() {
> > +	print_log "SHOULD FAIL mounting $fstype \"$1\" "
> > +	do_mnt $@
> > +	if [ $? -eq 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +_mnt() {
> > +	print_log "mounting $fstype \"$1\" "
> > +	do_mnt $@
> > +	if [ $? -ne 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +}
> > +
> > +mnt() {
> > +	_mnt $*
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +# $1 - options to mount with
> > +# $2 - options to remount with
> > +remount() {
> > +	# First do this specifying both dev and mnt
> > +	print_log "mounting $fstype \"$1\" "
> > +	do_mnt $1
> > +	[ $? -ne 0 ] && fail && return
> > +	print_log "remounting \"$2\" "
> > +	do_mnt remount,$2 $3
> > +	if [ $? -ne 0 ]; then
> > +		fail
> > +		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +		return
> > +	else
> > +		ok
> > +	fi
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +
> > +	# Now just specify mnt
> > +	print_log "mounting $fstype \"$1\" "
> > +	do_mnt $1
> > +	[ $? -ne 0 ] && fail && return
> > +	print_log "remounting (MNT ONLY) \"$2\" "
> > +	do_mnt -n remount,$2 $3
> > +	if [ $? -ne 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +# $1 - options to mount with, or -r argument
> > +# $2 - options to remount with
> > +_not_remount() {
> > +	remount_only=0
> > +	# If -r is specified we're going to do remount only
> > +	if [ "$1" == "-r" ]; then
> > +		remount_only=1
> > +		# Dont need shift since first argument would
> > +		# have been consumed by mount anyway
> > +	fi
> > +
> > +	if [ $remount_only -eq 0 ]; then
> > +		print_log "mounting $fstype \"$1\" "
> > +		do_mnt $1
> > +		[ $? -ne 0 ] && fail && return
> > +	fi
> > +	print_log "SHOULD FAIL remounting $fstype \"$2\" "
> > +	do_mnt remount,$2 $3
> > +	if [ $? -eq 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +
> > +	# Now just specify mnt
> > +	print_log "SHOULD FAIL remounting $fstype (MNT ONLY) \"$2\" "
> > +	do_mnt -n remount,$2 $3
> > +	if [ $? -eq 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +}
> > +
> > +not_remount() {
> > +	_not_remount $*
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +
> > +do_mkfs() {
> > +	mke2fs -T $fstype -Fq $* >> $seqres.full 2>&1 ||
> > +	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
> > +}
> > +
> > +not_ext2() {
> > +	if [[ $fstype == "ext2" ]]; then
> > +		not_$*
> > +	else
> > +		$*
> > +	fi
> > +}
> > +
> > +only_ext4() {
> > +	if [[ $fstype == "ext4" ]]; then
> > +		$*
> > +	else
> > +		not_$*
> > +	fi
> > +}
> > +
> > +# Create logdev for external journal
> > +LOOP_IMG=$tmp.logdev
> > +truncate -s 100M $LOOP_IMG
> > +LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
> > +majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
> > +LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
> > +
> > +# Test all the extN file system supported by ext4 driver
> > +fstype=
> > +for fstype in ext2 ext3 ext4; do
> > +
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +	$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
> > +
> > +	do_mkfs $SCRATCH_DEV
> > +
> > +	# do we have fstype support ?
> > +	do_mnt
> > +	if [ $? -ne 0 ]; then
> > +		print_log "$fstype not supported. Skipping..."
> > +		ok
> > +		continue
> > +	fi
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +
> > +	not_mnt failme
> > +	mnt
> > +	mnt bsddf
> > +	mnt minixdf
> > +	mnt grpid
> > +	mnt bsdgroups grpid
> > +	mnt nogrpid
> > +	mnt sysvgroups nogrpid
> > +	mnt resgid=1001
> > +	mnt resuid=1001
> > +	mnt sb=131072
> > +	mnt errors=continue
> > +	mnt errors=panic
> > +	mnt errors=remount-ro
> > +	mnt nouid32
> > +	mnt debug
> > +	mnt oldalloc removed
> > +	mnt orlov removed
> > +	mnt user_xattr
> > +	mnt nouser_xattr
> > +	not_ext2 mnt noload norecovery
> > +	mnt bh removed
> > +	mnt nobh removed
> > +	not_ext2 mnt commit=7
> > +	mnt min_batch_time=200
> > +	mnt max_batch_time=10000
> > +	only_ext4 mnt journal_checksum
> > +	only_ext4 mnt nojournal_checksum
> > +	only_ext4 mnt journal_async_commit,data=writeback
> > +	mnt abort ignored
> > +	not_ext2 mnt data=journal
> > +	not_ext2 mnt data=ordered
> > +	not_ext2 mnt data=writeback
> > +	not_ext2 mnt data_err=abort
> > +	not_ext2 mnt data_err=ignore ignored
> > +	mnt usrjquota=aquota.user,jqfmt=vfsv0
> > +	not_mnt usrjquota=aquota.user
> > +	mnt usrjquota= ignored
> > +	mnt grpjquota=aquota.group,jqfmt=vfsv0
> > +	not_mnt grpjquota=aquota.group
> > +	mnt grpjquota= ignored
> > +	mnt jqfmt=vfsold
> > +	mnt jqfmt=vfsv0
> > +	mnt jqfmt=vfsv1
> > +	mnt grpquota
> > +	mnt quota
> > +	mnt noquota
> > +	mnt usrquota
> > +	mnt grpquota
> > +	mnt barrier
> > +	mnt barrier=0 nobarrier
> > +	mnt barrier=1 barrier
> > +	mnt barrier=99 barrier
> > +	mnt nobarrier
> > +	mnt i_version
> > +	#mnt dax
> > +	mnt stripe=512
> > +	only_ext4 mnt delalloc
> > +	only_ext4 mnt nodelalloc
> > +	mnt warn_on_error
> > +	mnt nowarn_on_error
> > +	mnt lazytime
> > +	mnt nolazytime ^lazytime
> > +	not_mnt debug_want_extra_isize=512
> > +	mnt debug_want_extra_isize=32 ignored
> > +	mnt mblk_io_submit removed
> > +	mnt nomblk_io_submit removed
> > +	mnt block_validity
> > +	mnt noblock_validity
> > +	mnt inode_readahead_blks=16
> > +	not_ext2 mnt journal_ioprio=6 ignored
> > +	mnt auto_da_alloc=0 noauto_da_alloc
> > +	mnt auto_da_alloc=1 auto_da_alloc
> > +	mnt auto_da_alloc=95 auto_da_alloc
> > +	mnt auto_da_alloc
> > +	mnt noauto_da_alloc
> > +	only_ext4 mnt dioread_nolock
> > +	kernel_gte 5.6 && only_ext4 mnt nodioread_nolock
> > +	kernel_gte 5.6 && only_ext4 mnt dioread_lock nodioread_nolock
> > +	mnt discard
> > +	mnt nodiscard
> > +	mnt init_itable=20
> > +	mnt init_itable
> > +	mnt init_itable=0
> > +	mnt noinit_itable
> > +	mnt max_dir_size_kb=4096
> > +	mnt test_dummy_encryption
> > +	mnt nombcache
> > +	mnt no_mbcache nombcache
> > +	mnt check=none removed
> > +	mnt nocheck removed
> > +	mnt reservation removed
> > +	mnt noreservation removed
> > +	not_mnt journal=20
> > +	not_mnt nonsenseoption
> > +	not_mnt nonsenseoption=value
> > +
> > +	# generic remount check
> > +	remount barrier nobarrier
> > +	remount nobarrier barrier
> > +	remount discard nodiscard
> > +	remount nodiscard discard
> > +
> > +	# Quota remount check
> > +	remount grpquota usrquota
> > +	remount usrquota quota
> > +	remount usrquota usrjquota=q.u,jqfmt=vfsv0
> > +	remount grpquota grpjquota=q.g,jqfmt=vfsv0
> > +
> > +	not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
> > +	not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
> > +
> > +	remount quota usrjquota=q.u,jqfmt=vfsv0
> > +	not_remount quota grpjquota=q.g,jqfmt=vfsv0
> > +
> > +	remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
> > +	not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
> > +	not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
> > +
> > +	remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
> > +	remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
> > +	not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
> > +	not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
> > +
> > +	remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
> > +	remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
> > +	remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
> > +
> > +	remount jqfmt=vfsv0 grpjquota=q.g
> > +	remount jqfmt=vfsv0 usrjquota=q.u
> > +
> > +	if [[ $fstype != "ext2" ]]; then
> > +		remount noload data=journal norecovery
> > +		not_remount data=ordered data=journal
> > +		not_remount data=journal data=writeback
> > +		not_remount data=writeback data=ordered
> > +	fi
> > +
> > +	do_mkfs -O journal_dev $LOOP_LOGDEV
> > +	do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV
> > +	mnt defaults
> > +	mnt journal_path=$LOOP_LOGDEV ignored
> > +	mnt journal_dev=$LOGDEV_DEVNUM ignored
> > +	not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
> > +	not_mnt journal_dev=123456 ignored
> > +	not_mnt journal_dev=999999999999999 ignored
> > +
> > +	do_mkfs -E quotatype=prjquota $SCRATCH_DEV
> > +	mnt prjquota
> > +
> > +	# test clearing/changing journalled quota when enabled
> > +	echo "== Testing active journalled quota" >> $seqres.full
> > +	_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
> > +
> > +	# Prepare and enable quota
> > +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> > +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> > +
> > +	_not_remount -r grpjquota=
> > +	_not_remount -r usrjquota=aaquota.user
> > +	_not_remount -r grpjquota=aaquota.group
> > +	_not_remount -r jqfmt=vfsv1
> > +	_not_remount -r noquota
> > +	_mnt remount,usrquota,grpquota ^usrquota,^grpquota
> > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +
> > +	# test clearing/changing quota when enabled
> > +	do_mkfs -E quotatype=^prjquota $SCRATCH_DEV
> > +	not_mnt prjquota
> > +	echo "== Testing active non-journalled quota" >> $seqres.full
> > +	_mnt grpquota,usrquota
> > +
> > +	# Prepare and enable quota
> > +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> > +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> > +
> > +	_not_remount -r noquota
> > +	_not_remount -r usrjquota=aquota.user
> > +	_not_remount -r grpjquota=aquota.group
> > +	_not_remount -r jqfmt=vfsv1
> > +	_mnt remount,grpjquota= grpquota,^grpjquota
> > +	_mnt remount,usrjquota= usrquota,^usrjquota
> > +	_mnt remount,usrquota,grpquota usrquota,grpquota
> > +	quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
> > +	_mnt remount,noquota ^usrquota,^grpquota,quota
> > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +
> > +	# Quota feature
> > +	echo "== Testing quota feature " >> $seqres.full
> > +	do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV
> > +	mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
> > +	mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
> > +	mnt jqfmt=vfsv1 ^jqfmt=
> > +	mnt prjquota
> > +	mnt usrquota
> > +	mnt grpquota
> > +	not_remount defaults usrjquota=aquota.user
> > +	not_remount defaults grpjquota=aquota.user
> > +	not_remount defaults jqfmt=vfsv1
> > +	remount defaults grpjquota=,usrjquota= ignored
> > +
> > +done #for fstype in ext2 ext3 ext4; do
> > +
> > +$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +echo "$ERR errors encountered" >> $seqres.full
> > +
> > +status=$ERR
> > +exit
> > diff --git a/tests/ext4/002.out b/tests/ext4/002.out
> > new file mode 100644
> > index 00000000..c1642bfd
> > --- /dev/null
> > +++ b/tests/ext4/002.out
> > @@ -0,0 +1,2 @@
> > +QA output created by 002
> > +Silence is golden.
> > diff --git a/tests/ext4/group b/tests/ext4/group
> > index a1adc553..b0aa781a 100644
> > --- a/tests/ext4/group
> > +++ b/tests/ext4/group
> > @@ -4,6 +4,7 @@
> >  # - comment line before each group is "new" description
> >  #
> >  001 auto prealloc quick zero
> > +002 auto mount
> >  003 auto quick
> >  004 auto dump
> >  005 auto quick metadata ioctl rw
> > -- 
> > 2.21.1
> > 
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] ext4: ext4 mount sanity test
  2020-04-27 10:57     ` Lukas Czerner
@ 2020-04-27 14:25       ` Lukas Czerner
  0 siblings, 0 replies; 10+ messages in thread
From: Lukas Czerner @ 2020-04-27 14:25 UTC (permalink / raw)
  To: fstests

On Mon, Apr 27, 2020 at 12:57:56PM +0200, Lukas Czerner wrote:
> On Mon, Apr 27, 2020 at 05:48:02PM +0800, Zorro Lang wrote:
> > On Thu, Apr 23, 2020 at 01:18:29PM +0200, Lukas Czerner wrote:
> > > Add test to validate that the ext4 mount options are properly recognized,
> > > validated and applied to avoid regression as ext4 moves to the new mount
> > > API.
> > > 
> > > Signed-off-by: Lukas Czerner <lczerner@redhat.com>
> > > ---
> > 
> > Hi Lukas,
> > 
> > How can I make this test run pass. I always get many errors[1] on upstream kernel
> > 5.6. Is there a stable way to make it passed on most kernel version? I think an
> > important thing is making sure the test case stable.
> 
> Hi,
> 
> can you show me the full output and the dmesg ?
> 
> Maybe you're using ext2 driver ?
> What I want to test here is ext4 driver, not just ext4 file system. I guess
> I have to rule out the situation where ext3 or ext2 driver is used,
> checking for existence of /proc/fs/ext4/<device> should do the trick I
> think.

The other problem is precisely because of the /proc/fs/ext4/<device>
whenre the device needs to be real device, not the link such as
/dev/mapper/testvg-scratchdev. I have to fix that.


Thanks!
-Lukas

> 
> -Lukas
> 
> > 
> > Thanks,
> > Zorro
> > 
> > [1]
> > # ./check ext4/002
> > FSTYP         -- ext4
> > PLATFORM      -- Linux/x86_64 xxx-xxxxx-xx 5.6.0-rc5-xfs
> > MKFS_OPTIONS  -- /dev/mapper/testvg-scratchdev
> > MOUNT_OPTIONS -- -o acl,user_xattr -o context=system_u:object_r:root_t:s0 /dev/mapper/testvg-scratchdev /mnt/scratch                                                                          
> >                                                                                                                                                                                               
> > ext4/002        [failed, exit status 1]- output mismatch (see /root/git/xfstests-dev/results//ext4/002.out.bad)                                                                               
> >     --- tests/ext4/002.out      2020-04-26 13:43:33.867689308 +0800                                                                                                                           
> >     +++ /root/git/xfstests-dev/results//ext4/002.out.bad        2020-04-26 13:44:22.670986282 +0800                                                                                           
> >     @@ -1,2 +1,83 @@
> >      QA output created by 002
> >      Silence is golden.                                                                                                                                                                       
> >     +mounting ext2 "bsddf" checking "bsddf" (not found) FAILED
> >     +mounting ext2 "minixdf" checking "minixdf" (not found) FAILED
> >     +mounting ext2 "grpid" checking "grpid" (not found) FAILED
> >     +mounting ext2 "bsdgroups" checking "grpid" (not found) FAILED
> >     +mounting ext2 "nogrpid" checking "nogrpid" (not found) FAILED
> >     ...
> >     (Run 'diff -u /root/git/xfstests-dev/tests/ext4/002.out /root/git/xfstests-dev/results//ext4/002.out.bad'  to see the entire diff)                                                        
> > Ran: ext4/002
> > Failures: ext4/002
> > Failed 1 of 1 tests
> > 
> > > v2: ext4 driver can support ext3 and ext2 as well so check the
> > >     compatibility for those fs as well
> > > 
> > >  tests/ext4/002     | 509 +++++++++++++++++++++++++++++++++++++++++++++
> > >  tests/ext4/002.out |   2 +
> > >  tests/ext4/group   |   1 +
> > >  3 files changed, 512 insertions(+)
> > >  create mode 100755 tests/ext4/002
> > >  create mode 100644 tests/ext4/002.out
> > > 
> > > diff --git a/tests/ext4/002 b/tests/ext4/002
> > > new file mode 100755
> > > index 00000000..eda4a2dd
> > > --- /dev/null
> > > +++ b/tests/ext4/002
> > > @@ -0,0 +1,509 @@
> > > +#! /bin/bash
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
> > > +#
> > > +# FS QA Test 002
> > > +#
> > > +# Sanity check of ext4 mount options
> > > +#
> > > +seq=`basename $0`
> > > +seqres=$RESULT_DIR/$seq
> > > +echo "QA output created by $seq"
> > > +
> > > +here=`pwd`
> > > +tmp=/tmp/$$
> > > +status=1	# failure is the default!
> > > +trap "_cleanup; exit \$status" 0 1 2 3 15
> > > +
> > > +_cleanup()
> > > +{
> > > +	cd /
> > > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > > +	if [ -n "$LOOP_LOGDEV" ];then
> > > +		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
> > > +	fi
> > > +	rm -f $tmp.*
> > > +}
> > > +
> > > +# get standard environment, filters and checks
> > > +. ./common/rc
> > > +. ./common/filter
> > > +. ./common/quota
> > > +
> > > +# remove previous $seqres.full before test
> > > +rm -f $seqres.full
> > > +
> > > +echo "Silence is golden."
> > > +
> > > +_supported_fs ext2 ext3 ext4
> > > +_supported_os Linux
> > > +_require_scratch
> > > +_require_quota
> > > +_require_loop
> > > +
> > > +LOG=""
> > > +print_log() {
> > > +	LOG="$LOG $@"
> > > +}
> > > +
> > > +KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
> > > +kernel_gte() {
> > > +	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
> > > +	[ $gte -eq 1 ] && return 0
> > > +	return 1
> > > +}
> > > +
> > > +# This test is only relevant for the newer kernel
> > > +kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 5.7 and higher"
> > > +
> > > +IGNORED="remount,defaults,ignored,removed"
> > > +CHECK_MINFO="lazytime"
> > > +ERR=0
> > > +
> > > +test_mnt() {
> > > +	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
> > > +	[ $? -ne 0 ] && return $?
> > > +
> > > +	if [ $# -eq 1 ]; then
> > > +		OPTS=$1
> > > +	elif [ $# -eq 2 ]; then
> > > +		OPTS=$2
> > > +	else
> > > +		return 0
> > > +	fi
> > > +
> > > +	print_log "checking \"$OPTS\" "
> > > +	# test options in /proc/fs/ext4/dev/options
> > > +	(
> > > +	ret=0
> > > +	IFS=','
> > > +	for option in $OPTS; do
> > > +		if echo $IGNORED | grep -w $option; then
> > > +			continue
> > > +		fi
> > > +
> > > +		[ $option = "noload" ] && option="norecovery"
> > > +
> > > +		if [[ $option = ^* ]]; then
> > > +			expected=1
> > > +		else
> > > +			expected=0
> > > +		fi
> > > +		option=${option#^}
> > > +
> > > +		if echo $CHECK_MINFO | grep -w $option; then
> > > +			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
> > > +			ret=$?
> > > +		else
> > > +			grep $option /proc/fs/ext4/$(basename $SCRATCH_DEV)/options
> > > +			ret=$?
> > > +		fi
> > > +
> > > +		if [ $ret -ne $expected ]; then
> > > +			exit 1
> > > +		fi
> > > +	done
> > > +	) > /dev/null 2>&1
> > > +	return $?
> > > +}
> > > +
> > > +fail() {
> > > +	print_log "   FAILED"
> > > +	ERR=$((ERR+1))
> > > +	echo $LOG | tee -a $seqres.full
> > > +	LOG=""
> > > +}
> > > +
> > > +ok() {
> > > +	print_log "   OK"
> > > +	echo $LOG >> $seqres.full
> > > +	LOG=""
> > > +}
> > > +
> > > +simple_mount() {
> > > +	_mount $* >> $seqres.full 2>&1
> > > +}
> > > +
> > > +# $1 - can hold -n option, if it does argumetns are shifted
> > > +# $1 - options to test
> > > +# $2 - if provided it's the option string to check for
> > > +do_mnt() {
> > > +	device=$SCRATCH_DEV
> > > +	# If -n argument is provided do not specify $SCRATCH_DEV
> > > +	# usefull for remount
> > > +	if [ "$1" == "-n" ]; then
> > > +		unset device
> > > +		shift
> > > +	fi
> > > +
> > > +	if [ -z "$1" ]; then
> > > +		simple_mount $device $SCRATCH_MNT
> > > +		ret=$?
> > > +	else
> > > +		simple_mount -o $1 $device $SCRATCH_MNT
> > > +		ret=$?
> > > +	fi
> > > +	if [ $ret -eq 0 ]; then
> > > +		test_mnt $1 $2
> > > +		ret=$?
> > > +		[ $ret -ne 0 ] && print_log "(not found)"
> > > +	else
> > > +		print_log "(failed mount)"
> > > +	fi
> > > +
> > > +	return $ret
> > > +}
> > > +
> > > +not_mnt() {
> > > +	print_log "SHOULD FAIL mounting $fstype \"$1\" "
> > > +	do_mnt $@
> > > +	if [ $? -eq 0 ]; then
> > > +		fail
> > > +	else
> > > +		ok
> > > +	fi
> > > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +}
> > > +
> > > +_mnt() {
> > > +	print_log "mounting $fstype \"$1\" "
> > > +	do_mnt $@
> > > +	if [ $? -ne 0 ]; then
> > > +		fail
> > > +	else
> > > +		ok
> > > +	fi
> > > +}
> > > +
> > > +mnt() {
> > > +	_mnt $*
> > > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +}
> > > +
> > > +# $1 - options to mount with
> > > +# $2 - options to remount with
> > > +remount() {
> > > +	# First do this specifying both dev and mnt
> > > +	print_log "mounting $fstype \"$1\" "
> > > +	do_mnt $1
> > > +	[ $? -ne 0 ] && fail && return
> > > +	print_log "remounting \"$2\" "
> > > +	do_mnt remount,$2 $3
> > > +	if [ $? -ne 0 ]; then
> > > +		fail
> > > +		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +		return
> > > +	else
> > > +		ok
> > > +	fi
> > > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +
> > > +	# Now just specify mnt
> > > +	print_log "mounting $fstype \"$1\" "
> > > +	do_mnt $1
> > > +	[ $? -ne 0 ] && fail && return
> > > +	print_log "remounting (MNT ONLY) \"$2\" "
> > > +	do_mnt -n remount,$2 $3
> > > +	if [ $? -ne 0 ]; then
> > > +		fail
> > > +	else
> > > +		ok
> > > +	fi
> > > +
> > > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +}
> > > +
> > > +# $1 - options to mount with, or -r argument
> > > +# $2 - options to remount with
> > > +_not_remount() {
> > > +	remount_only=0
> > > +	# If -r is specified we're going to do remount only
> > > +	if [ "$1" == "-r" ]; then
> > > +		remount_only=1
> > > +		# Dont need shift since first argument would
> > > +		# have been consumed by mount anyway
> > > +	fi
> > > +
> > > +	if [ $remount_only -eq 0 ]; then
> > > +		print_log "mounting $fstype \"$1\" "
> > > +		do_mnt $1
> > > +		[ $? -ne 0 ] && fail && return
> > > +	fi
> > > +	print_log "SHOULD FAIL remounting $fstype \"$2\" "
> > > +	do_mnt remount,$2 $3
> > > +	if [ $? -eq 0 ]; then
> > > +		fail
> > > +	else
> > > +		ok
> > > +	fi
> > > +
> > > +	# Now just specify mnt
> > > +	print_log "SHOULD FAIL remounting $fstype (MNT ONLY) \"$2\" "
> > > +	do_mnt -n remount,$2 $3
> > > +	if [ $? -eq 0 ]; then
> > > +		fail
> > > +	else
> > > +		ok
> > > +	fi
> > > +}
> > > +
> > > +not_remount() {
> > > +	_not_remount $*
> > > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +}
> > > +
> > > +
> > > +do_mkfs() {
> > > +	mke2fs -T $fstype -Fq $* >> $seqres.full 2>&1 ||
> > > +	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
> > > +}
> > > +
> > > +not_ext2() {
> > > +	if [[ $fstype == "ext2" ]]; then
> > > +		not_$*
> > > +	else
> > > +		$*
> > > +	fi
> > > +}
> > > +
> > > +only_ext4() {
> > > +	if [[ $fstype == "ext4" ]]; then
> > > +		$*
> > > +	else
> > > +		not_$*
> > > +	fi
> > > +}
> > > +
> > > +# Create logdev for external journal
> > > +LOOP_IMG=$tmp.logdev
> > > +truncate -s 100M $LOOP_IMG
> > > +LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
> > > +majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
> > > +LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
> > > +
> > > +# Test all the extN file system supported by ext4 driver
> > > +fstype=
> > > +for fstype in ext2 ext3 ext4; do
> > > +
> > > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +	$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
> > > +
> > > +	do_mkfs $SCRATCH_DEV
> > > +
> > > +	# do we have fstype support ?
> > > +	do_mnt
> > > +	if [ $? -ne 0 ]; then
> > > +		print_log "$fstype not supported. Skipping..."
> > > +		ok
> > > +		continue
> > > +	fi
> > > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > > +
> > > +	not_mnt failme
> > > +	mnt
> > > +	mnt bsddf
> > > +	mnt minixdf
> > > +	mnt grpid
> > > +	mnt bsdgroups grpid
> > > +	mnt nogrpid
> > > +	mnt sysvgroups nogrpid
> > > +	mnt resgid=1001
> > > +	mnt resuid=1001
> > > +	mnt sb=131072
> > > +	mnt errors=continue
> > > +	mnt errors=panic
> > > +	mnt errors=remount-ro
> > > +	mnt nouid32
> > > +	mnt debug
> > > +	mnt oldalloc removed
> > > +	mnt orlov removed
> > > +	mnt user_xattr
> > > +	mnt nouser_xattr
> > > +	not_ext2 mnt noload norecovery
> > > +	mnt bh removed
> > > +	mnt nobh removed
> > > +	not_ext2 mnt commit=7
> > > +	mnt min_batch_time=200
> > > +	mnt max_batch_time=10000
> > > +	only_ext4 mnt journal_checksum
> > > +	only_ext4 mnt nojournal_checksum
> > > +	only_ext4 mnt journal_async_commit,data=writeback
> > > +	mnt abort ignored
> > > +	not_ext2 mnt data=journal
> > > +	not_ext2 mnt data=ordered
> > > +	not_ext2 mnt data=writeback
> > > +	not_ext2 mnt data_err=abort
> > > +	not_ext2 mnt data_err=ignore ignored
> > > +	mnt usrjquota=aquota.user,jqfmt=vfsv0
> > > +	not_mnt usrjquota=aquota.user
> > > +	mnt usrjquota= ignored
> > > +	mnt grpjquota=aquota.group,jqfmt=vfsv0
> > > +	not_mnt grpjquota=aquota.group
> > > +	mnt grpjquota= ignored
> > > +	mnt jqfmt=vfsold
> > > +	mnt jqfmt=vfsv0
> > > +	mnt jqfmt=vfsv1
> > > +	mnt grpquota
> > > +	mnt quota
> > > +	mnt noquota
> > > +	mnt usrquota
> > > +	mnt grpquota
> > > +	mnt barrier
> > > +	mnt barrier=0 nobarrier
> > > +	mnt barrier=1 barrier
> > > +	mnt barrier=99 barrier
> > > +	mnt nobarrier
> > > +	mnt i_version
> > > +	#mnt dax
> > > +	mnt stripe=512
> > > +	only_ext4 mnt delalloc
> > > +	only_ext4 mnt nodelalloc
> > > +	mnt warn_on_error
> > > +	mnt nowarn_on_error
> > > +	mnt lazytime
> > > +	mnt nolazytime ^lazytime
> > > +	not_mnt debug_want_extra_isize=512
> > > +	mnt debug_want_extra_isize=32 ignored
> > > +	mnt mblk_io_submit removed
> > > +	mnt nomblk_io_submit removed
> > > +	mnt block_validity
> > > +	mnt noblock_validity
> > > +	mnt inode_readahead_blks=16
> > > +	not_ext2 mnt journal_ioprio=6 ignored
> > > +	mnt auto_da_alloc=0 noauto_da_alloc
> > > +	mnt auto_da_alloc=1 auto_da_alloc
> > > +	mnt auto_da_alloc=95 auto_da_alloc
> > > +	mnt auto_da_alloc
> > > +	mnt noauto_da_alloc
> > > +	only_ext4 mnt dioread_nolock
> > > +	kernel_gte 5.6 && only_ext4 mnt nodioread_nolock
> > > +	kernel_gte 5.6 && only_ext4 mnt dioread_lock nodioread_nolock
> > > +	mnt discard
> > > +	mnt nodiscard
> > > +	mnt init_itable=20
> > > +	mnt init_itable
> > > +	mnt init_itable=0
> > > +	mnt noinit_itable
> > > +	mnt max_dir_size_kb=4096
> > > +	mnt test_dummy_encryption
> > > +	mnt nombcache
> > > +	mnt no_mbcache nombcache
> > > +	mnt check=none removed
> > > +	mnt nocheck removed
> > > +	mnt reservation removed
> > > +	mnt noreservation removed
> > > +	not_mnt journal=20
> > > +	not_mnt nonsenseoption
> > > +	not_mnt nonsenseoption=value
> > > +
> > > +	# generic remount check
> > > +	remount barrier nobarrier
> > > +	remount nobarrier barrier
> > > +	remount discard nodiscard
> > > +	remount nodiscard discard
> > > +
> > > +	# Quota remount check
> > > +	remount grpquota usrquota
> > > +	remount usrquota quota
> > > +	remount usrquota usrjquota=q.u,jqfmt=vfsv0
> > > +	remount grpquota grpjquota=q.g,jqfmt=vfsv0
> > > +
> > > +	not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
> > > +	not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
> > > +
> > > +	remount quota usrjquota=q.u,jqfmt=vfsv0
> > > +	not_remount quota grpjquota=q.g,jqfmt=vfsv0
> > > +
> > > +	remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
> > > +	not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
> > > +	not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
> > > +
> > > +	remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
> > > +	remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
> > > +	not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
> > > +	not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
> > > +
> > > +	remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
> > > +	remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
> > > +	remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
> > > +
> > > +	remount jqfmt=vfsv0 grpjquota=q.g
> > > +	remount jqfmt=vfsv0 usrjquota=q.u
> > > +
> > > +	if [[ $fstype != "ext2" ]]; then
> > > +		remount noload data=journal norecovery
> > > +		not_remount data=ordered data=journal
> > > +		not_remount data=journal data=writeback
> > > +		not_remount data=writeback data=ordered
> > > +	fi
> > > +
> > > +	do_mkfs -O journal_dev $LOOP_LOGDEV
> > > +	do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV
> > > +	mnt defaults
> > > +	mnt journal_path=$LOOP_LOGDEV ignored
> > > +	mnt journal_dev=$LOGDEV_DEVNUM ignored
> > > +	not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
> > > +	not_mnt journal_dev=123456 ignored
> > > +	not_mnt journal_dev=999999999999999 ignored
> > > +
> > > +	do_mkfs -E quotatype=prjquota $SCRATCH_DEV
> > > +	mnt prjquota
> > > +
> > > +	# test clearing/changing journalled quota when enabled
> > > +	echo "== Testing active journalled quota" >> $seqres.full
> > > +	_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
> > > +
> > > +	# Prepare and enable quota
> > > +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> > > +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> > > +
> > > +	_not_remount -r grpjquota=
> > > +	_not_remount -r usrjquota=aaquota.user
> > > +	_not_remount -r grpjquota=aaquota.group
> > > +	_not_remount -r jqfmt=vfsv1
> > > +	_not_remount -r noquota
> > > +	_mnt remount,usrquota,grpquota ^usrquota,^grpquota
> > > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > > +
> > > +	# test clearing/changing quota when enabled
> > > +	do_mkfs -E quotatype=^prjquota $SCRATCH_DEV
> > > +	not_mnt prjquota
> > > +	echo "== Testing active non-journalled quota" >> $seqres.full
> > > +	_mnt grpquota,usrquota
> > > +
> > > +	# Prepare and enable quota
> > > +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> > > +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> > > +
> > > +	_not_remount -r noquota
> > > +	_not_remount -r usrjquota=aquota.user
> > > +	_not_remount -r grpjquota=aquota.group
> > > +	_not_remount -r jqfmt=vfsv1
> > > +	_mnt remount,grpjquota= grpquota,^grpjquota
> > > +	_mnt remount,usrjquota= usrquota,^usrjquota
> > > +	_mnt remount,usrquota,grpquota usrquota,grpquota
> > > +	quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
> > > +	_mnt remount,noquota ^usrquota,^grpquota,quota
> > > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > > +
> > > +	# Quota feature
> > > +	echo "== Testing quota feature " >> $seqres.full
> > > +	do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV
> > > +	mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
> > > +	mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
> > > +	mnt jqfmt=vfsv1 ^jqfmt=
> > > +	mnt prjquota
> > > +	mnt usrquota
> > > +	mnt grpquota
> > > +	not_remount defaults usrjquota=aquota.user
> > > +	not_remount defaults grpjquota=aquota.user
> > > +	not_remount defaults jqfmt=vfsv1
> > > +	remount defaults grpjquota=,usrjquota= ignored
> > > +
> > > +done #for fstype in ext2 ext3 ext4; do
> > > +
> > > +$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > > +echo "$ERR errors encountered" >> $seqres.full
> > > +
> > > +status=$ERR
> > > +exit
> > > diff --git a/tests/ext4/002.out b/tests/ext4/002.out
> > > new file mode 100644
> > > index 00000000..c1642bfd
> > > --- /dev/null
> > > +++ b/tests/ext4/002.out
> > > @@ -0,0 +1,2 @@
> > > +QA output created by 002
> > > +Silence is golden.
> > > diff --git a/tests/ext4/group b/tests/ext4/group
> > > index a1adc553..b0aa781a 100644
> > > --- a/tests/ext4/group
> > > +++ b/tests/ext4/group
> > > @@ -4,6 +4,7 @@
> > >  # - comment line before each group is "new" description
> > >  #
> > >  001 auto prealloc quick zero
> > > +002 auto mount
> > >  003 auto quick
> > >  004 auto dump
> > >  005 auto quick metadata ioctl rw
> > > -- 
> > > 2.21.1
> > > 
> > 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] ext4: ext4 mount sanity test
  2020-04-23 11:18 ` [PATCH v2] " Lukas Czerner
  2020-04-27  9:48   ` Zorro Lang
@ 2020-05-17 15:02   ` Eryu Guan
  2020-05-18  7:15     ` Lukas Czerner
  2020-05-18  8:52   ` [PATCH v3] " Lukas Czerner
  2 siblings, 1 reply; 10+ messages in thread
From: Eryu Guan @ 2020-05-17 15:02 UTC (permalink / raw)
  To: Lukas Czerner; +Cc: fstests

On Thu, Apr 23, 2020 at 01:18:29PM +0200, Lukas Czerner wrote:
> Add test to validate that the ext4 mount options are properly recognized,
> validated and applied to avoid regression as ext4 moves to the new mount
> API.
> 
> Signed-off-by: Lukas Czerner <lczerner@redhat.com>

This looks thorough, thanks for the test!

> ---
> v2: ext4 driver can support ext3 and ext2 as well so check the
>     compatibility for those fs as well

I'm using the dedicated ext2 driver for ext2 filesystem on my test vm,
so most of the ext2 tests failed like

+mounting ext2 "bsddf" checking "bsddf" (not found) FAILED                                                
+mounting ext2 "minixdf" checking "minixdf" (not found) FAILED                                            
+mounting ext2 "grpid" checking "grpid" (not found) FAILED                               
+mounting ext2 "bsdgroups" checking "grpid" (not found) FAILED                           
+mounting ext2 "nogrpid" checking "nogrpid" (not found) FAILED                                            
+mounting ext2 "sysvgroups" checking "nogrpid" (not found) FAILED                                         
+mounting ext2 "resgid=1001" checking "resgid=1001" (not found) FAILED                                    
+mounting ext2 "resuid=1001" checking "resuid=1001" (not found) FAILED                                    
+mounting ext2 "sb=131072" checking "sb=131072" (not found) FAILED
+mounting ext2 "errors=continue" checking "errors=continue" (not found) FAILED                            
+mounting ext2 "errors=panic" checking "errors=panic" (not found) FAILED
+mounting ext2 "errors=remount-ro" checking "errors=remount-ro" (not found) FAILED                        
+mounting ext2 "nouid32" checking "nouid32" (not found) FAILED                                                                                                                                                       
+mounting ext2 "debug" checking "debug" (not found) FAILED
+mounting ext2 "user_xattr" checking "user_xattr" (not found) FAILED
+mounting ext2 "nouser_xattr" checking "nouser_xattr" (not found) FAILED                                                                                                                                             
+mounting ext2 "bh" (failed mount) FAILED                                                                                                                                                                            
+mounting ext2 "min_batch_time=200" (failed mount) FAILED
+mounting ext2 "max_batch_time=10000" (failed mount) FAILED     
+mounting ext2 "abort" (failed mount) FAILED
...

So either we check if ext2 is driven by ext4 driver or just remove ext2
support from the test.

> 
>  tests/ext4/002     | 509 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/ext4/002.out |   2 +
>  tests/ext4/group   |   1 +
>  3 files changed, 512 insertions(+)
>  create mode 100755 tests/ext4/002
>  create mode 100644 tests/ext4/002.out
> 
> diff --git a/tests/ext4/002 b/tests/ext4/002
> new file mode 100755
> index 00000000..eda4a2dd
> --- /dev/null
> +++ b/tests/ext4/002
> @@ -0,0 +1,509 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
> +#
> +# FS QA Test 002
> +#
> +# Sanity check of ext4 mount options
> +#
> +seq=`basename $0`
> +seqres=$RESULT_DIR/$seq
> +echo "QA output created by $seq"
> +
> +here=`pwd`
> +tmp=/tmp/$$
> +status=1	# failure is the default!
> +trap "_cleanup; exit \$status" 0 1 2 3 15
> +
> +_cleanup()
> +{
> +	cd /
> +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +	if [ -n "$LOOP_LOGDEV" ];then
> +		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
> +	fi
> +	rm -f $tmp.*
> +}
> +
> +# get standard environment, filters and checks
> +. ./common/rc
> +. ./common/filter
> +. ./common/quota
> +
> +# remove previous $seqres.full before test
> +rm -f $seqres.full
> +
> +echo "Silence is golden."
> +
> +_supported_fs ext2 ext3 ext4
> +_supported_os Linux
> +_require_scratch
> +_require_quota
> +_require_loop
> +
> +LOG=""
> +print_log() {
> +	LOG="$LOG $@"
> +}
> +
> +KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
> +kernel_gte() {
> +	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
> +	[ $gte -eq 1 ] && return 0
> +	return 1
> +}
> +
> +# This test is only relevant for the newer kernel
> +kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 5.7 and higher"

fstests doesn't do any version check, we do run & test for
supported/needed features.

But I assume that the mount behavior should be changed after ext4
adopping the new mount API, so why bothering checking the version? It
just should pass with both old & new kernels.

> +
> +IGNORED="remount,defaults,ignored,removed"
> +CHECK_MINFO="lazytime"
> +ERR=0
> +
> +test_mnt() {
> +	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
> +	[ $? -ne 0 ] && return $?
> +
> +	if [ $# -eq 1 ]; then
> +		OPTS=$1
> +	elif [ $# -eq 2 ]; then
> +		OPTS=$2
> +	else
> +		return 0
> +	fi
> +
> +	print_log "checking \"$OPTS\" "
> +	# test options in /proc/fs/ext4/dev/options
> +	(
> +	ret=0
> +	IFS=','
> +	for option in $OPTS; do
> +		if echo $IGNORED | grep -w $option; then
> +			continue
> +		fi
> +
> +		[ $option = "noload" ] && option="norecovery"
> +
> +		if [[ $option = ^* ]]; then
> +			expected=1
> +		else
> +			expected=0
> +		fi
> +		option=${option#^}
> +
> +		if echo $CHECK_MINFO | grep -w $option; then
> +			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
> +			ret=$?
> +		else
> +			grep $option /proc/fs/ext4/$(basename $SCRATCH_DEV)/options

'basename $SCRATCH_DEV' doesn't work for lvm based scratch devices, e.g.
/dev/mapper/testvg-testlv, as they're symlinks. Use helper '_short_dev'
instead.

> +			ret=$?
> +		fi
> +
> +		if [ $ret -ne $expected ]; then
> +			exit 1
> +		fi
> +	done
> +	) > /dev/null 2>&1
> +	return $?
> +}
> +
> +fail() {
> +	print_log "   FAILED"
> +	ERR=$((ERR+1))
> +	echo $LOG | tee -a $seqres.full
> +	LOG=""
> +}
> +
> +ok() {
> +	print_log "   OK"
> +	echo $LOG >> $seqres.full
> +	LOG=""
> +}
> +
> +simple_mount() {
> +	_mount $* >> $seqres.full 2>&1
> +}
> +
> +# $1 - can hold -n option, if it does argumetns are shifted
> +# $1 - options to test
> +# $2 - if provided it's the option string to check for
> +do_mnt() {
> +	device=$SCRATCH_DEV
> +	# If -n argument is provided do not specify $SCRATCH_DEV
> +	# usefull for remount
> +	if [ "$1" == "-n" ]; then
> +		unset device
> +		shift
> +	fi
> +
> +	if [ -z "$1" ]; then
> +		simple_mount $device $SCRATCH_MNT
> +		ret=$?
> +	else
> +		simple_mount -o $1 $device $SCRATCH_MNT
> +		ret=$?
> +	fi
> +	if [ $ret -eq 0 ]; then
> +		test_mnt $1 $2
> +		ret=$?
> +		[ $ret -ne 0 ] && print_log "(not found)"
> +	else
> +		print_log "(failed mount)"
> +	fi
> +
> +	return $ret
> +}
> +
> +not_mnt() {
> +	print_log "SHOULD FAIL mounting $fstype \"$1\" "
> +	do_mnt $@
> +	if [ $? -eq 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +_mnt() {
> +	print_log "mounting $fstype \"$1\" "
> +	do_mnt $@
> +	if [ $? -ne 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +}
> +
> +mnt() {
> +	_mnt $*
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +# $1 - options to mount with
> +# $2 - options to remount with
> +remount() {
> +	# First do this specifying both dev and mnt
> +	print_log "mounting $fstype \"$1\" "
> +	do_mnt $1
> +	[ $? -ne 0 ] && fail && return
> +	print_log "remounting \"$2\" "
> +	do_mnt remount,$2 $3
> +	if [ $? -ne 0 ]; then
> +		fail
> +		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +		return
> +	else
> +		ok
> +	fi
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +
> +	# Now just specify mnt
> +	print_log "mounting $fstype \"$1\" "
> +	do_mnt $1
> +	[ $? -ne 0 ] && fail && return
> +	print_log "remounting (MNT ONLY) \"$2\" "
> +	do_mnt -n remount,$2 $3
> +	if [ $? -ne 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +# $1 - options to mount with, or -r argument
> +# $2 - options to remount with
> +_not_remount() {
> +	remount_only=0
> +	# If -r is specified we're going to do remount only
> +	if [ "$1" == "-r" ]; then
> +		remount_only=1
> +		# Dont need shift since first argument would
> +		# have been consumed by mount anyway
> +	fi
> +
> +	if [ $remount_only -eq 0 ]; then
> +		print_log "mounting $fstype \"$1\" "
> +		do_mnt $1
> +		[ $? -ne 0 ] && fail && return
> +	fi
> +	print_log "SHOULD FAIL remounting $fstype \"$2\" "
> +	do_mnt remount,$2 $3
> +	if [ $? -eq 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +
> +	# Now just specify mnt
> +	print_log "SHOULD FAIL remounting $fstype (MNT ONLY) \"$2\" "
> +	do_mnt -n remount,$2 $3
> +	if [ $? -eq 0 ]; then
> +		fail
> +	else
> +		ok
> +	fi
> +}
> +
> +not_remount() {
> +	_not_remount $*
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +}
> +
> +
> +do_mkfs() {
> +	mke2fs -T $fstype -Fq $* >> $seqres.full 2>&1 ||
> +	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
> +}
> +
> +not_ext2() {
> +	if [[ $fstype == "ext2" ]]; then
> +		not_$*
> +	else
> +		$*
> +	fi
> +}
> +
> +only_ext4() {
> +	if [[ $fstype == "ext4" ]]; then
> +		$*
> +	else
> +		not_$*
> +	fi
> +}
> +
> +# Create logdev for external journal
> +LOOP_IMG=$tmp.logdev
> +truncate -s 100M $LOOP_IMG
> +LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
> +majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
> +LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
> +
> +# Test all the extN file system supported by ext4 driver
> +fstype=
> +for fstype in ext2 ext3 ext4; do
> +
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +	$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
> +
> +	do_mkfs $SCRATCH_DEV
> +
> +	# do we have fstype support ?
> +	do_mnt
> +	if [ $? -ne 0 ]; then
> +		print_log "$fstype not supported. Skipping..."
> +		ok
> +		continue
> +	fi
> +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> +
> +	not_mnt failme
> +	mnt
> +	mnt bsddf
> +	mnt minixdf
> +	mnt grpid
> +	mnt bsdgroups grpid
> +	mnt nogrpid
> +	mnt sysvgroups nogrpid
> +	mnt resgid=1001
> +	mnt resuid=1001
> +	mnt sb=131072
> +	mnt errors=continue
> +	mnt errors=panic
> +	mnt errors=remount-ro
> +	mnt nouid32
> +	mnt debug
> +	mnt oldalloc removed
> +	mnt orlov removed
> +	mnt user_xattr
> +	mnt nouser_xattr
> +	not_ext2 mnt noload norecovery
> +	mnt bh removed
> +	mnt nobh removed
> +	not_ext2 mnt commit=7
> +	mnt min_batch_time=200
> +	mnt max_batch_time=10000
> +	only_ext4 mnt journal_checksum
> +	only_ext4 mnt nojournal_checksum
> +	only_ext4 mnt journal_async_commit,data=writeback
> +	mnt abort ignored
> +	not_ext2 mnt data=journal
> +	not_ext2 mnt data=ordered
> +	not_ext2 mnt data=writeback
> +	not_ext2 mnt data_err=abort
> +	not_ext2 mnt data_err=ignore ignored
> +	mnt usrjquota=aquota.user,jqfmt=vfsv0
> +	not_mnt usrjquota=aquota.user
> +	mnt usrjquota= ignored
> +	mnt grpjquota=aquota.group,jqfmt=vfsv0
> +	not_mnt grpjquota=aquota.group
> +	mnt grpjquota= ignored
> +	mnt jqfmt=vfsold
> +	mnt jqfmt=vfsv0
> +	mnt jqfmt=vfsv1
> +	mnt grpquota
> +	mnt quota
> +	mnt noquota
> +	mnt usrquota
> +	mnt grpquota
> +	mnt barrier
> +	mnt barrier=0 nobarrier
> +	mnt barrier=1 barrier
> +	mnt barrier=99 barrier
> +	mnt nobarrier
> +	mnt i_version
> +	#mnt dax

Why commented out?

Thanks,
Eryu

> +	mnt stripe=512
> +	only_ext4 mnt delalloc
> +	only_ext4 mnt nodelalloc
> +	mnt warn_on_error
> +	mnt nowarn_on_error
> +	mnt lazytime
> +	mnt nolazytime ^lazytime
> +	not_mnt debug_want_extra_isize=512
> +	mnt debug_want_extra_isize=32 ignored
> +	mnt mblk_io_submit removed
> +	mnt nomblk_io_submit removed
> +	mnt block_validity
> +	mnt noblock_validity
> +	mnt inode_readahead_blks=16
> +	not_ext2 mnt journal_ioprio=6 ignored
> +	mnt auto_da_alloc=0 noauto_da_alloc
> +	mnt auto_da_alloc=1 auto_da_alloc
> +	mnt auto_da_alloc=95 auto_da_alloc
> +	mnt auto_da_alloc
> +	mnt noauto_da_alloc
> +	only_ext4 mnt dioread_nolock
> +	kernel_gte 5.6 && only_ext4 mnt nodioread_nolock
> +	kernel_gte 5.6 && only_ext4 mnt dioread_lock nodioread_nolock
> +	mnt discard
> +	mnt nodiscard
> +	mnt init_itable=20
> +	mnt init_itable
> +	mnt init_itable=0
> +	mnt noinit_itable
> +	mnt max_dir_size_kb=4096
> +	mnt test_dummy_encryption
> +	mnt nombcache
> +	mnt no_mbcache nombcache
> +	mnt check=none removed
> +	mnt nocheck removed
> +	mnt reservation removed
> +	mnt noreservation removed
> +	not_mnt journal=20
> +	not_mnt nonsenseoption
> +	not_mnt nonsenseoption=value
> +
> +	# generic remount check
> +	remount barrier nobarrier
> +	remount nobarrier barrier
> +	remount discard nodiscard
> +	remount nodiscard discard
> +
> +	# Quota remount check
> +	remount grpquota usrquota
> +	remount usrquota quota
> +	remount usrquota usrjquota=q.u,jqfmt=vfsv0
> +	remount grpquota grpjquota=q.g,jqfmt=vfsv0
> +
> +	not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
> +	not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
> +
> +	remount quota usrjquota=q.u,jqfmt=vfsv0
> +	not_remount quota grpjquota=q.g,jqfmt=vfsv0
> +
> +	remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
> +	not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
> +	not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
> +
> +	remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
> +	remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
> +	not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
> +	not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
> +
> +	remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
> +	remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
> +	remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
> +
> +	remount jqfmt=vfsv0 grpjquota=q.g
> +	remount jqfmt=vfsv0 usrjquota=q.u
> +
> +	if [[ $fstype != "ext2" ]]; then
> +		remount noload data=journal norecovery
> +		not_remount data=ordered data=journal
> +		not_remount data=journal data=writeback
> +		not_remount data=writeback data=ordered
> +	fi
> +
> +	do_mkfs -O journal_dev $LOOP_LOGDEV
> +	do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV
> +	mnt defaults
> +	mnt journal_path=$LOOP_LOGDEV ignored
> +	mnt journal_dev=$LOGDEV_DEVNUM ignored
> +	not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
> +	not_mnt journal_dev=123456 ignored
> +	not_mnt journal_dev=999999999999999 ignored
> +
> +	do_mkfs -E quotatype=prjquota $SCRATCH_DEV
> +	mnt prjquota
> +
> +	# test clearing/changing journalled quota when enabled
> +	echo "== Testing active journalled quota" >> $seqres.full
> +	_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
> +
> +	# Prepare and enable quota
> +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> +
> +	_not_remount -r grpjquota=
> +	_not_remount -r usrjquota=aaquota.user
> +	_not_remount -r grpjquota=aaquota.group
> +	_not_remount -r jqfmt=vfsv1
> +	_not_remount -r noquota
> +	_mnt remount,usrquota,grpquota ^usrquota,^grpquota
> +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +
> +	# test clearing/changing quota when enabled
> +	do_mkfs -E quotatype=^prjquota $SCRATCH_DEV
> +	not_mnt prjquota
> +	echo "== Testing active non-journalled quota" >> $seqres.full
> +	_mnt grpquota,usrquota
> +
> +	# Prepare and enable quota
> +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> +
> +	_not_remount -r noquota
> +	_not_remount -r usrjquota=aquota.user
> +	_not_remount -r grpjquota=aquota.group
> +	_not_remount -r jqfmt=vfsv1
> +	_mnt remount,grpjquota= grpquota,^grpjquota
> +	_mnt remount,usrjquota= usrquota,^usrjquota
> +	_mnt remount,usrquota,grpquota usrquota,grpquota
> +	quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
> +	_mnt remount,noquota ^usrquota,^grpquota,quota
> +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +
> +	# Quota feature
> +	echo "== Testing quota feature " >> $seqres.full
> +	do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV
> +	mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
> +	mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
> +	mnt jqfmt=vfsv1 ^jqfmt=
> +	mnt prjquota
> +	mnt usrquota
> +	mnt grpquota
> +	not_remount defaults usrjquota=aquota.user
> +	not_remount defaults grpjquota=aquota.user
> +	not_remount defaults jqfmt=vfsv1
> +	remount defaults grpjquota=,usrjquota= ignored
> +
> +done #for fstype in ext2 ext3 ext4; do
> +
> +$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> +echo "$ERR errors encountered" >> $seqres.full
> +
> +status=$ERR
> +exit
> diff --git a/tests/ext4/002.out b/tests/ext4/002.out
> new file mode 100644
> index 00000000..c1642bfd
> --- /dev/null
> +++ b/tests/ext4/002.out
> @@ -0,0 +1,2 @@
> +QA output created by 002
> +Silence is golden.
> diff --git a/tests/ext4/group b/tests/ext4/group
> index a1adc553..b0aa781a 100644
> --- a/tests/ext4/group
> +++ b/tests/ext4/group
> @@ -4,6 +4,7 @@
>  # - comment line before each group is "new" description
>  #
>  001 auto prealloc quick zero
> +002 auto mount
>  003 auto quick
>  004 auto dump
>  005 auto quick metadata ioctl rw
> -- 
> 2.21.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] ext4: ext4 mount sanity test
  2020-05-17 15:02   ` Eryu Guan
@ 2020-05-18  7:15     ` Lukas Czerner
  0 siblings, 0 replies; 10+ messages in thread
From: Lukas Czerner @ 2020-05-18  7:15 UTC (permalink / raw)
  To: Eryu Guan; +Cc: fstests

On Sun, May 17, 2020 at 11:02:11PM +0800, Eryu Guan wrote:
> On Thu, Apr 23, 2020 at 01:18:29PM +0200, Lukas Czerner wrote:
> > Add test to validate that the ext4 mount options are properly recognized,
> > validated and applied to avoid regression as ext4 moves to the new mount
> > API.
> > 
> > Signed-off-by: Lukas Czerner <lczerner@redhat.com>
> 
> This looks thorough, thanks for the test!
> 
> > ---
> > v2: ext4 driver can support ext3 and ext2 as well so check the
> >     compatibility for those fs as well
> 
> I'm using the dedicated ext2 driver for ext2 filesystem on my test vm,
> so most of the ext2 tests failed like
> 
> +mounting ext2 "bsddf" checking "bsddf" (not found) FAILED                                                
> +mounting ext2 "minixdf" checking "minixdf" (not found) FAILED                                            
> +mounting ext2 "grpid" checking "grpid" (not found) FAILED                               
> +mounting ext2 "bsdgroups" checking "grpid" (not found) FAILED                           
> +mounting ext2 "nogrpid" checking "nogrpid" (not found) FAILED                                            
> +mounting ext2 "sysvgroups" checking "nogrpid" (not found) FAILED                                         
> +mounting ext2 "resgid=1001" checking "resgid=1001" (not found) FAILED                                    
> +mounting ext2 "resuid=1001" checking "resuid=1001" (not found) FAILED                                    
> +mounting ext2 "sb=131072" checking "sb=131072" (not found) FAILED
> +mounting ext2 "errors=continue" checking "errors=continue" (not found) FAILED                            
> +mounting ext2 "errors=panic" checking "errors=panic" (not found) FAILED
> +mounting ext2 "errors=remount-ro" checking "errors=remount-ro" (not found) FAILED                        
> +mounting ext2 "nouid32" checking "nouid32" (not found) FAILED                                                                                                                                                       
> +mounting ext2 "debug" checking "debug" (not found) FAILED
> +mounting ext2 "user_xattr" checking "user_xattr" (not found) FAILED
> +mounting ext2 "nouser_xattr" checking "nouser_xattr" (not found) FAILED                                                                                                                                             
> +mounting ext2 "bh" (failed mount) FAILED                                                                                                                                                                            
> +mounting ext2 "min_batch_time=200" (failed mount) FAILED
> +mounting ext2 "max_batch_time=10000" (failed mount) FAILED     
> +mounting ext2 "abort" (failed mount) FAILED
> ...
> 
> So either we check if ext2 is driven by ext4 driver or just remove ext2
> support from the test.

Thanks for the review, yeah this should be resolved in my new version. I
am not sure why I have not sent that out yet. Will do shortly.

> 
> > 
> >  tests/ext4/002     | 509 +++++++++++++++++++++++++++++++++++++++++++++
> >  tests/ext4/002.out |   2 +
> >  tests/ext4/group   |   1 +
> >  3 files changed, 512 insertions(+)
> >  create mode 100755 tests/ext4/002
> >  create mode 100644 tests/ext4/002.out
> > 
> > diff --git a/tests/ext4/002 b/tests/ext4/002
> > new file mode 100755
> > index 00000000..eda4a2dd
> > --- /dev/null
> > +++ b/tests/ext4/002
> > @@ -0,0 +1,509 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
> > +#
> > +# FS QA Test 002
> > +#
> > +# Sanity check of ext4 mount options
> > +#
> > +seq=`basename $0`
> > +seqres=$RESULT_DIR/$seq
> > +echo "QA output created by $seq"
> > +
> > +here=`pwd`
> > +tmp=/tmp/$$
> > +status=1	# failure is the default!
> > +trap "_cleanup; exit \$status" 0 1 2 3 15
> > +
> > +_cleanup()
> > +{
> > +	cd /
> > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +	if [ -n "$LOOP_LOGDEV" ];then
> > +		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
> > +	fi
> > +	rm -f $tmp.*
> > +}
> > +
> > +# get standard environment, filters and checks
> > +. ./common/rc
> > +. ./common/filter
> > +. ./common/quota
> > +
> > +# remove previous $seqres.full before test
> > +rm -f $seqres.full
> > +
> > +echo "Silence is golden."
> > +
> > +_supported_fs ext2 ext3 ext4
> > +_supported_os Linux
> > +_require_scratch
> > +_require_quota
> > +_require_loop
> > +
> > +LOG=""
> > +print_log() {
> > +	LOG="$LOG $@"
> > +}
> > +
> > +KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
> > +kernel_gte() {
> > +	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
> > +	[ $gte -eq 1 ] && return 0
> > +	return 1
> > +}
> > +
> > +# This test is only relevant for the newer kernel
> > +kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 5.7 and higher"
> 
> fstests doesn't do any version check, we do run & test for
> supported/needed features.

Mount options changed in the past (added/removed) and I can't rely on
mount returning EINVAL for non-existent mount optins since that might
very well be a bug.
I though 4.19 was a good enough baseline (that I tested) and I don't
want to special case more options to allow older kernels.

> 
> But I assume that the mount behavior should be changed after ext4
> adopping the new mount API, so why bothering checking the version? It
> just should pass with both old & new kernels.

It will not pass for old kernels if the kernel does not have a mount
options we're testing.

The mount behaviour should remain the same after the new mount API.
That's the point of this test. But as the new options are added in the
future we can special case them with this kernel_gte check, as I've done
with some options already.

> 
> > +
> > +IGNORED="remount,defaults,ignored,removed"
> > +CHECK_MINFO="lazytime"
> > +ERR=0
> > +
> > +test_mnt() {
> > +	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
> > +	[ $? -ne 0 ] && return $?
> > +
> > +	if [ $# -eq 1 ]; then
> > +		OPTS=$1
> > +	elif [ $# -eq 2 ]; then
> > +		OPTS=$2
> > +	else
> > +		return 0
> > +	fi
> > +
> > +	print_log "checking \"$OPTS\" "
> > +	# test options in /proc/fs/ext4/dev/options
> > +	(
> > +	ret=0
> > +	IFS=','
> > +	for option in $OPTS; do
> > +		if echo $IGNORED | grep -w $option; then
> > +			continue
> > +		fi
> > +
> > +		[ $option = "noload" ] && option="norecovery"
> > +
> > +		if [[ $option = ^* ]]; then
> > +			expected=1
> > +		else
> > +			expected=0
> > +		fi
> > +		option=${option#^}
> > +
> > +		if echo $CHECK_MINFO | grep -w $option; then
> > +			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
> > +			ret=$?
> > +		else
> > +			grep $option /proc/fs/ext4/$(basename $SCRATCH_DEV)/options
> 
> 'basename $SCRATCH_DEV' doesn't work for lvm based scratch devices, e.g.
> /dev/mapper/testvg-testlv, as they're symlinks. Use helper '_short_dev'
> instead.

I've fixed that in the new version using readlink, but it's good to know
there is _short_dev/_real_dev helper, I am going to use that instead.

Honestly I think that SCRATCH_DEV should just be sanitized so that we do
not have to worry about it.

> 
> > +			ret=$?
> > +		fi
> > +
> > +		if [ $ret -ne $expected ]; then
> > +			exit 1
> > +		fi
> > +	done
> > +	) > /dev/null 2>&1
> > +	return $?
> > +}
> > +
> > +fail() {
> > +	print_log "   FAILED"
> > +	ERR=$((ERR+1))
> > +	echo $LOG | tee -a $seqres.full
> > +	LOG=""
> > +}
> > +
> > +ok() {
> > +	print_log "   OK"
> > +	echo $LOG >> $seqres.full
> > +	LOG=""
> > +}
> > +
> > +simple_mount() {
> > +	_mount $* >> $seqres.full 2>&1
> > +}
> > +
> > +# $1 - can hold -n option, if it does argumetns are shifted
> > +# $1 - options to test
> > +# $2 - if provided it's the option string to check for
> > +do_mnt() {
> > +	device=$SCRATCH_DEV
> > +	# If -n argument is provided do not specify $SCRATCH_DEV
> > +	# usefull for remount
> > +	if [ "$1" == "-n" ]; then
> > +		unset device
> > +		shift
> > +	fi
> > +
> > +	if [ -z "$1" ]; then
> > +		simple_mount $device $SCRATCH_MNT
> > +		ret=$?
> > +	else
> > +		simple_mount -o $1 $device $SCRATCH_MNT
> > +		ret=$?
> > +	fi
> > +	if [ $ret -eq 0 ]; then
> > +		test_mnt $1 $2
> > +		ret=$?
> > +		[ $ret -ne 0 ] && print_log "(not found)"
> > +	else
> > +		print_log "(failed mount)"
> > +	fi
> > +
> > +	return $ret
> > +}
> > +
> > +not_mnt() {
> > +	print_log "SHOULD FAIL mounting $fstype \"$1\" "
> > +	do_mnt $@
> > +	if [ $? -eq 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +_mnt() {
> > +	print_log "mounting $fstype \"$1\" "
> > +	do_mnt $@
> > +	if [ $? -ne 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +}
> > +
> > +mnt() {
> > +	_mnt $*
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +# $1 - options to mount with
> > +# $2 - options to remount with
> > +remount() {
> > +	# First do this specifying both dev and mnt
> > +	print_log "mounting $fstype \"$1\" "
> > +	do_mnt $1
> > +	[ $? -ne 0 ] && fail && return
> > +	print_log "remounting \"$2\" "
> > +	do_mnt remount,$2 $3
> > +	if [ $? -ne 0 ]; then
> > +		fail
> > +		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +		return
> > +	else
> > +		ok
> > +	fi
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +
> > +	# Now just specify mnt
> > +	print_log "mounting $fstype \"$1\" "
> > +	do_mnt $1
> > +	[ $? -ne 0 ] && fail && return
> > +	print_log "remounting (MNT ONLY) \"$2\" "
> > +	do_mnt -n remount,$2 $3
> > +	if [ $? -ne 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +# $1 - options to mount with, or -r argument
> > +# $2 - options to remount with
> > +_not_remount() {
> > +	remount_only=0
> > +	# If -r is specified we're going to do remount only
> > +	if [ "$1" == "-r" ]; then
> > +		remount_only=1
> > +		# Dont need shift since first argument would
> > +		# have been consumed by mount anyway
> > +	fi
> > +
> > +	if [ $remount_only -eq 0 ]; then
> > +		print_log "mounting $fstype \"$1\" "
> > +		do_mnt $1
> > +		[ $? -ne 0 ] && fail && return
> > +	fi
> > +	print_log "SHOULD FAIL remounting $fstype \"$2\" "
> > +	do_mnt remount,$2 $3
> > +	if [ $? -eq 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +
> > +	# Now just specify mnt
> > +	print_log "SHOULD FAIL remounting $fstype (MNT ONLY) \"$2\" "
> > +	do_mnt -n remount,$2 $3
> > +	if [ $? -eq 0 ]; then
> > +		fail
> > +	else
> > +		ok
> > +	fi
> > +}
> > +
> > +not_remount() {
> > +	_not_remount $*
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +}
> > +
> > +
> > +do_mkfs() {
> > +	mke2fs -T $fstype -Fq $* >> $seqres.full 2>&1 ||
> > +	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
> > +}
> > +
> > +not_ext2() {
> > +	if [[ $fstype == "ext2" ]]; then
> > +		not_$*
> > +	else
> > +		$*
> > +	fi
> > +}
> > +
> > +only_ext4() {
> > +	if [[ $fstype == "ext4" ]]; then
> > +		$*
> > +	else
> > +		not_$*
> > +	fi
> > +}
> > +
> > +# Create logdev for external journal
> > +LOOP_IMG=$tmp.logdev
> > +truncate -s 100M $LOOP_IMG
> > +LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
> > +majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
> > +LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
> > +
> > +# Test all the extN file system supported by ext4 driver
> > +fstype=
> > +for fstype in ext2 ext3 ext4; do
> > +
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +	$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
> > +
> > +	do_mkfs $SCRATCH_DEV
> > +
> > +	# do we have fstype support ?
> > +	do_mnt
> > +	if [ $? -ne 0 ]; then
> > +		print_log "$fstype not supported. Skipping..."
> > +		ok
> > +		continue
> > +	fi
> > +	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
> > +
> > +	not_mnt failme
> > +	mnt
> > +	mnt bsddf
> > +	mnt minixdf
> > +	mnt grpid
> > +	mnt bsdgroups grpid
> > +	mnt nogrpid
> > +	mnt sysvgroups nogrpid
> > +	mnt resgid=1001
> > +	mnt resuid=1001
> > +	mnt sb=131072
> > +	mnt errors=continue
> > +	mnt errors=panic
> > +	mnt errors=remount-ro
> > +	mnt nouid32
> > +	mnt debug
> > +	mnt oldalloc removed
> > +	mnt orlov removed
> > +	mnt user_xattr
> > +	mnt nouser_xattr
> > +	not_ext2 mnt noload norecovery
> > +	mnt bh removed
> > +	mnt nobh removed
> > +	not_ext2 mnt commit=7
> > +	mnt min_batch_time=200
> > +	mnt max_batch_time=10000
> > +	only_ext4 mnt journal_checksum
> > +	only_ext4 mnt nojournal_checksum
> > +	only_ext4 mnt journal_async_commit,data=writeback
> > +	mnt abort ignored
> > +	not_ext2 mnt data=journal
> > +	not_ext2 mnt data=ordered
> > +	not_ext2 mnt data=writeback
> > +	not_ext2 mnt data_err=abort
> > +	not_ext2 mnt data_err=ignore ignored
> > +	mnt usrjquota=aquota.user,jqfmt=vfsv0
> > +	not_mnt usrjquota=aquota.user
> > +	mnt usrjquota= ignored
> > +	mnt grpjquota=aquota.group,jqfmt=vfsv0
> > +	not_mnt grpjquota=aquota.group
> > +	mnt grpjquota= ignored
> > +	mnt jqfmt=vfsold
> > +	mnt jqfmt=vfsv0
> > +	mnt jqfmt=vfsv1
> > +	mnt grpquota
> > +	mnt quota
> > +	mnt noquota
> > +	mnt usrquota
> > +	mnt grpquota
> > +	mnt barrier
> > +	mnt barrier=0 nobarrier
> > +	mnt barrier=1 barrier
> > +	mnt barrier=99 barrier
> > +	mnt nobarrier
> > +	mnt i_version
> > +	#mnt dax
> 
> Why commented out?

This requires a special device, I have not implemented support for this
options in this test yet.

Thanks!
-Lukas

> 
> Thanks,
> Eryu
> 
> > +	mnt stripe=512
> > +	only_ext4 mnt delalloc
> > +	only_ext4 mnt nodelalloc
> > +	mnt warn_on_error
> > +	mnt nowarn_on_error
> > +	mnt lazytime
> > +	mnt nolazytime ^lazytime
> > +	not_mnt debug_want_extra_isize=512
> > +	mnt debug_want_extra_isize=32 ignored
> > +	mnt mblk_io_submit removed
> > +	mnt nomblk_io_submit removed
> > +	mnt block_validity
> > +	mnt noblock_validity
> > +	mnt inode_readahead_blks=16
> > +	not_ext2 mnt journal_ioprio=6 ignored
> > +	mnt auto_da_alloc=0 noauto_da_alloc
> > +	mnt auto_da_alloc=1 auto_da_alloc
> > +	mnt auto_da_alloc=95 auto_da_alloc
> > +	mnt auto_da_alloc
> > +	mnt noauto_da_alloc
> > +	only_ext4 mnt dioread_nolock
> > +	kernel_gte 5.6 && only_ext4 mnt nodioread_nolock
> > +	kernel_gte 5.6 && only_ext4 mnt dioread_lock nodioread_nolock
> > +	mnt discard
> > +	mnt nodiscard
> > +	mnt init_itable=20
> > +	mnt init_itable
> > +	mnt init_itable=0
> > +	mnt noinit_itable
> > +	mnt max_dir_size_kb=4096
> > +	mnt test_dummy_encryption
> > +	mnt nombcache
> > +	mnt no_mbcache nombcache
> > +	mnt check=none removed
> > +	mnt nocheck removed
> > +	mnt reservation removed
> > +	mnt noreservation removed
> > +	not_mnt journal=20
> > +	not_mnt nonsenseoption
> > +	not_mnt nonsenseoption=value
> > +
> > +	# generic remount check
> > +	remount barrier nobarrier
> > +	remount nobarrier barrier
> > +	remount discard nodiscard
> > +	remount nodiscard discard
> > +
> > +	# Quota remount check
> > +	remount grpquota usrquota
> > +	remount usrquota quota
> > +	remount usrquota usrjquota=q.u,jqfmt=vfsv0
> > +	remount grpquota grpjquota=q.g,jqfmt=vfsv0
> > +
> > +	not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
> > +	not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
> > +
> > +	remount quota usrjquota=q.u,jqfmt=vfsv0
> > +	not_remount quota grpjquota=q.g,jqfmt=vfsv0
> > +
> > +	remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
> > +	not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
> > +	not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
> > +
> > +	remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
> > +	remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
> > +	not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
> > +	not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
> > +
> > +	remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
> > +	remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
> > +	remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
> > +
> > +	remount jqfmt=vfsv0 grpjquota=q.g
> > +	remount jqfmt=vfsv0 usrjquota=q.u
> > +
> > +	if [[ $fstype != "ext2" ]]; then
> > +		remount noload data=journal norecovery
> > +		not_remount data=ordered data=journal
> > +		not_remount data=journal data=writeback
> > +		not_remount data=writeback data=ordered
> > +	fi
> > +
> > +	do_mkfs -O journal_dev $LOOP_LOGDEV
> > +	do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV
> > +	mnt defaults
> > +	mnt journal_path=$LOOP_LOGDEV ignored
> > +	mnt journal_dev=$LOGDEV_DEVNUM ignored
> > +	not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
> > +	not_mnt journal_dev=123456 ignored
> > +	not_mnt journal_dev=999999999999999 ignored
> > +
> > +	do_mkfs -E quotatype=prjquota $SCRATCH_DEV
> > +	mnt prjquota
> > +
> > +	# test clearing/changing journalled quota when enabled
> > +	echo "== Testing active journalled quota" >> $seqres.full
> > +	_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
> > +
> > +	# Prepare and enable quota
> > +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> > +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> > +
> > +	_not_remount -r grpjquota=
> > +	_not_remount -r usrjquota=aaquota.user
> > +	_not_remount -r grpjquota=aaquota.group
> > +	_not_remount -r jqfmt=vfsv1
> > +	_not_remount -r noquota
> > +	_mnt remount,usrquota,grpquota ^usrquota,^grpquota
> > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +
> > +	# test clearing/changing quota when enabled
> > +	do_mkfs -E quotatype=^prjquota $SCRATCH_DEV
> > +	not_mnt prjquota
> > +	echo "== Testing active non-journalled quota" >> $seqres.full
> > +	_mnt grpquota,usrquota
> > +
> > +	# Prepare and enable quota
> > +	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
> > +	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
> > +
> > +	_not_remount -r noquota
> > +	_not_remount -r usrjquota=aquota.user
> > +	_not_remount -r grpjquota=aquota.group
> > +	_not_remount -r jqfmt=vfsv1
> > +	_mnt remount,grpjquota= grpquota,^grpjquota
> > +	_mnt remount,usrjquota= usrquota,^usrjquota
> > +	_mnt remount,usrquota,grpquota usrquota,grpquota
> > +	quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
> > +	_mnt remount,noquota ^usrquota,^grpquota,quota
> > +	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +
> > +	# Quota feature
> > +	echo "== Testing quota feature " >> $seqres.full
> > +	do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV
> > +	mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
> > +	mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
> > +	mnt jqfmt=vfsv1 ^jqfmt=
> > +	mnt prjquota
> > +	mnt usrquota
> > +	mnt grpquota
> > +	not_remount defaults usrjquota=aquota.user
> > +	not_remount defaults grpjquota=aquota.user
> > +	not_remount defaults jqfmt=vfsv1
> > +	remount defaults grpjquota=,usrjquota= ignored
> > +
> > +done #for fstype in ext2 ext3 ext4; do
> > +
> > +$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
> > +echo "$ERR errors encountered" >> $seqres.full
> > +
> > +status=$ERR
> > +exit
> > diff --git a/tests/ext4/002.out b/tests/ext4/002.out
> > new file mode 100644
> > index 00000000..c1642bfd
> > --- /dev/null
> > +++ b/tests/ext4/002.out
> > @@ -0,0 +1,2 @@
> > +QA output created by 002
> > +Silence is golden.
> > diff --git a/tests/ext4/group b/tests/ext4/group
> > index a1adc553..b0aa781a 100644
> > --- a/tests/ext4/group
> > +++ b/tests/ext4/group
> > @@ -4,6 +4,7 @@
> >  # - comment line before each group is "new" description
> >  #
> >  001 auto prealloc quick zero
> > +002 auto mount
> >  003 auto quick
> >  004 auto dump
> >  005 auto quick metadata ioctl rw
> > -- 
> > 2.21.1
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3] ext4: ext4 mount sanity test
  2020-04-23 11:18 ` [PATCH v2] " Lukas Czerner
  2020-04-27  9:48   ` Zorro Lang
  2020-05-17 15:02   ` Eryu Guan
@ 2020-05-18  8:52   ` Lukas Czerner
  2 siblings, 0 replies; 10+ messages in thread
From: Lukas Czerner @ 2020-05-18  8:52 UTC (permalink / raw)
  To: fstests

Add test to validate that the ext4 mount options are properly recognized,
validated and applied to avoid regression as ext4 moves to the new mount
API.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
v2: ext4 driver can support ext3 and ext2 as well so check the
    compatibility for those fs as well
v3: Use real scratch device node, not the link to determine options
    Test mount options set in super block via tune2fs


 tests/ext4/002     | 566 +++++++++++++++++++++++++++++++++++++++++++++
 tests/ext4/002.out |   2 +
 tests/ext4/group   |   1 +
 3 files changed, 569 insertions(+)
 create mode 100755 tests/ext4/002
 create mode 100644 tests/ext4/002.out

diff --git a/tests/ext4/002 b/tests/ext4/002
new file mode 100755
index 00000000..6be24bc2
--- /dev/null
+++ b/tests/ext4/002
@@ -0,0 +1,566 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>.
+#
+# FS QA Test 002
+#
+# Sanity check of ext4 mount options
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	cd /
+	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+	if [ -n "$LOOP_LOGDEV" ];then
+		_destroy_loop_device $LOOP_LOGDEV 2>/dev/null
+	fi
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/quota
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+echo "Silence is golden."
+
+SIZE=$((1024 * 1024))	# 1GB in KB
+LOGSIZE=$((10 *1024))	# 10MB in KB
+
+_supported_fs ext2 ext3 ext4
+_supported_os Linux
+_require_scratch_size $SIZE
+_require_quota
+_require_loop
+_require_command "$TUNE2FS_PROG" tune2fs
+MKE2FS_PROG=$(type -P mke2fs)
+_require_command "$MKE2FS_PROG" mke2fs
+
+LOG=""
+print_log() {
+	LOG="$LOG $@"
+}
+
+KERNEL_VERSION=`uname -r | cut -d'.' -f1,2`
+kernel_gte() {
+	gte=`echo "$KERNEL_VERSION >= $1" | $BC_PROG`
+	[ $gte -eq 1 ] && return 0
+	return 1
+}
+
+# This test is only relevant for the newer kernel
+kernel_gte 4.19 || _notrun "This test is only relevant for kernel versions 4.19 and higher"
+
+IGNORED="remount,defaults,ignored,removed"
+CHECK_MINFO="lazytime,noatime,nodiratime,noexec,nosuid,ro"
+ERR=0
+
+test_mnt() {
+	findmnt -n $SCRATCH_DEV > /dev/null 2>&1
+	[ $? -ne 0 ] && return $?
+
+	if [ $# -eq 1 ]; then
+		OPTS=$1
+	elif [ $# -eq 2 ]; then
+		OPTS=$2
+	else
+		return 0
+	fi
+
+	print_log "checking \"$OPTS\" "
+	# test options in /proc/fs/ext4/dev/options
+	(
+	ret=0
+	IFS=','
+	for option in $OPTS; do
+		if echo $IGNORED | grep -w $option; then
+			continue
+		fi
+
+		[ $option = "noload" ] && option="norecovery"
+
+		if [[ $option = ^* ]]; then
+			expected=1
+		else
+			expected=0
+		fi
+		option=${option#^}
+
+		if echo $CHECK_MINFO | grep -w $option; then
+			findmnt -n -o OPTIONS $SCRATCH_DEV | grep $option
+			ret=$?
+		else
+			grep $option /proc/fs/ext4/$(_short_dev $SCRATCH_DEV)/options
+			ret=$?
+		fi
+
+		if [ $ret -ne $expected ]; then
+			exit 1
+		fi
+	done
+	) > /dev/null 2>&1
+	return $?
+}
+
+fail() {
+	print_log "   FAILED"
+	ERR=$((ERR+1))
+	echo $LOG | tee -a $seqres.full
+	LOG=""
+}
+
+ok() {
+	print_log "   OK"
+	echo $LOG >> $seqres.full
+	LOG=""
+}
+
+simple_mount() {
+	_mount $* >> $seqres.full 2>&1
+}
+
+# $1 - can hold -n option, if it does argumetns are shifted
+# $1 - options to test
+# $2 - if provided it's the option string to check for
+do_mnt() {
+	device=$SCRATCH_DEV
+	# If -n argument is provided do not specify $SCRATCH_DEV
+	# usefull for remount
+	if [ "$1" == "-n" ]; then
+		unset device
+		shift
+	fi
+
+	if [ -z "$1" ]; then
+		simple_mount $device $SCRATCH_MNT
+		ret=$?
+	else
+		simple_mount -o $1 $device $SCRATCH_MNT
+		ret=$?
+	fi
+	if [ $ret -eq 0 ]; then
+		test_mnt $1 $2
+		ret=$?
+		[ $ret -ne 0 ] && print_log "(not found)"
+	else
+		print_log "(failed mount)"
+	fi
+
+	return $ret
+}
+
+not_mnt() {
+	# We don't need -t not not_ variant
+	if [ "$1" == "-t" ]; then
+		shift
+	fi
+
+	print_log "SHOULD FAIL mounting $fstype \"$1\" "
+	do_mnt $@
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+_mnt() {
+	print_log "mounting $fstype \"$1\" "
+	do_mnt $@
+	if [ $? -ne 0 ]; then
+		fail
+	else
+		ok
+	fi
+}
+
+mnt() {
+	# Do we need to run the tune2fs mount option test ?
+	t2fs=0
+	if [ "$1" == "-t" ]; then
+		t2fs=1
+		shift
+	fi
+
+	_mnt $*
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+
+	[ "$t2fs" -eq 0 ] && return
+
+	op_set=$1
+	if [ $# -eq 1 ]; then
+		check=$1
+	elif [ $# -eq 2 ]; then
+		check=$2
+	else
+		return 0
+	fi
+
+	# some options need translation for tune2fs
+	op_set=$(echo $op_set | sed -e 's/data=journal/journal_data/' \
+				    -e 's/data=ordered/journal_data_ordered/' \
+				    -e 's/data=writeback/journal_data_writeback/')
+	$TUNE2FS_PROG -o $op_set $SCRATCH_DEV > /dev/null 2>&1
+	_mnt "defaults" $check
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+	if [ "$op_set" = ^* ]; then
+		op_set=${op_set#^}
+	else
+		op_set="^${op_set}"
+	fi
+	$TUNE2FS_PROG -o $op_set $SCRATCH_DEV > /dev/null 2>&1
+}
+
+# $1 - options to mount with
+# $2 - options to remount with
+remount() {
+	# First do this specifying both dev and mnt
+	print_log "mounting $fstype \"$1\" "
+	do_mnt $1
+	[ $? -ne 0 ] && fail && return
+	print_log "remounting \"$2\" "
+	do_mnt remount,$2 $3
+	if [ $? -ne 0 ]; then
+		fail
+		$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+		return
+	else
+		ok
+	fi
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+
+	# Now just specify mnt
+	print_log "mounting $fstype \"$1\" "
+	do_mnt $1
+	[ $? -ne 0 ] && fail && return
+	print_log "remounting (MNT ONLY) \"$2\" "
+	do_mnt -n remount,$2 $3
+	if [ $? -ne 0 ]; then
+		fail
+	else
+		ok
+	fi
+
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+# $1 - options to mount with, or -r argument
+# $2 - options to remount with
+_not_remount() {
+	remount_only=0
+	# If -r is specified we're going to do remount only
+	if [ "$1" == "-r" ]; then
+		remount_only=1
+		# Dont need shift since first argument would
+		# have been consumed by mount anyway
+	fi
+
+	if [ $remount_only -eq 0 ]; then
+		print_log "mounting $fstype \"$1\" "
+		do_mnt $1
+		[ $? -ne 0 ] && fail && return
+	fi
+	print_log "SHOULD FAIL remounting $fstype \"$2\" "
+	do_mnt remount,$2 $3
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+
+	# Now just specify mnt
+	print_log "SHOULD FAIL remounting $fstype (MNT ONLY) \"$2\" "
+	do_mnt -n remount,$2 $3
+	if [ $? -eq 0 ]; then
+		fail
+	else
+		ok
+	fi
+}
+
+not_remount() {
+	_not_remount $*
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+}
+
+
+do_mkfs() {
+	$MKE2FS_PROG -T $fstype -Fq $* >> $seqres.full 2>&1 ||
+	_fail "mkfs failed - $MKFS_EXT4_PROG -Fq $* $SCRATCH_DEV"
+}
+
+not_ext2() {
+	if [[ $fstype == "ext2" ]]; then
+		not_$*
+	else
+		$*
+	fi
+}
+
+only_ext4() {
+	if [[ $fstype == "ext4" ]]; then
+		$*
+	else
+		not_$*
+	fi
+}
+
+# Create logdev for external journal
+LOOP_IMG=$tmp.logdev
+truncate -s ${LOGSIZE}k $LOOP_IMG
+LOOP_LOGDEV=`_create_loop_device $LOOP_IMG`
+majmin=`stat -c "%t:%T" $LOOP_LOGDEV`
+LOGDEV_DEVNUM=`echo "${majmin%:*}*2^8 + ${majmin#*:}" | bc`
+
+# Test all the extN file system supported by ext4 driver
+fstype=
+for fstype in ext2 ext3 ext4; do
+
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+	$UMOUNT_PROG $SCRATCH_DEV 2> /dev/null
+
+	do_mkfs $SCRATCH_DEV ${SIZE}k
+
+	# do we have fstype support ?
+	do_mnt
+	if [ $? -ne 0 ]; then
+		print_log "$fstype not supported. Skipping..."
+		ok
+		continue
+	fi
+	if [ ! -f /proc/fs/ext4/$(_short_dev $SCRATCH_DEV)/options ]; then
+		print_log "$fstype not supported. Skipping..."
+		ok
+		continue
+	fi
+
+	$UMOUNT_PROG $SCRATCH_MNT 2> /dev/null
+
+	not_mnt failme
+	mnt
+	mnt bsddf
+	mnt minixdf
+	mnt grpid
+	mnt -t bsdgroups grpid
+	mnt nogrpid
+	mnt sysvgroups nogrpid
+	mnt resgid=1001
+	mnt resuid=1001
+	mnt sb=131072
+	mnt errors=continue
+	mnt errors=panic
+	mnt errors=remount-ro
+	mnt nouid32
+	mnt debug
+	mnt oldalloc removed
+	mnt orlov removed
+	mnt -t user_xattr
+	mnt nouser_xattr
+	mnt -t acl
+	not_ext2 mnt noload norecovery
+	mnt bh removed
+	mnt nobh removed
+	not_ext2 mnt commit=7
+	mnt min_batch_time=200
+	mnt max_batch_time=10000
+	only_ext4 mnt journal_checksum
+	only_ext4 mnt nojournal_checksum
+	only_ext4 mnt journal_async_commit,data=writeback
+	mnt abort ignored
+	not_ext2 mnt -t data=journal
+	not_ext2 mnt -t data=ordered
+	not_ext2 mnt -t data=writeback
+	not_ext2 mnt data_err=abort
+	not_ext2 mnt data_err=ignore ignored
+	mnt usrjquota=aquota.user,jqfmt=vfsv0
+	not_mnt usrjquota=aquota.user
+	mnt usrjquota= ignored
+	mnt grpjquota=aquota.group,jqfmt=vfsv0
+	not_mnt grpjquota=aquota.group
+	mnt grpjquota= ignored
+	mnt jqfmt=vfsold
+	mnt jqfmt=vfsv0
+	mnt jqfmt=vfsv1
+	mnt grpquota
+	mnt quota
+	mnt noquota
+	mnt usrquota
+	mnt grpquota
+	mnt barrier
+	mnt barrier=0 nobarrier
+	mnt barrier=1 barrier
+	mnt barrier=99 barrier
+	mnt -t nobarrier
+	mnt i_version
+	#mnt dax
+	mnt stripe=512
+	only_ext4 mnt delalloc
+	only_ext4 mnt -t nodelalloc
+	mnt warn_on_error
+	mnt nowarn_on_error
+	not_mnt debug_want_extra_isize=512
+	mnt debug_want_extra_isize=32 ignored
+	mnt mblk_io_submit removed
+	mnt nomblk_io_submit removed
+	mnt -t block_validity
+	mnt noblock_validity
+	mnt inode_readahead_blks=16
+	not_ext2 mnt journal_ioprio=6 ignored
+	mnt auto_da_alloc=0 noauto_da_alloc
+	mnt auto_da_alloc=1 auto_da_alloc
+	mnt auto_da_alloc=95 auto_da_alloc
+	mnt auto_da_alloc
+	mnt noauto_da_alloc
+	only_ext4 mnt dioread_nolock
+	kernel_gte 5.6 && only_ext4 mnt nodioread_nolock
+	kernel_gte 5.6 && only_ext4 mnt dioread_lock nodioread_nolock
+	mnt -t discard
+	mnt nodiscard
+	mnt init_itable=20
+	mnt init_itable
+	mnt init_itable=0
+	mnt noinit_itable
+	mnt max_dir_size_kb=4096
+	#mnt test_dummy_encryption
+	mnt nombcache
+	mnt no_mbcache nombcache
+	mnt check=none removed
+	mnt nocheck removed
+	mnt reservation removed
+	mnt noreservation removed
+	not_mnt journal=20
+	not_mnt nonsenseoption
+	not_mnt nonsenseoption=value
+
+	# generic mount options
+	mnt lazytime
+	mnt nolazytime ^lazytime
+	mnt noatime
+	mnt nodiratime
+	mnt noexec
+	mnt nosuid
+	mnt ro
+
+	# generic remount check
+	remount barrier nobarrier
+	remount nobarrier barrier
+	remount discard nodiscard
+	remount nodiscard discard
+
+	# Quota remount check
+	remount grpquota usrquota
+	remount usrquota quota
+	remount usrquota usrjquota=q.u,jqfmt=vfsv0
+	remount grpquota grpjquota=q.g,jqfmt=vfsv0
+
+	not_remount usrquota grpjquota=q.g,jqfmt=vfsv0
+	not_remount grpquota usrjquota=q.u,jqfmt=vfsv0
+
+	remount quota usrjquota=q.u,jqfmt=vfsv0
+	not_remount quota grpjquota=q.g,jqfmt=vfsv0
+
+	remount usrjquota=q.u,jqfmt=vfsv0 grpjquota=q.g
+	not_remount usrjquota=q.u,jqfmt=vfsv0 usrjquota=q.ua
+	not_remount grpjquota=q.g,jqfmt=vfsv0 grpjquota=q.ga
+
+	remount usrjquota=q.u,jqfmt=vfsv0 usrquota usrjquota=q.u,jqfmt=vfsv0
+	remount grpjquota=q.g,jqfmt=vfsv0 grpquota grpjquota=q.g,jqfmt=vfsv0
+	not_remount usrjquota=q.u,jqfmt=vfsv0 grpquota
+	not_remount grpjquota=q.g,jqfmt=vfsv0 usrquota
+
+	remount grpjquota=q.g,jqfmt=vfsv0 grpjquota= ^grpjquota=
+	remount usrjquota=q.u,jqfmt=vfsv0 usrjquota= ^usrjquota=
+	remount grpjquota=q.g,usrjquota=q.u,jqfmt=vfsv0 grpjquota=,usrjquota= ^grpjquota=,^usrjquota=
+
+	remount jqfmt=vfsv0 grpjquota=q.g
+	remount jqfmt=vfsv0 usrjquota=q.u
+
+	if [[ $fstype != "ext2" ]]; then
+		remount noload data=journal norecovery
+		not_remount data=ordered data=journal
+		not_remount data=journal data=writeback
+		not_remount data=writeback data=ordered
+	fi
+
+	do_mkfs -O journal_dev $LOOP_LOGDEV ${LOGSIZE}k
+	do_mkfs -J device=$LOOP_LOGDEV $SCRATCH_DEV ${SIZE}k
+	mnt defaults
+	mnt journal_path=$LOOP_LOGDEV ignored
+	mnt journal_dev=$LOGDEV_DEVNUM ignored
+	not_mnt journal_path=${LOOP_LOGDEV}_nonexistent ignored
+	not_mnt journal_dev=123456 ignored
+	not_mnt journal_dev=999999999999999 ignored
+
+	do_mkfs -E quotatype=prjquota $SCRATCH_DEV ${SIZE}k
+	mnt prjquota
+
+	# test clearing/changing journalled quota when enabled
+	echo "== Testing active journalled quota" >> $seqres.full
+	_mnt prjquota,grpjquota=aquota.group,usrjquota=aquota.user,jqfmt=vfsv0
+
+	# Prepare and enable quota
+	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
+	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
+
+	_not_remount -r grpjquota=
+	_not_remount -r usrjquota=aaquota.user
+	_not_remount -r grpjquota=aaquota.group
+	_not_remount -r jqfmt=vfsv1
+	_not_remount -r noquota
+	_mnt remount,usrquota,grpquota ^usrquota,^grpquota
+	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+
+	# test clearing/changing quota when enabled
+	do_mkfs -E quotatype=^prjquota $SCRATCH_DEV ${SIZE}k
+	not_mnt prjquota
+	echo "== Testing active non-journalled quota" >> $seqres.full
+	_mnt grpquota,usrquota
+
+	# Prepare and enable quota
+	quotacheck -vugm $SCRATCH_MNT >> $seqres.full 2>&1
+	quotaon -vug $SCRATCH_MNT >> $seqres.full 2>&1
+
+	_not_remount -r noquota
+	_not_remount -r usrjquota=aquota.user
+	_not_remount -r grpjquota=aquota.group
+	_not_remount -r jqfmt=vfsv1
+	_mnt remount,grpjquota= grpquota,^grpjquota
+	_mnt remount,usrjquota= usrquota,^usrjquota
+	_mnt remount,usrquota,grpquota usrquota,grpquota
+	quotaoff -f $SCRATCH_MNT >> $seqres.full 2>&1
+	_mnt remount,noquota ^usrquota,^grpquota,quota
+	$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+
+	# Quota feature
+	echo "== Testing quota feature " >> $seqres.full
+	do_mkfs -O quota -E quotatype=prjquota $SCRATCH_DEV ${SIZE}k
+	mnt usrjquota=aquota.user,jqfmt=vfsv0 ^usrjquota=
+	mnt grpjquota=aquota.user,jqfmt=vfsv0 ^grpjquota=
+	mnt jqfmt=vfsv1 ^jqfmt=
+	mnt prjquota
+	mnt usrquota
+	mnt grpquota
+	not_remount defaults usrjquota=aquota.user
+	not_remount defaults grpjquota=aquota.user
+	not_remount defaults jqfmt=vfsv1
+	remount defaults grpjquota=,usrjquota= ignored
+
+done #for fstype in ext2 ext3 ext4; do
+
+$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
+echo "$ERR errors encountered" >> $seqres.full
+
+status=$ERR
+exit
diff --git a/tests/ext4/002.out b/tests/ext4/002.out
new file mode 100644
index 00000000..c1642bfd
--- /dev/null
+++ b/tests/ext4/002.out
@@ -0,0 +1,2 @@
+QA output created by 002
+Silence is golden.
diff --git a/tests/ext4/group b/tests/ext4/group
index a1adc553..b0aa781a 100644
--- a/tests/ext4/group
+++ b/tests/ext4/group
@@ -4,6 +4,7 @@
 # - comment line before each group is "new" description
 #
 001 auto prealloc quick zero
+002 auto mount
 003 auto quick
 004 auto dump
 005 auto quick metadata ioctl rw
-- 
2.21.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-05-18  8:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-22 15:20 [PATCH] ext4: ext4 mount sanity test Lukas Czerner
2020-04-22 17:42 ` Ira Weiny
2020-04-22 19:39   ` Lukas Czerner
2020-04-23 11:18 ` [PATCH v2] " Lukas Czerner
2020-04-27  9:48   ` Zorro Lang
2020-04-27 10:57     ` Lukas Czerner
2020-04-27 14:25       ` Lukas Czerner
2020-05-17 15:02   ` Eryu Guan
2020-05-18  7:15     ` Lukas Czerner
2020-05-18  8:52   ` [PATCH v3] " Lukas Czerner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.