Commit 1203b681 authored by Miao Xie's avatar Miao Xie Committed by Chris Mason

Btrfs: modify clean_io_failure and make it suit direct io

We could not use clean_io_failure in the direct IO path because it got the
filesystem information from the page structure, but the page in the direct
IO bio didn't have the filesystem information in its structure. So we need
modify it and pass all the information it need by parameters.
Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent ffdd2018
...@@ -1995,10 +1995,10 @@ static int free_io_failure(struct inode *inode, struct io_failure_record *rec) ...@@ -1995,10 +1995,10 @@ static int free_io_failure(struct inode *inode, struct io_failure_record *rec)
* currently, there can be no more than two copies of every data bit. thus, * currently, there can be no more than two copies of every data bit. thus,
* exactly one rewrite is required. * exactly one rewrite is required.
*/ */
int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, int repair_io_failure(struct inode *inode, u64 start, u64 length, u64 logical,
u64 length, u64 logical, struct page *page, struct page *page, unsigned int pg_offset, int mirror_num)
unsigned int pg_offset, int mirror_num)
{ {
struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
struct bio *bio; struct bio *bio;
struct btrfs_device *dev; struct btrfs_device *dev;
u64 map_length = 0; u64 map_length = 0;
...@@ -2046,10 +2046,9 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, ...@@ -2046,10 +2046,9 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
} }
printk_ratelimited_in_rcu(KERN_INFO printk_ratelimited_in_rcu(KERN_INFO
"BTRFS: read error corrected: ino %lu off %llu " "BTRFS: read error corrected: ino %llu off %llu (dev %s sector %llu)\n",
"(dev %s sector %llu)\n", page->mapping->host->i_ino, btrfs_ino(inode), start,
start, rcu_str_deref(dev->name), sector); rcu_str_deref(dev->name), sector);
bio_put(bio); bio_put(bio);
return 0; return 0;
} }
...@@ -2066,9 +2065,10 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, ...@@ -2066,9 +2065,10 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
for (i = 0; i < num_pages; i++) { for (i = 0; i < num_pages; i++) {
struct page *p = extent_buffer_page(eb, i); struct page *p = extent_buffer_page(eb, i);
ret = repair_io_failure(root->fs_info, start, PAGE_CACHE_SIZE,
start, p, start - page_offset(p), ret = repair_io_failure(root->fs_info->btree_inode, start,
mirror_num); PAGE_CACHE_SIZE, start, p,
start - page_offset(p), mirror_num);
if (ret) if (ret)
break; break;
start += PAGE_CACHE_SIZE; start += PAGE_CACHE_SIZE;
...@@ -2081,12 +2081,12 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, ...@@ -2081,12 +2081,12 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
* each time an IO finishes, we do a fast check in the IO failure tree * each time an IO finishes, we do a fast check in the IO failure tree
* to see if we need to process or clean up an io_failure_record * to see if we need to process or clean up an io_failure_record
*/ */
static int clean_io_failure(u64 start, struct page *page) static int clean_io_failure(struct inode *inode, u64 start,
struct page *page, unsigned int pg_offset)
{ {
u64 private; u64 private;
u64 private_failure; u64 private_failure;
struct io_failure_record *failrec; struct io_failure_record *failrec;
struct inode *inode = page->mapping->host;
struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
struct extent_state *state; struct extent_state *state;
int num_copies; int num_copies;
...@@ -2126,10 +2126,9 @@ static int clean_io_failure(u64 start, struct page *page) ...@@ -2126,10 +2126,9 @@ static int clean_io_failure(u64 start, struct page *page)
num_copies = btrfs_num_copies(fs_info, failrec->logical, num_copies = btrfs_num_copies(fs_info, failrec->logical,
failrec->len); failrec->len);
if (num_copies > 1) { if (num_copies > 1) {
repair_io_failure(fs_info, start, failrec->len, repair_io_failure(inode, start, failrec->len,
failrec->logical, page, failrec->logical, page,
start - page_offset(page), pg_offset, failrec->failed_mirror);
failrec->failed_mirror);
} }
} }
...@@ -2538,7 +2537,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err) ...@@ -2538,7 +2537,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
if (ret) if (ret)
uptodate = 0; uptodate = 0;
else else
clean_io_failure(start, page); clean_io_failure(inode, start, page, 0);
} }
if (likely(uptodate)) if (likely(uptodate))
......
...@@ -338,9 +338,9 @@ struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask); ...@@ -338,9 +338,9 @@ struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask);
struct btrfs_fs_info; struct btrfs_fs_info;
int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, int repair_io_failure(struct inode *inode, u64 start, u64 length, u64 logical,
u64 length, u64 logical, struct page *page, struct page *page, unsigned int pg_offset,
unsigned int pg_offset, int mirror_num); int mirror_num);
int end_extent_writepage(struct page *page, int err, u64 start, u64 end); 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 repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
int mirror_num); int mirror_num);
......
...@@ -679,8 +679,7 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx) ...@@ -679,8 +679,7 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx)
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
fs_info = BTRFS_I(inode)->root->fs_info; ret = repair_io_failure(inode, offset, PAGE_SIZE,
ret = repair_io_failure(fs_info, offset, PAGE_SIZE,
fixup->logical, page, fixup->logical, page,
offset - page_offset(page), offset - page_offset(page),
fixup->mirror_num); fixup->mirror_num);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment