OSDN Git Service

btrfs: always read the entire extent_buffer
authorChristoph Hellwig <hch@lst.de>
Wed, 3 May 2023 15:24:25 +0000 (17:24 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 19 Jun 2023 11:59:27 +0000 (13:59 +0200)
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>
fs/btrfs/extent_io.c

index a75e05c..ede7c88 100644 (file)
@@ -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);