#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2017 Oracle, Inc.  All Rights Reserved.
#
# FS QA Test No. 801
#
# Force-enable THPs/large folios in tmpfs, then race fsstress and xfs_scrub in
# force-repair mode for a while to see if we crash, livelock, or corrupt data
# because the xfile code wasn't folioized.
#
. ./common/preamble
_begin_fstest online_repair fsstress_online_repair

declare -A oldvalues

_cleanup() {
	cd /
	for knob in "${!oldvalues[@]}"; do
		echo "${oldvalues["$knob"]}" > "$knob"
	done

	_scratch_xfs_stress_scrub_cleanup &> /dev/null
	rm -r -f $tmp.*
}
_register_cleanup "_cleanup" BUS

. ./common/filter
. ./common/fuzzy
. ./common/inject
. ./common/xfs

_require_scratch
_require_xfs_stress_online_repair

_fixed_by_git_commit kernel 099d90642a711 \
	"mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray"

# Make sure that the xfile code can handle large folios
knob="/sys/kernel/mm/transparent_hugepage/shmem_enabled"
test -w "$knob" || _notrun "tmpfs transparent hugepages disabled"

pagesize=`getconf PAGE_SIZE`
pagesize_kb=$((pagesize / 1024))

sysfs-dump() {
	for i in "$@"; do
		if [ -d "$i" ]; then
			for x in "$i/"*; do
				test -f "$x" && echo "$x: $(cat "$x")"
			done
		else
			test -f "$i" && echo "$i: $(cat "$i")"
		fi
	done
}

echo "settings now: pagesize=${pagesize_kb}KB" >> $seqres.full
sysfs-dump /sys/kernel/mm/transparent_hugepage/* >> $seqres.full

# Enable large folios for each of the relevant page sizes.
for ((i = 0; i <= 31; i++)); do
	hugepagesize_kb=$(( pagesize_kb * (2**i) ))
	knob="/sys/kernel/mm/transparent_hugepage/hugepages-${hugepagesize_kb}kB/enabled"
	test -e "$knob" || continue

	echo "setting $knob to inherit" >> $seqres.full
	oldvalue="$(sed -e 's/^.*\[//g' -e 's/\].*$//g' < "$knob")"
	oldvalues["$knob"]="$oldvalue"
	echo inherit > "$knob"
done

# Turn on large folios
knob="/sys/kernel/mm/transparent_hugepage/shmem_enabled"
echo "setting $knob to force" >> $seqres.full
oldvalues["$knob"]="$(sed -e 's/^.*\[//g' -e 's/\].*$//g' < "$knob")"
echo force > "$knob" || _fail "could not force tmpfs transparent hugepages"

echo "settings now" >> $seqres.full
sysfs-dump /sys/kernel/mm/transparent_hugepage/* >> $seqres.full

_scratch_mkfs >> "$seqres.full" 2>&1
_scratch_mount
_scratch_xfs_stress_online_repair -S '-k'

# success, all done
echo Silence is golden
status=0
exit
