#!/bin/bash
# Scan an ext filesystem and print all files that have blocks marked as bad.
#
# The filsystem must have been previously scanned with fsck -c (scan for bad blocks and mark them)
#
# Argument needed: partition name
#
# Found on https://unix.stackexchange.com/a/37243

if [ $# -lt 1 ] ; then
	echo "Usage: $0 partition_name"
	exit 1
fi

echo "This script may take a long time to execute on large filesystems"

DEVNAME="$1"
[ -b "$DEVNAME" ] || exit 1
echo "Analyzing device $DEVNAME"

BADBLOCKS="$(dumpe2fs -b "$DEVNAME" | tr '\n' ' ')"
[ -n "$BADBLOCKS" ] || exit 0
echo "Bad blocks found: $BADBLOCKS"

# Equivalent but slower: tail -n +2 | awk '{ print $2 }' | sort -u | tr '\n' ' '
FILTER='NR >= 2 { uniq[$2] = "" } END { for (inode in uniq) printf inode OFS }'
INODES="$(debugfs -R "icheck $BADBLOCKS" "$DEVNAME" | awk "$FILTER")"
[ -n "$INODES" ] || exit 0
echo "Inodes affected by bad blocks: $INODES"

echo "Printing files affected by bad blocks..."
debugfs -R "ncheck -c $INODES" "$DEVNAME"

echo "Done."
