Commit e9538283 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David Sterba

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: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent d87e6575
...@@ -4315,7 +4315,6 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num, ...@@ -4315,7 +4315,6 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
int locked_pages = 0; int locked_pages = 0;
int all_uptodate = 1; int all_uptodate = 1;
int num_pages; int num_pages;
unsigned long num_reads = 0;
struct btrfs_bio_ctrl bio_ctrl = { struct btrfs_bio_ctrl bio_ctrl = {
.opf = REQ_OP_READ, .opf = REQ_OP_READ,
.mirror_num = mirror_num, .mirror_num = mirror_num,
...@@ -4361,10 +4360,8 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int 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++) { for (i = 0; i < num_pages; i++) {
page = eb->pages[i]; page = eb->pages[i];
if (!PageUptodate(page)) { if (!PageUptodate(page))
num_reads++;
all_uptodate = 0; all_uptodate = 0;
}
} }
if (all_uptodate) { if (all_uptodate) {
...@@ -4374,7 +4371,7 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num, ...@@ -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); clear_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
eb->read_mirror = 0; 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 * 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. * 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, ...@@ -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++) { for (i = 0; i < num_pages; i++) {
page = eb->pages[i]; page = eb->pages[i];
if (!PageUptodate(page)) { ClearPageError(page);
ClearPageError(page); submit_extent_page(&bio_ctrl, page_offset(page), page,
submit_extent_page(&bio_ctrl, page_offset(page), page, PAGE_SIZE, 0);
PAGE_SIZE, 0);
} else {
unlock_page(page);
}
} }
submit_one_bio(&bio_ctrl); submit_one_bio(&bio_ctrl);
......
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