Is it possible to explicitly retrieve full file contents with bad checksum on a btrfs filesystem

btrfschecksumdata-recovery

Imagine a situation when a file became corrupted on a single device Btrfs. And in this case file contents are needed as is including corrupted bits.

As stated in man page for mount:

nodatasum
              Enable/disable data checksumming for newly created files.

So it won't disable checksum checks when reading files.

And as I guess all standard system calls involving filesystem for reading will fail at this file. Raw disk read is not an option because of likely fragmentation.

When I try to cat such file, I get error:

cat: file: Input/output error

dmesg reports messages like these:

[631847.884641] BTRFS warning (device loop0): csum failed ino 257 off 0 csum 1280268577 expected csum 2391276770

Having information that corruption occurs at off 0, so this is first 4096 bytes of file, indeed I'm able to retrieve non-corrupted blocks pretty easily:

dd if=file bs=4K skip=1

Btw, writing and appending data to non-corrupted blocks of corrupted file also succeeds. At least when there is only one corrupted block and it's not the last. At first it surprised me, but then I think probably it's a good feature, so that applications that must append critical data won't stuck on a corrupted file.

The question is how do I retrive data from corrupted block (or entire corrupted file)?

Best Answer

As a last resort you can try

btrfs check --init-csum-tree /tmp/copy_of_the_device.bin

This command will change the filesystem and the result can be worse than before, so run this only on a dd or ddrescue copy of the filesystem.

Related Question