#! /bin/bash
-# FS QA Test 260
-#
-# When default quota is set, all different quota types inherits the
-# same default value, include group quota. So if a user quota limit
-# larger than the default user quota value, it will still be limited
-# by the group default quota value.
-#
-# There's a patch from Upstream can fix this bug:
-#
-# [PATCH] xfs: Split default quota limits by quota type V4
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2017 Red Hat Inc. All Rights Reserved.
#
-#-----------------------------------------------------------------------
-# Copyright (c) 2016 Red Hat, Inc. All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it would be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# FS QA Test 260
#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#-----------------------------------------------------------------------
+# Test per-inode DAX flag by mmap direct/buffered IO.
#
-
seq=`basename $0`
seqres=$RESULT_DIR/$seq
echo "QA output created by $seq"
# get standard environment, filters and checks
. ./common/rc
. ./common/filter
-. ./common/quota
# remove previous $seqres.full before test
rm -f $seqres.full
-# real QA test starts here
_supported_fs xfs
_supported_os Linux
-_require_scratch
-_require_quota
-_require_user
-_require_group
+_require_scratch_dax_mountopt "dax"
+_require_test_program "feature"
+_require_test_program "t_mmap_dio"
+_require_dax_iflag
+_require_xfs_io_command "falloc"
+
+prep_files()
+{
+ rm -f $SCRATCH_MNT/tf_{s,d}
+
+ $XFS_IO_PROG -f -c "falloc 0 $tsize" \
+ $SCRATCH_MNT/tf_{s,d} >> $seqres.full 2>&1
+}
+
+t_both_dax()
+{
+ prep_files
+ $XFS_IO_PROG -c "chattr +x" $SCRATCH_MNT/tf_{s,d}
+ # with O_DIRECT first
+ $here/src/t_mmap_dio $SCRATCH_MNT/tf_{s,d} $1 "dio both dax"
+
+ prep_files
+ $XFS_IO_PROG -c "chattr +x" $SCRATCH_MNT/tf_{s,d}
+ # again with buffered IO
+ $here/src/t_mmap_dio -b $SCRATCH_MNT/tf_{s,d} \
+ $1 "buffered both dax"
+}
+
+t_nondax_to_dax()
+{
+ prep_files
+ $XFS_IO_PROG -c "chattr -x" $SCRATCH_MNT/tf_s
+ $XFS_IO_PROG -c "chattr +x" $SCRATCH_MNT/tf_d
+ $here/src/t_mmap_dio $SCRATCH_MNT/tf_{s,d} \
+ $1 "dio nondax to dax"
+
+ prep_files
+ $XFS_IO_PROG -c "chattr -x" $SCRATCH_MNT/tf_s
+ $XFS_IO_PROG -c "chattr +x" $SCRATCH_MNT/tf_d
+ $here/src/t_mmap_dio -b $SCRATCH_MNT/tf_{s,d} \
+ $1 "buffered nondax to dax"
+}
+
+t_dax_to_nondax()
+{
+ prep_files
+ $XFS_IO_PROG -c "chattr +x" $SCRATCH_MNT/tf_s
+ $XFS_IO_PROG -c "chattr -x" $SCRATCH_MNT/tf_d
+ $here/src/t_mmap_dio $SCRATCH_MNT/tf_{s,d} \
+ $1 "dio dax to nondax"
+
+ prep_files
+ $XFS_IO_PROG -c "chattr +x" $SCRATCH_MNT/tf_s
+ $XFS_IO_PROG -c "chattr -x" $SCRATCH_MNT/tf_d
+ $here/src/t_mmap_dio -b $SCRATCH_MNT/tf_{s,d} \
+ $1 "buffered dax to nondax"
+}
-do_test()
+t_both_nondax()
{
- local qname=$1
- local type
-
- if [ "$qname" = "user" ];then
- type="-u"
- echo "=== user quota test ==="
- elif [ "$qname" = "group" ];then
- type="-g"
- echo "=== group quota test ==="
- else
- echo "wrong quota type name - $qname"
- return 1
- fi
-
- $XFS_QUOTA_PROG -x -c "limit bsoft=20M bhard=20M isoft=20 ihard=20 $type -d" $SCRATCH_MNT
- $XFS_QUOTA_PROG -x -c "limit bsoft=40M bhard=40M isoft=40 ihard=40 $type fsgqa" $SCRATCH_MNT
- echo "$qname blocks and inode limit"
- $XFS_QUOTA_PROG -x -c "report $type -N -bi" $SCRATCH_MNT | _filter_spaces
-
- ## blocks default quota test ##
- _user_do "$XFS_IO_PROG -f -c \"pwrite 0 30M\" -c \"fsync\" $SCRATCH_MNT/data" | _filter_xfs_io
- echo "$qname blocks quota after write 30M data"
- $XFS_QUOTA_PROG -x -c "report $type -N -b" $SCRATCH_MNT | _filter_spaces
-
- rm -f ${SCRATCH_MNT}/* >/dev/null 2>&1
-
- ## inode default quota test ##
- for ((i=0; i<30; i++));do
- _user_do "echo -n > ${SCRATCH_MNT}/file${i}"
- done
- sync
-
- echo "$qname inode quota after create 300 inodes"
- $XFS_QUOTA_PROG -x -c "report $type -N -i" $SCRATCH_MNT | _filter_spaces
-
- rm -f ${SCRATCH_MNT}/* >/dev/null 2>&1
+ prep_files
+ $XFS_IO_PROG -c "chattr -x" $SCRATCH_MNT/tf_{s,d}
+ $here/src/t_mmap_dio $SCRATCH_MNT/tf_{s,d} \
+ $1 "dio both nondax"
+
+ prep_files
+ $XFS_IO_PROG -c "chattr -x" $SCRATCH_MNT/tf_{s,d}
+ $here/src/t_mmap_dio -b $SCRATCH_MNT/tf_{s,d} \
+ $1 "buffered both nondax"
}
-### user default quota test ###
-_scratch_mkfs_xfs >/dev/null 2>&1
-_qmount_option "uquota,gquota"
-_qmount
+# $1 mmap read/write size
+t_dax_flag_mmap_dio()
+{
+ t_both_dax $1
+ t_dax_to_nondax $1
+ t_nondax_to_dax $1
+ t_both_nondax $1
+}
+
+do_tests()
+{
+ # less than page size
+ t_dax_flag_mmap_dio 1024
+ # page size
+ t_dax_flag_mmap_dio `$here/src/feature -s`
+ # bigger sizes, for PMD faults
+ t_dax_flag_mmap_dio $((16 * 1024 * 1024))
+ t_dax_flag_mmap_dio $((64 * 1024 * 1024))
+}
+
+# make xfs aligned for PMD fault testing
+_scratch_mkfs_geom $(_get_hugepagesize) 1 >> $seqres.full 2>&1
+
+# mount with dax option
+_scratch_mount "-o dax"
-do_test user
+tsize=$((128 * 1024 * 1024))
-### group default quota test ###
+do_tests
_scratch_unmount
-_scratch_mkfs_xfs >/dev/null 2>&1
-_qmount_option "gquota,uquota"
-_qmount
-do_test group
+# mount again without dax option
+export MOUNT_OPTIONS=""
+_scratch_mount
+do_tests
# success, all done
+echo "Silence is golden"
status=0
exit