@@ -154,6 +154,12 @@ _scratch_xfs_dump_metadata() {
_scratch_xfs_db "${cmds[@]}" -c print
}
+# Decide from the output of the xfs_db "stack" command if the debugger's io
+# cursor is pointed at a block that is an unstructured data format (blob).
+__scratch_xfs_detect_blob_from_stack() {
+ grep -q -E 'inode.*, type (data|rtsummary|rtbitmap)'
+}
+
# Navigate to some part of the filesystem and print the field info.
# The first argument is an grep filter for the fields
# The rest of the arguments are xfs_db commands to locate the metadata.
@@ -169,7 +175,17 @@ _scratch_xfs_list_metadata_fields() {
for arg in "$@"; do
cmds+=("-c" "${arg}")
done
- _scratch_xfs_db "${cmds[@]}" -c print | __filter_xfs_db_print_fields "${filter}"
+
+ # Does the path argument point towards something that is an
+ # unstructured blob?
+ if _scratch_xfs_db "${cmds[@]}" -c stack 2>/dev/null | \
+ __scratch_xfs_detect_blob_from_stack; then
+ echo "<blob>"
+ return
+ fi
+
+ _scratch_xfs_db "${cmds[@]}" -c print | \
+ __filter_xfs_db_print_fields "${filter}"
}
# Fuzz a metadata field
@@ -207,6 +223,70 @@ _scratch_xfs_fuzz_metadata_field() {
return 0
}
+# List the fuzzing verbs available for unstructured blobs
+__scratch_xfs_list_blob_fuzz_verbs() {
+ cat << ENDL
+zeroes
+ones
+firstbit
+middlebit
+lastbit
+random
+ENDL
+}
+
+# Fuzz a metadata blob
+# The first arg is a blob fuzzing verb
+# The rest of the arguments are xfs_db commands to find the metadata.
+_scratch_xfs_fuzz_metadata_blob() {
+ local fuzzverb="$1"
+ shift
+ local trashcmd=(blocktrash -z)
+
+ local cmds=()
+ for arg in "$@"; do
+ cmds+=("-c" "${arg}")
+ done
+
+ local bytecount=$(_scratch_xfs_db "${cmds[@]}" -c "stack" | grep 'byte.*length' | awk '{print $5}')
+ local bitmax=$((bytecount * 8))
+
+ case "${fuzzverb}" in
+ "zeroes")
+ trashcmd+=(-0 -o 0 -x "${bitmax}" -y "${bitmax}");;
+ "ones")
+ trashcmd+=(-1 -o 0 -x "${bitmax}" -y "${bitmax}");;
+ "firstbit")
+ trashcmd+=(-2 -o 0 -x 1 -y 1);;
+ "middlebit")
+ trashcmd+=(-2 -o $((bitmax / 2)) -x 1 -y 1);;
+ "lastbit")
+ trashcmd+=(-2 -o "${bitmax}" -x 1 -y 1);;
+ "random")
+ trashcmd+=(-3 -o 0 -x "${bitmax}" -y "${bitmax}");;
+ *)
+ echo "Unknown blob fuzz verb \"${fuzzverb}\"."
+ return 1
+ ;;
+ esac
+
+ trashcmd="${trashcmd[@]}"
+ oldval="$(_scratch_xfs_get_metadata_field "" "$@")"
+ while true; do
+ _scratch_xfs_db -x "${cmds[@]}" -c "${trashcmd}"
+ echo
+ newval="$(_scratch_xfs_get_metadata_field "" "$@" 2> /dev/null)"
+ if [ "${fuzzverb}" != "random" ] || [ "${oldval}" != "${newval}" ]; then
+ break;
+ fi
+ done
+ if [ "${oldval}" = "${newval}" ]; then
+ echo "Blob already set to new value, skipping test."
+ return 1
+ fi
+ return 0
+}
+
# Try to forcibly unmount the scratch fs
__scratch_xfs_fuzz_unmount()
{
@@ -503,7 +583,11 @@ __scratch_xfs_fuzz_field_test() {
# Set the new field value
__fuzz_notify "+ Fuzz ${field} = ${fuzzverb}"
- _scratch_xfs_fuzz_metadata_field "${field}" ${fuzzverb} "$@"
+ if [ "$field" = "<blob>" ]; then
+ _scratch_xfs_fuzz_metadata_blob ${fuzzverb} "$@"
+ else
+ _scratch_xfs_fuzz_metadata_field "${field}" ${fuzzverb} "$@"
+ fi
res=$?
test $res -ne 0 && return
@@ -587,7 +671,22 @@ _scratch_xfs_list_fuzz_verbs() {
echo "${SCRATCH_XFS_LIST_FUZZ_VERBS}" | tr '[ ,]' '[\n\n]'
return;
fi
- _scratch_xfs_db -x -c 'sb 0' -c 'fuzz' | grep '^Fuzz commands:' | \
+
+ local cmds=()
+ for arg in "$@"; do
+ cmds+=("-c" "${arg}")
+ done
+ test "${#cmds[@]}" -eq 0 && cmds=('-c' 'sb 0')
+
+ # Does the path argument point towards something that is an
+ # unstructured blob?
+ if _scratch_xfs_db "${cmds[@]}" -c stack 2>/dev/null | \
+ __scratch_xfs_detect_blob_from_stack; then
+ __scratch_xfs_list_blob_fuzz_verbs
+ return
+ fi
+
+ _scratch_xfs_db -x "${cmds[@]}" -c 'fuzz' | grep '^Fuzz commands:' | \
sed -e 's/[,.]//g' -e 's/Fuzz commands: //g' -e 's/ /\n/g' | \
grep -v '^random$'
}
@@ -605,7 +704,7 @@ _scratch_xfs_fuzz_metadata() {
shift; shift
fields="$(_scratch_xfs_list_metadata_fields "${filter}" "$@")"
- verbs="$(_scratch_xfs_list_fuzz_verbs)"
+ verbs="$(_scratch_xfs_list_fuzz_verbs "$@")"
echo "Fields we propose to fuzz with the \"${repair}\" repair strategy: $@"
echo $(echo "${fields}")
echo "Verbs we propose to fuzz with:"
new file mode 100755
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1562
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.bitmap')
+else
+ path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1562
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
new file mode 100755
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1563
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.summary')
+else
+ path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1563
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
new file mode 100755
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1564
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.bitmap')
+else
+ path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1564
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
new file mode 100755
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1565
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.summary')
+else
+ path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1565
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
new file mode 100755
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1566
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.bitmap')
+else
+ path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1566
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
new file mode 100755
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1567
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.summary')
+else
+ path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1567
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
new file mode 100755
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1568
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.bitmap')
+else
+ path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1568
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
new file mode 100755
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1569
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+ path=('path -m /realtime/0.summary')
+else
+ path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1569
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary