btrfs: always read the entire extent_buffer
Currently read_extent_buffer_pages skips pages that are already uptodate when reading in an extent_buffer. While this reduces the amount of data read, it increases the number of I/O operations as we now need to do multiple I/Os when reading an extent buffer with one or more uptodate pages in the middle of it. On any modern storage device, be that hard drives or SSDs this actually decreases I/O performance. Fortunately this case is pretty rare as the pages are always initially read together and then aged the same way. Besides simplifying the code a bit as-is this will allow for major simplifications to the I/O completion handler later on. Note that the case where all pages are uptodate is still handled by an optimized fast path that does not read any data from disk. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
d87e6575e9
Коммит
e95382834c
|
@ -4315,7 +4315,6 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
|
|||
int locked_pages = 0;
|
||||
int all_uptodate = 1;
|
||||
int num_pages;
|
||||
unsigned long num_reads = 0;
|
||||
struct btrfs_bio_ctrl bio_ctrl = {
|
||||
.opf = REQ_OP_READ,
|
||||
.mirror_num = mirror_num,
|
||||
|
@ -4361,10 +4360,8 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
|
|||
*/
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
page = eb->pages[i];
|
||||
if (!PageUptodate(page)) {
|
||||
num_reads++;
|
||||
if (!PageUptodate(page))
|
||||
all_uptodate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (all_uptodate) {
|
||||
|
@ -4374,7 +4371,7 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
|
|||
|
||||
clear_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
|
||||
eb->read_mirror = 0;
|
||||
atomic_set(&eb->io_pages, num_reads);
|
||||
atomic_set(&eb->io_pages, num_pages);
|
||||
/*
|
||||
* It is possible for release_folio to clear the TREE_REF bit before we
|
||||
* set io_pages. See check_buffer_tree_ref for a more detailed comment.
|
||||
|
@ -4384,13 +4381,9 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
|
|||
for (i = 0; i < num_pages; i++) {
|
||||
page = eb->pages[i];
|
||||
|
||||
if (!PageUptodate(page)) {
|
||||
ClearPageError(page);
|
||||
submit_extent_page(&bio_ctrl, page_offset(page), page,
|
||||
PAGE_SIZE, 0);
|
||||
} else {
|
||||
unlock_page(page);
|
||||
}
|
||||
ClearPageError(page);
|
||||
submit_extent_page(&bio_ctrl, page_offset(page), page,
|
||||
PAGE_SIZE, 0);
|
||||
}
|
||||
|
||||
submit_one_bio(&bio_ctrl);
|
||||
|
|
Загрузка…
Ссылка в новой задаче