TL;DR: Two disks in raid1 using btrfs. Checksums are only verified for the disk from which the file data was read. How to force verifying all checksums occasionally, e.g. in a weekly cron?
I have a btrfs on 2 disks in raid1 (/dev/sd{b,c}1
). To test error correction, I wrote a file to disk, looked up in which sector it was stored, and changed a single bit by writing directly to /dev/sdc1
. Since I mounted /dev/sdb1
, I figured writing to /dev/sdc1
would be a good test to see whether it replicated at all, and whether it would detect the change.
When reading the file, no errors occurred and the changed bit was still present in sdc1
(it was not present in sdb1
). It took until unmounting sdb1
and mounting sdc1
instead, then reading the file, for the error to be corrected.
How can I regularly verify checksums (for example weekly, using cron) on both disks without having to unmount?
If you want to replicate the situation, this is what I did:
$ mount /dev/sdb1 /mnt && cd /mnt
$ yes | head -100 > yes
$ filefrag -e yes # Look up in which sector the file is stored
$ echo x | dd of=/dev/sdc seek=$((offset*4096)) bs=1 count=1 # offset*sector_size
$ grep x yes # no results, no errors
$ dmesg | tail # nothing relevant
$ dd if=/dev/sdc skip=$((offset*4096)) bs=1 count=10 # To verify the x is actually there, and it is
$ # Mount sdc1 instead of sdb1
$ cd .. && umount mnt && mount /dev/sdc1 mnt
$ grep x yes # no results, no errors
$ dmesg | tail
[3695509.439534] BTRFS warning (device sdc1): csum failed ino 466 off 469331968 csum 444003100 expected csum 3637724482
[3695509.555018] BTRFS warning (device sdc1): csum failed ino 466 off 469331968 csum 444003100 expected csum 3637724482
[3695509.590762] BTRFS info (device sdc1): read error corrected: ino 466 off 469331968 (dev /dev/sdc1 sector 3692728)
# Finally, it was detected and silently corrected
I'm on kernel version 4.9.