diff --git a/common/fuzzy b/common/fuzzy
index 866901931e..ef42336fa6 100644
--- a/common/fuzzy
+++ b/common/fuzzy
@@ -194,6 +194,148 @@ __fuzz_notify() {
 	test -w /dev/ttyprintk && echo "$@" >> /dev/ttyprintk
 }
 
+# Perform the online repair part of a fuzz test.
+__scratch_xfs_fuzz_field_online() {
+	local fuzz_action="$1"
+
+	# Mount or else we can't do anything online
+	echo "+ Mount filesystem to try online repair"
+	_try_scratch_mount 2>&1
+	res=$?
+	if [ $res -ne 0 ]; then
+		(>&2 echo "mount failed ($res) with ${fuzz_action}.")
+		return 0
+	fi
+
+	# Make sure online scrub will catch whatever we fuzzed
+	echo "++ Online scrub"
+	_scratch_scrub -n -a 1 -e continue 2>&1
+	res=$?
+	test $res -eq 0 && \
+		(>&2 echo "scrub didn't fail with ${fuzz_action}.")
+
+	# Try fixing the filesystem online
+	__fuzz_notify "++ Try to repair filesystem online"
+	_scratch_scrub 2>&1
+	res=$?
+	test $res -ne 0 && \
+		(>&2 echo "online repair failed ($res) with ${fuzz_action}.")
+
+	__scratch_xfs_fuzz_unmount
+
+	# Offline scrub should pass now
+	echo "+ Make sure error is gone (offline)"
+	_scratch_xfs_repair -n 2>&1
+	res=$?
+	test $res -ne 0 && \
+		(>&2 echo "offline re-scrub failed ($res) with ${fuzz_action}.")
+
+	return 0
+}
+
+# Perform the offline repair part of a fuzz test.
+__scratch_xfs_fuzz_field_offline() {
+	local fuzz_action="$1"
+
+	# Mount or else we can't do anything offline
+	echo "+ Mount filesystem to try offline repair"
+	_try_scratch_mount 2>&1
+	res=$?
+	if [ $res -ne 0 ]; then
+		(>&2 echo "mount failed ($res) with ${fuzz_action}.")
+		return 0
+	fi
+
+	# Make sure online scrub will catch whatever we fuzzed
+	echo "++ Online scrub"
+	_scratch_scrub -n -a 1 -e continue 2>&1
+	res=$?
+	test $res -eq 0 && \
+		(>&2 echo "scrub didn't fail with ${fuzz_action}.")
+
+	__scratch_xfs_fuzz_unmount
+
+	# Repair the filesystem offline
+	echo "+ Try to repair the filesystem offline"
+	_repair_scratch_fs 2>&1
+	res=$?
+	test $res -ne 0 && \
+		(>&2 echo "offline repair failed ($res) with ${fuzz_action}.")
+
+	# See if repair finds a clean fs
+	echo "+ Make sure error is gone (offline)"
+	_scratch_xfs_repair -n 2>&1
+	res=$?
+	test $res -ne 0 && \
+		(>&2 echo "offline re-scrub failed ($res) with ${fuzz_action}.")
+
+	return 0
+}
+
+# Perform the no-repair part of a fuzz test.
+__scratch_xfs_fuzz_field_norepair() {
+	local fuzz_action="$1"
+
+	# Mount or else we can't do anything in norepair mode
+	echo "+ Mount filesystem to try no repair"
+	_try_scratch_mount 2>&1
+	res=$?
+	if [ $res -ne 0 ]; then
+		(>&2 echo "mount failed ($res) with ${fuzz_action}.")
+		return 0
+	fi
+
+	__scratch_xfs_fuzz_unmount
+
+	return 0
+}
+
+# Perform the online-then-offline repair part of a fuzz test.
+__scratch_xfs_fuzz_field_both() {
+	local fuzz_action="$1"
+
+	# Mount or else we can't do anything in both repair mode
+	echo "+ Mount filesystem to try both repairs"
+	_try_scratch_mount 2>&1
+	res=$?
+	if [ $res -ne 0 ]; then
+		(>&2 echo "mount failed ($res) with ${fuzz_action}.")
+		return 0
+	fi
+
+	# Make sure online scrub will catch whatever we fuzzed
+	echo "++ Online scrub"
+	_scratch_scrub -n -a 1 -e continue 2>&1
+	res=$?
+	test $res -eq 0 && \
+		(>&2 echo "online scrub didn't fail with ${fuzz_action}.")
+
+	# Try fixing the filesystem online
+	__fuzz_notify "++ Try to repair filesystem online"
+	_scratch_scrub 2>&1
+	res=$?
+	test $res -ne 0 && \
+		(>&2 echo "online repair failed ($res) with ${fuzz_action}.")
+
+	__scratch_xfs_fuzz_unmount
+
+	# Repair the filesystem offline?
+	echo "+ Try to repair the filesystem offline"
+	_repair_scratch_fs 2>&1
+	res=$?
+	test $res -ne 0 && \
+		(>&2 echo "offline repair failed ($res) with ${fuzz_action}.")
+
+	# See if repair finds a clean fs
+	echo "+ Make sure error is gone (offline)"
+	_scratch_xfs_repair -n 2>&1
+	res=$?
+	test $res -ne 0 && \
+		(>&2 echo "offline re-scrub ($res) with ${fuzz_action}.")
+
+	return 0
+}
+
 # Fuzz one field of some piece of metadata.
 # First arg is the field name
 # Second arg is the fuzz verb (ones, zeroes, random, add, sub...)
