summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/scrub.c
diff options
context:
space:
mode:
authorLiu Bo2018-03-03 00:10:41 +0100
committerDavid Sterba2018-03-26 15:09:43 +0200
commit4759700a71ab109c67376360e9f00e2fed6b3807 (patch)
tree206e7dcaba8efee859c5c87ca952b7ee10fdbb1d /fs/btrfs/scrub.c
parentBtrfs: raid56: remove redundant async_missing_raid56 (diff)
downloadkernel-qcow2-linux-4759700a71ab109c67376360e9f00e2fed6b3807.tar.gz
kernel-qcow2-linux-4759700a71ab109c67376360e9f00e2fed6b3807.tar.xz
kernel-qcow2-linux-4759700a71ab109c67376360e9f00e2fed6b3807.zip
Btrfs: dev-replace: make sure target is identical to source when raid56 rebuild fails
In the last step of scrub_handle_error_block, we try to combine good copies on all possible mirrors, this works fine for raid1 and raid10, but not for raid56 as it's doing parity rebuild. If parity rebuild doesn't get back with correct data which matches its checksum, in case of replace we'd rather write what is stored in the source device than the data calculuated from parity. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/scrub.c')
-rw-r--r--fs/btrfs/scrub.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 9fb7d09842e6..f4c9b30903b0 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1412,8 +1412,17 @@ nodatasum_case:
if (!page_bad->io_error && !sctx->is_dev_replace)
continue;
- /* try to find no-io-error page in mirrors */
- if (page_bad->io_error) {
+ if (scrub_is_page_on_raid56(sblock_bad->pagev[0])) {
+ /*
+ * In case of dev replace, if raid56 rebuild process
+ * didn't work out correct data, then copy the content
+ * in sblock_bad to make sure target device is identical
+ * to source device, instead of writing garbage data in
+ * sblock_for_recheck array to target device.
+ */
+ sblock_other = NULL;
+ } else if (page_bad->io_error) {
+ /* try to find no-io-error page in mirrors */
for (mirror_index = 0;
mirror_index < BTRFS_MAX_MIRRORS &&
sblocks_for_recheck[mirror_index].page_count > 0;