Skip to content

Instantly share code, notes, and snippets.

@Wolf480pl
Last active August 10, 2025 16:01
Show Gist options
  • Select an option

  • Save Wolf480pl/ee459bc8b09c0c9dac2eed1584b522db to your computer and use it in GitHub Desktop.

Select an option

Save Wolf480pl/ee459bc8b09c0c9dac2eed1584b522db to your computer and use it in GitHub Desktop.
Random scripts for figuring out which files you lost after ddrescue-ing a failing drive. You should not need this. You should have backups. Do as I say not as I do.
#!/bin/sh
## tail -n+9 sda.map | cut-map.sh <start-offset-in-bytes> <length-in-bytes> > sda3.map
##
## Takes a ddrescue mapfile for a block device
## (after you've cut off the header manually)
## and outputs a mapfile for a partition/subvolume
## of a specified length, starting at a specified offset.
## The byte offsets in the output are relative to the start of the partition.
##
## Note that offset and length are in bytes,
## so if you got yours from `fdisk -l` or `dmsetup table` or sth,
## you'll need to multiply them by whatever sector size these tools are using (usually 512 bytes).
offset=$1
length=$2
exec awk --non-decimal-data -v "off=$offset" -v "len=$length" '
{
start = $1 - off;
end = start + $2;
if ((end > 0) && (start < len)) {
if (start < 0) { start = 0; };
if (end > len) { end = len; };
printf("0x%08X 0x%08X %s\n", start, end - start, $3)
}
}'
#!/bin/sh
## e2fs-list-blocks-verbose.sh copy-of-sda3.img > sda3-metadata-blocks.txt
## grep -F -f <(cut -d' ' -f2 sda3-icheck.txt) sda3-metadata-blocks.txt
##
## Lists block numbers of all blocks used for ext4 metadata structures
## (superblock, group descriptors, free block bitmaps, inode table, etc)
## in hex, so that you can compare them with the output of map-to-icheck.sh
## to see if any of the damaged blocks belong to ext4 metadata.
dumpe2fs -g "$1" 2>/dev/null |tail -n+3 \
|awk -v "itblocks=512" -F ':' '{print $1 " block - " $2; if ($3 != "-1") { print $1 " super - " $3 }; if ($4 != "-1") { print $1 " gdt - " $4 }; print $1 " bbitmap - " $5; print $1 " ibitmap - " $6; itstart=$7; print $1 " itable - " itstart "-" (itstart + itblocks - 1)}' \
|awk -F- '($3 == ""){printf("0x%x %s\n", $2, $1)} ($3 != "") { for (i=$2; i <= $3; i+=1) { printf("0x%x %s\n", i, $1) }}' |sort
#!/bin/sh
## icheck-to-ncheck.sh sda3-icheck.out > sda3-ncheck.txt
## debugfs copy-of-sda3.img -f sda3-ncheck.txt > sda3-ncheck.out
##
## Takes output of debugfs(8)'s icheck commands, extracts inode numbers out of it,
## and generates a series of ncheck commands for debugfs(8)
## to find filesystem paths of those inodes.
##
## Combined with map-to-icheck.sh, this allows finding out which files are damaged.
grep -vE '^(debugfs: icheck|Block)' "$@" |grep -v 'not found' |awk '{print $2}' |sort -u |sed 's/^/ncheck /'
#!/bin/sh
## cat sda3.map | map-to-icheck.sh > sda3-icheck.txt
## debugfs copy-of-sda3.img -f sda3-icheck.txt > sda3-icheck.out
##
## Takes bad sector locations from a ddrescue mapfile
## and generates a series of icheck commands for debugfs(8)
## to check which inodes used the damaged sectors.
awk -v "fsblock=4096" --non-decimal-data '
($3 == "-") {
for (off = 0; off < $2; off += fsblock) {
printf("icheck 0x%x\n", ($1 + off) / fsblock);
}
}
' | uniq
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment