aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2017-03-29 13:53:58 -0400
committerDavid Sterba <dsterba@suse.com>2017-04-18 08:07:26 -0400
commitc725328c55443f150577efcf445a7924687342e4 (patch)
treee1f88a7d401224779bab91b9c82ca9723a1b564f
parent619a974292387343c817f5a36e9df6daeb3ccc60 (diff)
Btrfs: enable repair during read for raid56 profile
Now that scrub can fix data errors with the help of parity for raid56 profile, repair during read is able to as well. Although the mirror num in raid56 scenario has different meanings, i.e. 0 or 1: read data directly > 1: do recover with parity, it could be fit into how we repair bad block during read. The trick is to use BTRFS_MAP_READ instead of BTRFS_MAP_WRITE to get the device and position on it. Cc: David Sterba <dsterba@suse.cz> Tested-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/extent_io.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 77bd016ba18b..d8da3edf2ac3 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2009,10 +2009,6 @@ int repair_io_failure(struct btrfs_inode *inode, u64 start, u64 length,
2009 ASSERT(!(fs_info->sb->s_flags & MS_RDONLY)); 2009 ASSERT(!(fs_info->sb->s_flags & MS_RDONLY));
2010 BUG_ON(!mirror_num); 2010 BUG_ON(!mirror_num);
2011 2011
2012 /* we can't repair anything in raid56 yet */
2013 if (btrfs_is_parity_mirror(fs_info, logical, length, mirror_num))
2014 return 0;
2015
2016 bio = btrfs_io_bio_alloc(GFP_NOFS, 1); 2012 bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
2017 if (!bio) 2013 if (!bio)
2018 return -EIO; 2014 return -EIO;
@@ -2025,17 +2021,35 @@ int repair_io_failure(struct btrfs_inode *inode, u64 start, u64 length,
2025 * read repair operation. 2021 * read repair operation.
2026 */ 2022 */
2027 btrfs_bio_counter_inc_blocked(fs_info); 2023 btrfs_bio_counter_inc_blocked(fs_info);
2028 ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, logical, 2024 if (btrfs_is_parity_mirror(fs_info, logical, length, mirror_num)) {
2029 &map_length, &bbio, mirror_num); 2025 /*
2030 if (ret) { 2026 * Note that we don't use BTRFS_MAP_WRITE because it's supposed
2031 btrfs_bio_counter_dec(fs_info); 2027 * to update all raid stripes, but here we just want to correct
2032 bio_put(bio); 2028 * bad stripe, thus BTRFS_MAP_READ is abused to only get the bad
2033 return -EIO; 2029 * stripe's dev and sector.
2030 */
2031 ret = btrfs_map_block(fs_info, BTRFS_MAP_READ, logical,
2032 &map_length, &bbio, 0);
2033 if (ret) {
2034 btrfs_bio_counter_dec(fs_info);
2035 bio_put(bio);
2036 return -EIO;
2037 }
2038 ASSERT(bbio->mirror_num == 1);
2039 } else {
2040 ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, logical,
2041 &map_length, &bbio, mirror_num);
2042 if (ret) {
2043 btrfs_bio_counter_dec(fs_info);
2044 bio_put(bio);
2045 return -EIO;
2046 }
2047 BUG_ON(mirror_num != bbio->mirror_num);
2034 } 2048 }
2035 BUG_ON(mirror_num != bbio->mirror_num); 2049
2036 sector = bbio->stripes[mirror_num-1].physical >> 9; 2050 sector = bbio->stripes[bbio->mirror_num - 1].physical >> 9;
2037 bio->bi_iter.bi_sector = sector; 2051 bio->bi_iter.bi_sector = sector;
2038 dev = bbio->stripes[mirror_num-1].dev; 2052 dev = bbio->stripes[bbio->mirror_num - 1].dev;
2039 btrfs_put_bbio(bbio); 2053 btrfs_put_bbio(bbio);
2040 if (!dev || !dev->bdev || !dev->writeable) { 2054 if (!dev || !dev->bdev || !dev->writeable) {
2041 btrfs_bio_counter_dec(fs_info); 2055 btrfs_bio_counter_dec(fs_info);