I have an ext4 filesystem that recently developed some bad sectors. Running fsck.ext4 -c
finds and remembers the bad blocks. How can I find which files (if any) included these bad blocks so I can restore them from backups?
-
while I was interactively fixing it with fsck, it shown what files had problems; but, if there are too many, better is what @Nethox answered.– Aquarius PowerMay 8, 2015 at 22:57
1 Answer
With a combination of dumpe2fs
and debugfs
, which are included in the e2fsprogs
package along fsck.ext*
.
You must use the output of a command as the argument of the next one.
These tools auto-detect the filesystem block size, so it is consistent and safer than direct badblocks
invocation.
Prints the registered bad blocks of the filesystem:
# dumpe2fs -b DEVNAME
Prints the inodes which use the given block list:
# debugfs -R "icheck BLOCK ..." DEVNAME
Prints the pathnames to the given inode list:
# debugfs -R "ncheck INODE ..." DEVNAME
debugfs
has also an interactive shell and the -f cmd_file
option, but they are not much powerful or useful for this case.
The -R option allows more automated scripts like this:
#!/bin/sh
# Finds files affected by bad blocks on ext* filesystems.
# Valid only for ext* filesystems with bad blocks registered with
# fsck -c [-c] [-k] or -l|-L options.
# Can be extremely slow on damaged storage (not just a corrupt filesystem).
DEVNAME="$1"
[ -b "$DEVNAME" ] || exit 1
BADBLOCKS="$(dumpe2fs -b "$DEVNAME" | tr '\n' ' ')"
[ -n "$BADBLOCKS" ] || exit 0
INODES="$(debugfs -R "icheck $BADBLOCKS" "$DEVNAME" | awk -F'\t' '
NR > 1 { bad_inodes[$2]++; }
END {
for (inode in bad_inodes) {
if (inode == "<block not found>") {
printf("%d unallocated bad blocks\n", bad_inodes[inode]) > "/dev/stderr";
continue;
}
printf inode OFS;
}
}
')"
[ -n "$INODES" ] || exit 0
debugfs -R "ncheck -c $INODES" "$DEVNAME"
-
just to point out that debugfs, on a very large filesystem, may take a long time before showing something May 8, 2015 at 22:40