[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    Btrfs: fix unexpected result when dio reading corrupted blocks
From:       "Linux Kernel Mailing List" <linux-kernel () vger ! kernel ! org>
Date:       2017-09-29 20:02:04
Message-ID: 20170929200204.1F0C721B60 () pdx-korg-gitolite-1 ! ci ! codeaurora ! org
[Download RAW message or body]

Web:        https://git.kernel.org/torvalds/c/99c4e3b96c797f047be4e6b7c03cfca01959f146
Commit:     99c4e3b96c797f047be4e6b7c03cfca01959f146
Parent:     36b96fdc6b2dc6f4a0fedc563fa7508c91b90a10
Refname:    refs/heads/master
Author:     Liu Bo <bo.li.liu@oracle.com>
AuthorDate: Fri Sep 15 15:06:51 2017 -0600
Committer:  David Sterba <dsterba@suse.com>
CommitDate: Tue Sep 26 14:54:07 2017 +0200

    Btrfs: fix unexpected result when dio reading corrupted blocks
    
    commit 4246a0b63bd8 ("block: add a bi_error field to struct bio")
    changed the logic of how dio read endio reports errors.
    
    For single stripe dio read, %bio->bi_status reflects the error before
    verifying checksum, and now we're updating it when data block matches
    with its checksum, while in the mismatching case, %bio->bi_status is
    not updated to relfect that.
    
    When some blocks in a file have been corrupted on disk, reading such a
    file ends up with
    
    1) checksum errors are reported in kernel log
    2) read(2) returns successfully with some content being 0x01.
    
    In order to fix it, we need to report its checksum mismatch error to
    the upper layer (dio layer in this case) as well.
    
    Fixes: 4246a0b63bd8 ("block: add a bi_error field to struct bio")
    Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
    Reported-by: Goffredo Baroncelli <kreijack@inwind.it>
    Tested-by: Goffredo Baroncelli <kreijack@inwind.it>
    Reviewed-by: David Sterba <dsterba@suse.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/inode.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f78c5640c6dc..c242d0230db9 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8366,11 +8366,8 @@ static void btrfs_endio_direct_read(struct bio *bio)
 	struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
 	blk_status_t err = bio->bi_status;
 
-	if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) {
+	if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED)
 		err = btrfs_subio_endio_read(inode, io_bio, err);
-		if (!err)
-			bio->bi_status = 0;
-	}
 
 	unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
 		      dip->logical_offset + dip->bytes - 1);
@@ -8378,7 +8375,7 @@ static void btrfs_endio_direct_read(struct bio *bio)
 
 	kfree(dip);
 
-	dio_bio->bi_status = bio->bi_status;
+	dio_bio->bi_status = err;
 	dio_end_io(dio_bio);
 
 	if (io_bio->end_io)
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic