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: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: David Sterba <dsterba@suse.com> [ update changelog ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
committed by
David Sterba
parent
a5aa7ab6e7
commit
97861cd166
@ -3017,7 +3017,6 @@ static void end_bio_extent_readpage(struct bio *bio)
|
||||
*/
|
||||
u32 bio_offset = 0;
|
||||
int mirror;
|
||||
int ret;
|
||||
struct bvec_iter_all iter_all;
|
||||
|
||||
ASSERT(!bio_flagged(bio, BIO_CLONED));
|
||||
@ -3028,6 +3027,7 @@ static void end_bio_extent_readpage(struct bio *bio)
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
const u32 sectorsize = fs_info->sectorsize;
|
||||
unsigned int error_bitmap = (unsigned int)-1;
|
||||
bool repair = false;
|
||||
u64 start;
|
||||
u64 end;
|
||||
u32 len;
|
||||
@ -3065,55 +3065,23 @@ static void end_bio_extent_readpage(struct bio *bio)
|
||||
if (is_data_inode(inode)) {
|
||||
error_bitmap = btrfs_verify_data_csum(bbio,
|
||||
bio_offset, page, start, end);
|
||||
ret = error_bitmap;
|
||||
if (error_bitmap)
|
||||
uptodate = false;
|
||||
} else {
|
||||
ret = btrfs_validate_metadata_buffer(bbio,
|
||||
page, start, end, mirror);
|
||||
if (btrfs_validate_metadata_buffer(bbio,
|
||||
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)) {
|
||||
loff_t i_size = i_size_read(inode);
|
||||
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
|
||||
* i_size.
|
||||
@ -3130,14 +3098,40 @@ readpage_ok:
|
||||
zero_user_segment(page, zero_start,
|
||||
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);
|
||||
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 */
|
||||
endio_readpage_release_extent(&processed, NULL, 0, 0, false);
|
||||
|
Reference in New Issue
Block a user