diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index c191ea58750f7c28333489554e76e9c79466ac09..74d47e197ca08455a91ffd9cc2fbb27183c60a09 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) */ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, u64 length, u64 logical, struct page *page, - int mirror_num) + unsigned int pg_offset, int mirror_num) { struct bio *bio; struct btrfs_device *dev; @@ -2036,7 +2036,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, return -EIO; } bio->bi_bdev = dev->bdev; - bio_add_page(bio, page, length, start - page_offset(page)); + bio_add_page(bio, page, length, pg_offset); if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) { /* try to remap that extent elsewhere? */ @@ -2067,7 +2067,8 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, for (i = 0; i < num_pages; i++) { struct page *p = extent_buffer_page(eb, i); ret = repair_io_failure(root->fs_info, start, PAGE_CACHE_SIZE, - start, p, mirror_num); + start, p, start - page_offset(p), + mirror_num); if (ret) break; start += PAGE_CACHE_SIZE; @@ -2127,6 +2128,7 @@ static int clean_io_failure(u64 start, struct page *page) if (num_copies > 1) { repair_io_failure(fs_info, start, failrec->len, failrec->logical, page, + start - page_offset(page), failrec->failed_mirror); } } diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 75b621b7cd9fa67f9b32d158472edc820c00114b..a82ecbc2b84264a439bc7f4851e8ced9cfabc7f7 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -340,7 +340,7 @@ struct btrfs_fs_info; int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, u64 length, u64 logical, struct page *page, - int mirror_num); + unsigned int pg_offset, int mirror_num); int end_extent_writepage(struct page *page, int err, u64 start, u64 end); int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, int mirror_num); diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 9d80e37044dbb36f73e3ad0d98465b530db0338c..c026fa6b9553df61da4c3f375eae8e0d5772eca5 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) fs_info = BTRFS_I(inode)->root->fs_info; ret = repair_io_failure(fs_info, offset, PAGE_SIZE, fixup->logical, page, + offset - page_offset(page), fixup->mirror_num); unlock_page(page); corrected = !ret;