Btrfs: skip checksum verification if IO error occurs
authorLiu Bo <bo.li.liu@oracle.com>
Fri, 14 Apr 2017 01:11:48 +0000 (18:11 -0700)
committerDavid Sterba <dsterba@suse.com>
Mon, 19 Jun 2017 16:26:03 +0000 (18:26 +0200)
Currently dio read also goes to verify checksum if -EIO has been returned,
although it usually fails on checksum, it's not necessary at all, we could
directly check if there is another copy to read.

And with this, the behavior of dio read is now consistent with that of
buffered read.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ use bool for uptodate ]
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index 147bafdb862896d7c91404f22926221d8dcb8aa3..b74a6d23a0fe629818e5e5bf0af8c7c11280389a 100644 (file)
@@ -8180,6 +8180,7 @@ static int __btrfs_subio_endio_read(struct inode *inode,
        int nr_sectors;
        unsigned int pgoff;
        int csum_pos;
+       bool uptodate = (err == 0);
        int ret;
 
        fs_info = BTRFS_I(inode)->root->fs_info;
@@ -8195,12 +8196,13 @@ static int __btrfs_subio_endio_read(struct inode *inode,
 
                pgoff = bvec.bv_offset;
 next_block:
-               csum_pos = BTRFS_BYTES_TO_BLKS(fs_info, offset);
-               ret = __readpage_endio_check(inode, io_bio, csum_pos,
-                                       bvec.bv_page, pgoff, start,
-                                       sectorsize);
-               if (likely(!ret))
-                       goto next;
+               if (uptodate) {
+                       csum_pos = BTRFS_BYTES_TO_BLKS(fs_info, offset);
+                       ret = __readpage_endio_check(inode, io_bio, csum_pos,
+                                       bvec.bv_page, pgoff, start, sectorsize);
+                       if (likely(!ret))
+                               goto next;
+               }
 try_again:
                done.uptodate = 0;
                done.start = start;