#!/bin/bash
# https://bugs.gentoo.org/641262

read -r -d '' HELP <<EOF
usage: ${0##*/} [-h] [--file-count COUNT] [--increment-count COUNT] [--tmpdir TMPDIR]

  ${0##*/} ${VERSION}
  Test for stale (removed) files in btrfs directory listings

optional arguments:
  --file-count COUNT
                    specify total number of files to create
  --increment-count COUNT
                    specify increment for the seq command
                    that conrols which files are removed
  --tmpdir TMPDIR   specify the parent temporary directory
EOF

# Results are extremely sensitive to the following variables:
FILE_COUNT=350
INCREMENT_COUNT=10

die() {
	echo "${@}" 1>&2
	exit 1
}

params=$(getopt -o "h" -l "file-count:,help,increment-count:,tmpdir:" --name "${0##*/}" -- "${@}") || exit $?
eval set -- "${params}"

while [[ ${#} -gt 0 ]]; do
	case ${1} in
		--file-count)
			FILE_COUNT=${2}
			shift
			;;
		--increment-count)
			INCREMENT_COUNT=${2}
			shift
			;;
		--tmpdir)
			export TMPDIR=${2}
			shift
			;;
		-h|--help) echo "${HELP}"; exit 0;;
		--) ;;
		*) die "Unexpected argument: ${1}";;
	esac
	shift
done

tempdir=$(mktemp -d)

trap 'rm -rf "${tempdir}"' EXIT

for x in $(seq 1 "${FILE_COUNT}"); do
	# write one \n to file, since empty files don't
	# appear to trigger the problem
	echo > "${tempdir}/${x}"
done

sync "${tempdir}"

for x in $(seq 1 "${INCREMENT_COUNT}" "${FILE_COUNT}"); do
	printf -- "%s/%s\0" "${tempdir}" "${x}"
done | xargs -0 rm

before_sync=$(ls -1 "${tempdir}")

sync "${tempdir}"

after_sync=$(ls -1 "${tempdir}")

if [[ ${before_sync} != ${after_sync} ]]; then
	diff -u <(printf -- "${after_sync}") <(printf -- "${before_sync}")
fi
