btrfs: refactor end_bio_extent_readpage code flow
authorChristoph Hellwig <hch@lst.de>
Sun, 22 May 2022 11:47:51 +0000 (13:47 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 Jul 2022 15:44:34 +0000 (17:44 +0200)
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>
fs/btrfs/extent_io.c

index b50c1f1..62425d1 100644 (file)
@@ -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);