Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test March 26 #1

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 50 additions & 31 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2010,10 +2010,6 @@ int repair_io_failure(struct btrfs_inode *inode, u64 start, u64 length,
ASSERT(!(fs_info->sb->s_flags & MS_RDONLY));
BUG_ON(!mirror_num);

/* we can't repair anything in raid56 yet */
if (btrfs_is_parity_mirror(map_tree, logical, length, mirror_num))
return 0;

bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
if (!bio)
return -EIO;
Expand All @@ -2026,17 +2022,30 @@ int repair_io_failure(struct btrfs_inode *inode, u64 start, u64 length,
* read repair operation.
*/
btrfs_bio_counter_inc_blocked(fs_info);
ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, logical,
&map_length, &bbio, mirror_num);
if (ret) {
btrfs_bio_counter_dec(fs_info);
bio_put(bio);
return -EIO;
if (btrfs_is_parity_mirror(map_tree, logical, length, mirror_num)) {
/* use BTRFS_MAP_READ to get the phy dev and sector */
ret = btrfs_map_block(fs_info, BTRFS_MAP_READ, logical,
&map_length, &bbio, 0);
if (ret) {
btrfs_bio_counter_dec(fs_info);
bio_put(bio);
return -EIO;
}
ASSERT(bbio->mirror_num == 1);
} else {
ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, logical,
&map_length, &bbio, mirror_num);
if (ret) {
btrfs_bio_counter_dec(fs_info);
bio_put(bio);
return -EIO;
}
BUG_ON(mirror_num != bbio->mirror_num);
}
BUG_ON(mirror_num != bbio->mirror_num);
sector = bbio->stripes[mirror_num-1].physical >> 9;

sector = bbio->stripes[bbio->mirror_num - 1].physical >> 9;
bio->bi_iter.bi_sector = sector;
dev = bbio->stripes[mirror_num-1].dev;
dev = bbio->stripes[bbio->mirror_num - 1].dev;
btrfs_put_bbio(bbio);
if (!dev || !dev->bdev || !dev->writeable) {
btrfs_bio_counter_dec(fs_info);
Expand Down Expand Up @@ -2584,26 +2593,36 @@ static void end_bio_extent_readpage(struct bio *bio)

if (tree->ops) {
ret = tree->ops->readpage_io_failed_hook(page, mirror);
if (!ret && !bio->bi_error)
uptodate = 1;
} else {
if (ret == -EAGAIN) {
/*
* Data inode's readpage_io_failed_hook() always
* returns -EAGAIN.
*
* The generic bio_readpage_error handles errors
* the following way: If possible, new read
* requests are created and submitted and will
* end up in end_bio_extent_readpage as well (if
* we're lucky, not in the !uptodate case). In
* that case it returns 0 and we just go on with
* the next page in our bio. If it can't handle
* the error it will return -EIO and we remain
* responsible for that page.
*/
ret = bio_readpage_error(bio, offset, page,
start, end, mirror);
if (ret == 0) {
uptodate = !bio->bi_error;
offset += len;
continue;
}
}

/*
* The generic bio_readpage_error handles errors the
* following way: If possible, new read requests are
* created and submitted and will end up in
* end_bio_extent_readpage as well (if we're lucky, not
* in the !uptodate case). In that case it returns 0 and
* we just go on with the next page in our bio. If it
* can't handle the error it will return -EIO and we
* remain responsible for that page.
* metadata's readpage_io_failed_hook() always returns
* -EIO and fixes nothing. -EIO is also returned if
* data inode error could not be fixed.
*/
ret = bio_readpage_error(bio, offset, page, start, end,
mirror);
if (ret == 0) {
uptodate = !bio->bi_error;
offset += len;
continue;
}
ASSERT(ret == -EIO);
}
readpage_ok:
if (likely(uptodate)) {
Expand Down
7 changes: 3 additions & 4 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -10522,10 +10522,9 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)

}

__attribute__((const))
static int dummy_readpage_io_failed_hook(struct page *page, int failed_mirror)
static int btrfs_readpage_io_failed_hook(struct page *page, int failed_mirror)
{
return 0;
return -EAGAIN;
}

static const struct inode_operations btrfs_dir_inode_operations = {
Expand Down Expand Up @@ -10570,7 +10569,7 @@ static const struct extent_io_ops btrfs_extent_io_ops = {
.submit_bio_hook = btrfs_submit_bio_hook,
.readpage_end_io_hook = btrfs_readpage_end_io_hook,
.merge_bio_hook = btrfs_merge_bio_hook,
.readpage_io_failed_hook = dummy_readpage_io_failed_hook,
.readpage_io_failed_hook = btrfs_readpage_io_failed_hook,

/* optional callbacks */
.fill_delalloc = run_delalloc_range,
Expand Down
8 changes: 6 additions & 2 deletions fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1497,14 +1497,18 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info,

bio_add_page(bio, page->page, PAGE_SIZE, 0);
if (!retry_failed_mirror && scrub_is_page_on_raid56(page)) {
if (scrub_submit_raid56_bio_wait(fs_info, bio, page))
if (scrub_submit_raid56_bio_wait(fs_info, bio, page)) {
page->io_error = 1;
sblock->no_io_error_seen = 0;
}
} else {
bio->bi_iter.bi_sector = page->physical >> 9;
bio_set_op_attrs(bio, REQ_OP_READ, 0);

if (btrfsic_submit_bio_wait(bio))
if (btrfsic_submit_bio_wait(bio)) {
page->io_error = 1;
sblock->no_io_error_seen = 0;
}
}

bio_put(bio);
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -6197,6 +6197,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
} else {
ret = raid56_parity_recover(fs_info, bio, bbio,
map_length, mirror_num, 1);
btrfs_io_bio(bio)->mirror_num = mirror_num;
}

btrfs_bio_counter_dec(fs_info);
Expand Down