summaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2023-05-03 17:24:25 +0200
committerDavid Sterba <dsterba@suse.com>2023-05-15 13:04:47 +0200
commite0811da0a47a0e4534ea8903c83ed3e3f24da888 (patch)
tree0425598ac270c6c115ca278800068096738d7a5f /fs/btrfs
parentfb2e69cfb75e94de8e7614d799e4e4a8df890695 (diff)
downloadlinux-next-e0811da0a47a0e4534ea8903c83ed3e3f24da888.tar.gz
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: Christoph Hellwig <hch@lst.de> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/extent_io.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index a75e05c4f496..ede7c88e829e 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -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);