Commit 97861cd1 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David Sterba

btrfs: refactor end_bio_extent_readpage code flow

Untangle the goto and move the code it jumps to so it goes in the order
of the most likely states first.
Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
[ update changelog ]
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent a5aa7ab6
...@@ -3017,7 +3017,6 @@ static void end_bio_extent_readpage(struct bio *bio) ...@@ -3017,7 +3017,6 @@ static void end_bio_extent_readpage(struct bio *bio)
*/ */
u32 bio_offset = 0; u32 bio_offset = 0;
int mirror; int mirror;
int ret;
struct bvec_iter_all iter_all; struct bvec_iter_all iter_all;
ASSERT(!bio_flagged(bio, BIO_CLONED)); ASSERT(!bio_flagged(bio, BIO_CLONED));
...@@ -3028,6 +3027,7 @@ static void end_bio_extent_readpage(struct bio *bio) ...@@ -3028,6 +3027,7 @@ static void end_bio_extent_readpage(struct bio *bio)
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
const u32 sectorsize = fs_info->sectorsize; const u32 sectorsize = fs_info->sectorsize;
unsigned int error_bitmap = (unsigned int)-1; unsigned int error_bitmap = (unsigned int)-1;
bool repair = false;
u64 start; u64 start;
u64 end; u64 end;
u32 len; u32 len;
...@@ -3065,55 +3065,23 @@ static void end_bio_extent_readpage(struct bio *bio) ...@@ -3065,55 +3065,23 @@ static void end_bio_extent_readpage(struct bio *bio)
if (is_data_inode(inode)) { if (is_data_inode(inode)) {
error_bitmap = btrfs_verify_data_csum(bbio, error_bitmap = btrfs_verify_data_csum(bbio,
bio_offset, page, start, end); bio_offset, page, start, end);
ret = error_bitmap; if (error_bitmap)
uptodate = false;
} else { } else {
ret = btrfs_validate_metadata_buffer(bbio, if (btrfs_validate_metadata_buffer(bbio,
page, start, end, mirror); page, start, end, mirror))
uptodate = false;
} }
if (ret)
uptodate = false;
else
clean_io_failure(BTRFS_I(inode)->root->fs_info,
failure_tree, tree, start,
page,
btrfs_ino(BTRFS_I(inode)), 0);
} }
if (likely(uptodate))
goto readpage_ok;
if (is_data_inode(inode)) {
/*
* If we failed to submit the IO at all we'll have a
* mirror_num == 0, in which case we need to just mark
* the page with an error and unlock it and carry on.
*/
if (mirror == 0)
goto readpage_ok;
/*
* submit_data_read_repair() will handle all the good
* and bad sectors, we just continue to the next bvec.
*/
submit_data_read_repair(inode, bio, bio_offset, bvec,
mirror, error_bitmap);
ASSERT(bio_offset + len > bio_offset);
bio_offset += len;
continue;
} else {
struct extent_buffer *eb;
eb = find_extent_buffer_readpage(fs_info, page, start);
set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
eb->read_mirror = mirror;
atomic_dec(&eb->io_pages);
}
readpage_ok:
if (likely(uptodate)) { if (likely(uptodate)) {
loff_t i_size = i_size_read(inode); loff_t i_size = i_size_read(inode);
pgoff_t end_index = i_size >> PAGE_SHIFT; pgoff_t end_index = i_size >> PAGE_SHIFT;
clean_io_failure(BTRFS_I(inode)->root->fs_info,
failure_tree, tree, start, page,
btrfs_ino(BTRFS_I(inode)), 0);
/* /*
* Zero out the remaining part if this range straddles * Zero out the remaining part if this range straddles
* i_size. * i_size.
...@@ -3130,14 +3098,40 @@ static void end_bio_extent_readpage(struct bio *bio) ...@@ -3130,14 +3098,40 @@ static void end_bio_extent_readpage(struct bio *bio)
zero_user_segment(page, zero_start, zero_user_segment(page, zero_start,
offset_in_page(end) + 1); offset_in_page(end) + 1);
} }
} else if (is_data_inode(inode)) {
/*
* Only try to repair bios that actually made it to a
* device. If the bio failed to be submitted mirror
* is 0 and we need to fail it without retrying.
*/
if (mirror > 0)
repair = true;
} else {
struct extent_buffer *eb;
eb = find_extent_buffer_readpage(fs_info, page, start);
set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
eb->read_mirror = mirror;
atomic_dec(&eb->io_pages);
} }
if (repair) {
/*
* submit_data_read_repair() will handle all the good
* and bad sectors, we just continue to the next bvec.
*/
submit_data_read_repair(inode, bio, bio_offset, bvec,
mirror, error_bitmap);
} else {
/* Update page status and unlock */
end_page_read(page, uptodate, start, len);
endio_readpage_release_extent(&processed, BTRFS_I(inode),
start, end, PageUptodate(page));
}
ASSERT(bio_offset + len > bio_offset); ASSERT(bio_offset + len > bio_offset);
bio_offset += len; bio_offset += len;
/* Update page status and unlock */
end_page_read(page, uptodate, start, len);
endio_readpage_release_extent(&processed, BTRFS_I(inode),
start, end, PageUptodate(page));
} }
/* Release the last extent */ /* Release the last extent */
endio_readpage_release_extent(&processed, NULL, 0, 0, false); endio_readpage_release_extent(&processed, NULL, 0, 0, false);
......
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