#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2025 Oracle, Inc.  All Rights Reserved.
#
# FS QA Test No. 633
#
# Populate a XFS filesystem, ensure that rdump can "recover" the contents to
# another directory, and compare the contents.
#
. ./common/preamble
_begin_fstest auto scrub

_cleanup()
{
	_kill_fsstress
	cd /
	test -e "$testfiles" && rm -r -f $testfiles
}

_register_cleanup "_cleanup" BUS

# Import common functions.
. ./common/filter
. ./common/populate
. ./common/fuzzy

_require_xfs_db_command "rdump"
_require_test
_require_scratch
_require_scrub
_require_populate_commands

make_md5()
{
	(cd $1 ; find . -type f -print0 | xargs -0 md5sum) > $tmp.md5.$2
}

cmp_md5()
{
	(cd $1 ; md5sum --quiet -c $tmp.md5.$2)
}

make_stat()
{
	# columns:	raw mode in hex,
	# 		major rdev for special
	# 		minor rdev for special
	# 		uid of owner
	# 		gid of owner
	# 		file type
	# 		total size
	# 		mtime
	# 		name
	# We can't directly control directory sizes so filter them.
	# Too many things can bump (or not) atime so don't test that.
	(cd $1 ; find . -print0 |
		xargs -0 stat -c '%f %t:%T %u %g %F %s %Y %n' |
		sed -e 's/ directory [1-9][0-9]* / directory SIZE /g' |
		sort) > $tmp.stat.$2
}

cmp_stat()
{
	diff -u $tmp.stat.$1 $tmp.stat.$2
}

make_stat_files() {
	for file in "${FILES[@]}"; do
		find "$1/$file" -print0 | xargs -0 stat -c '%f %t:%T %u %g %F %s %Y %n'
	done | sed \
		-e 's/ directory [1-9][0-9]* / directory SIZE /g' \
		-e "s| $1| DUMPDIR|g" \
		| sort > $tmp.stat.files.$2
}

cmp_stat_files()
{
	diff -u $tmp.stat.files.$1 $tmp.stat.files.$2
}

make_stat_dir() {
	find "$1" -print0 | \
		xargs -0 stat -c '%f %t:%T %u %g %F %s %Y %n' | sed \
		-e 's/ directory [1-9][0-9]* / directory SIZE /g' \
		-e "s| $1| DUMPDIR|g" \
		| sort > $tmp.stat.dir.$2
}

cmp_stat_dir()
{
	diff -u $tmp.stat.dir.$1 $tmp.stat.dir.$2
}

FILES=(
	"/S_IFDIR.FMT_INLINE"
	"/S_IFBLK"
	"/S_IFCHR"
	"/S_IFLNK.FMT_LOCAL"
	"/S_IFIFO"
	"/S_IFDIR.FMT_INLINE/00000001"
	"/ATTR.FMT_EXTENTS_REMOTE3K"
	"/S_IFREG.FMT_EXTENTS"
	"/S_IFREG.FMT_BTREE"
	"/BNOBT"
	"/S_IFDIR.FMT_BLOCK"
)
DIR="/S_IFDIR.FMT_LEAF"

testfiles=$TEST_DIR/$seq
mkdir -p $testfiles

echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
_scratch_mount

_run_fsstress -n 500 -d $SCRATCH_MNT/newfiles

make_stat $SCRATCH_MNT before
make_md5 $SCRATCH_MNT before
make_stat_files $SCRATCH_MNT before
make_stat_dir $SCRATCH_MNT/$DIR before
_scratch_unmount

echo "Recover filesystem"
dumpdir1=$testfiles/rdump
dumpdir2=$testfiles/sdump
dumpdir3=$testfiles/tdump
rm -r -f $dumpdir1 $dumpdir2 $dumpdir3

# as of linux 6.12 fchownat does not work on symlinks
_scratch_xfs_db -c "rdump / $dumpdir1" | sed -e '/could not be set/d'
_scratch_xfs_db -c "rdump ${FILES[*]} $dumpdir2" | sed -e '/could not be set/d'
_scratch_xfs_db -c "rdump $DIR $dumpdir3" | sed -e '/could not be set/d'

echo "Check file contents"
make_stat $dumpdir1 after
cmp_stat before after
cmp_md5 $dumpdir1 before

echo "Check selected files contents"
make_stat_files $dumpdir2 after
cmp_stat_files before after

echo "Check single dir extraction contents"
make_stat_dir $dumpdir3 after
cmp_stat_dir before after

# remount so we can check this fs
_scratch_mount

# success, all done
status=0
exit
