aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-09-12 06:44:00 -0400
committerChris Mason <clm@fb.com>2014-09-17 16:38:58 -0400
commitffdd2018dd0bbfc0d9855ed811dba67201766a2d (patch)
tree2a1784606d21d72d54abd3baa04f2c8a1131a4a1 /fs/btrfs
parent2fe6303e7cd099334cdb09370cece6bc168de131 (diff)
Btrfs: modify repair_io_failure and make it suit direct io
The original code of repair_io_failure was just used for buffered read, because it got some filesystem data from page structure, it is safe for the page in the page cache. But when we do a direct read, the pages in bio are not in the page cache, that is there is no filesystem data in the page structure. In order to implement direct read data repair, we need modify repair_io_failure and pass all filesystem data it need by function parameters. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/extent_io.c8
-rw-r--r--fs/btrfs/extent_io.h2
-rw-r--r--fs/btrfs/scrub.c1
3 files changed, 7 insertions, 4 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index c191ea58750f..74d47e197ca0 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1997,7 +1997,7 @@ static int free_io_failure(struct inode *inode, struct io_failure_record *rec)
1997 */ 1997 */
1998int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, 1998int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
1999 u64 length, u64 logical, struct page *page, 1999 u64 length, u64 logical, struct page *page,
2000 int mirror_num) 2000 unsigned int pg_offset, int mirror_num)
2001{ 2001{
2002 struct bio *bio; 2002 struct bio *bio;
2003 struct btrfs_device *dev; 2003 struct btrfs_device *dev;
@@ -2036,7 +2036,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
2036 return -EIO; 2036 return -EIO;
2037 } 2037 }
2038 bio->bi_bdev = dev->bdev; 2038 bio->bi_bdev = dev->bdev;
2039 bio_add_page(bio, page, length, start - page_offset(page)); 2039 bio_add_page(bio, page, length, pg_offset);
2040 2040
2041 if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) { 2041 if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) {
2042 /* try to remap that extent elsewhere? */ 2042 /* try to remap that extent elsewhere? */
@@ -2067,7 +2067,8 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
2067 for (i = 0; i < num_pages; i++) { 2067 for (i = 0; i < num_pages; i++) {
2068 struct page *p = extent_buffer_page(eb, i); 2068 struct page *p = extent_buffer_page(eb, i);
2069 ret = repair_io_failure(root->fs_info, start, PAGE_CACHE_SIZE, 2069 ret = repair_io_failure(root->fs_info, start, PAGE_CACHE_SIZE,
2070 start, p, mirror_num); 2070 start, p, start - page_offset(p),
2071 mirror_num);
2071 if (ret) 2072 if (ret)
2072 break; 2073 break;
2073 start += PAGE_CACHE_SIZE; 2074 start += PAGE_CACHE_SIZE;
@@ -2127,6 +2128,7 @@ static int clean_io_failure(u64 start, struct page *page)
2127 if (num_copies > 1) { 2128 if (num_copies > 1) {
2128 repair_io_failure(fs_info, start, failrec->len, 2129 repair_io_failure(fs_info, start, failrec->len,
2129 failrec->logical, page, 2130 failrec->logical, page,
2131 start - page_offset(page),
2130 failrec->failed_mirror); 2132 failrec->failed_mirror);
2131 } 2133 }
2132 } 2134 }
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 75b621b7cd9f..a82ecbc2b842 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -340,7 +340,7 @@ struct btrfs_fs_info;
340 340
341int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, 341int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
342 u64 length, u64 logical, struct page *page, 342 u64 length, u64 logical, struct page *page,
343 int mirror_num); 343 unsigned int pg_offset, int mirror_num);
344int end_extent_writepage(struct page *page, int err, u64 start, u64 end); 344int end_extent_writepage(struct page *page, int err, u64 start, u64 end);
345int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, 345int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
346 int mirror_num); 346 int mirror_num);
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 9d80e37044db..c026fa6b9553 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -682,6 +682,7 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx)
682 fs_info = BTRFS_I(inode)->root->fs_info; 682 fs_info = BTRFS_I(inode)->root->fs_info;
683 ret = repair_io_failure(fs_info, offset, PAGE_SIZE, 683 ret = repair_io_failure(fs_info, offset, PAGE_SIZE,
684 fixup->logical, page, 684 fixup->logical, page,
685 offset - page_offset(page),
685 fixup->mirror_num); 686 fixup->mirror_num);
686 unlock_page(page); 687 unlock_page(page);
687 corrected = !ret; 688 corrected = !ret;