@@ -211,54 +353,32 @@ __scratch_xfs_fuzz_field_test() {
 	res=$?
 	test $res -ne 0 && return
 
-	# Try to catch the error with scrub
-	echo "+ Try to catch the error"
-	_try_scratch_mount 2>&1
-	res=$?
-	if [ $res -eq 0 ]; then
-		# Try an online scrub unless we're fuzzing ag 0's sb,
-		# which scrub doesn't know how to fix.
-		if [ "${repair}" != "none" ]; then
-			echo "++ Online scrub"
-			if [ "$1" != "sb 0" ]; then
-				_scratch_scrub -n -a 1 -e continue 2>&1
-				res=$?
-				test $res -eq 0 && \
-					(>&2 echo "scrub didn't fail with ${field} = ${fuzzverb}.")
-			fi
-		fi
-
-		# Try fixing the filesystem online?!
-		if [ "${repair}" = "online" ] || [ "${repair}" = "both" ]; then
-			__fuzz_notify "++ Try to repair filesystem online"
-			_scratch_scrub 2>&1
-			res=$?
-			test $res -ne 0 && \
-				(>&2 echo "online repair failed ($res) with ${field} = ${fuzzverb}.")
-		fi
-
-		__scratch_xfs_fuzz_unmount
-	elif [ "${repair}" = "online" ] || [ "${repair}" = "both" ]; then
-		(>&2 echo "mount failed ($res) with ${field} = ${fuzzverb}.")
-	fi
-
-	# Repair the filesystem offline?
-	if [ "${repair}" = "offline" ] || [ "${repair}" = "both" ]; then
-		echo "+ Try to repair the filesystem offline"
-		_repair_scratch_fs 2>&1
+	# Try to catch the error with whatever repair strategy we picked.
+	# The fs should not be mounted before or after the strategy call.
+	local fuzz_action="${field} = ${fuzzverb}"
+	case "${repair}" in
+	"online")
+		__scratch_xfs_fuzz_field_online "${fuzz_action}"
 		res=$?
-		test $res -ne 0 && \
-			(>&2 echo "offline repair failed ($res) with ${field} = ${fuzzverb}.")
-	fi
-
-	# See if repair finds a clean fs
-	if [ "${repair}" != "none" ]; then
-		echo "+ Make sure error is gone (offline)"
-		_scratch_xfs_repair -n 2>&1
+		;;
+	"offline")
+		__scratch_xfs_fuzz_field_offline "${fuzz_action}"
 		res=$?
-		test $res -ne 0 && \
-			(>&2 echo "offline re-scrub ($res) with ${field} = ${fuzzverb}.")
-	fi
+		;;
+	"none")
+		__scratch_xfs_fuzz_field_norepair "${fuzz_action}"
+		res=$?
+		;;
+	"both")
+		__scratch_xfs_fuzz_field_both "${fuzz_action}"
+		res=$?
+		;;
+	*)
+		(>&2 echo "unknown repair strategy ${repair}.")
+		res=2
+		;;
+	esac
+	test $res -eq 0 || return $res
 
 	# See if scrub finds a clean fs
 	echo "+ Make sure error is gone (online)"
