• Qu Wenruo's avatar
    btrfs: scrub: also report errors hit during the initial read · 79b8ee70
    Qu Wenruo authored
    [BUG]
    After the recent scrub rework introduced in commit e02ee89b ("btrfs:
    scrub: switch scrub_simple_mirror() to scrub_stripe infrastructure"),
    btrfs scrub no longer reports repaired errors any more:
    
      # mkfs.btrfs -f $dev -d DUP
      # mount $dev $mnt
      # xfs_io -f -d -c "pwrite -b 64K -S 0xaa 0 64" $mnt/file
      # umount $dev
      # xfs_io -f -c "pwrite -S 0xff $phy1 64K" $dev # Corrupt the first mirror
      # mount $dev $mnt
      # btrfs scrub start -BR $mnt
      scrub done for 725e7cb7-8a4a-4c77-9f2a-86943619e218
      Scrub started:    Tue Jun  6 14:56:50 2023
      Status:           finished
      Duration:         0:00:00
      	data_extents_scrubbed: 2
      	tree_extents_scrubbed: 18
      	data_bytes_scrubbed: 131072
      	tree_bytes_scrubbed: 294912
      	read_errors: 0
      	csum_errors: 0 <<< No errors here
      	verify_errors: 0
             [...]
      	uncorrectable_errors: 0
      	unverified_errors: 0
      	corrected_errors: 16		<<< Only corrected errors
      	last_physical: 2723151872
    
    This can confuse btrfs-progs, as it relies on the csum_errors to
    determine if there is anything wrong.
    
    While on v6.3.x kernels, the report is different:
    
     	csum_errors: 16			<<<
     	verify_errors: 0
    	[...]
     	uncorrectable_errors: 0
     	unverified_errors: 0
     	corrected_errors: 16 <<<
    
    [CAUSE]
    In the reworked scrub, we update the scrub progress inside
    scrub_stripe_report_errors(), using various bitmaps to update the
    result.
    
    For example for csum_errors, we use bitmap_weight() of
    stripe->csum_error_bitmap.
    
    Unfortunately at that stage, all error bitmaps (except
    init_error_bitmap) are the result of the latest repair attempt, thus if
    the stripe is fully repaired, those error bitmaps will all be empty,
    resulting the above output mismatch.
    
    To fix this, record the number of errors into stripe->init_nr_*_errors.
    Since we don't really care about where those errors are, we only need to
    record the number of errors.
    
    Then in scrub_stripe_report_errors(), use those initial numbers to
    update the progress other than using the latest error bitmaps.
    
    Fixes: e02ee89b ("btrfs: scrub: switch scrub_simple_mirror() to scrub_stripe infrastructure")
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    79b8ee70
scrub.c 86.4 KB