]>
Commit | Line | Data |
---|---|---|
1dabdb6f GKH |
1 | From a89afe58f1a74aac768a5eb77af95ef4ee15beaa Mon Sep 17 00:00:00 2001 |
2 | From: Jason Yan <yanaijie@huawei.com> | |
3 | Date: Fri, 12 Apr 2019 10:09:16 +0800 | |
4 | Subject: block: fix the return errno for direct IO | |
5 | ||
6 | From: Jason Yan <yanaijie@huawei.com> | |
7 | ||
8 | commit a89afe58f1a74aac768a5eb77af95ef4ee15beaa upstream. | |
9 | ||
10 | If the last bio returned is not dio->bio, the status of the bio will | |
11 | not assigned to dio->bio if it is error. This will cause the whole IO | |
12 | status wrong. | |
13 | ||
14 | ksoftirqd/21-117 [021] ..s. 4017.966090: 8,0 C N 4883648 [0] | |
15 | <idle>-0 [018] ..s. 4017.970888: 8,0 C WS 4924800 + 1024 [0] | |
16 | <idle>-0 [018] ..s. 4017.970909: 8,0 D WS 4935424 + 1024 [<idle>] | |
17 | <idle>-0 [018] ..s. 4017.970924: 8,0 D WS 4936448 + 321 [<idle>] | |
18 | ksoftirqd/21-117 [021] ..s. 4017.995033: 8,0 C R 4883648 + 336 [65475] | |
19 | ksoftirqd/21-117 [021] d.s. 4018.001988: myprobe1: (blkdev_bio_end_io+0x0/0x168) bi_status=7 | |
20 | ksoftirqd/21-117 [021] d.s. 4018.001992: myprobe: (aio_complete_rw+0x0/0x148) x0=0xffff802f2595ad80 res=0x12a000 res2=0x0 | |
21 | ||
22 | We always have to assign bio->bi_status to dio->bio.bi_status because we | |
23 | will only check dio->bio.bi_status when we return the whole IO to | |
24 | the upper layer. | |
25 | ||
26 | Fixes: 542ff7bf18c6 ("block: new direct I/O implementation") | |
27 | Cc: stable@vger.kernel.org | |
28 | Cc: Christoph Hellwig <hch@lst.de> | |
29 | Cc: Jens Axboe <axboe@kernel.dk> | |
30 | Reviewed-by: Ming Lei <ming.lei@redhat.com> | |
31 | Signed-off-by: Jason Yan <yanaijie@huawei.com> | |
32 | Signed-off-by: Jens Axboe <axboe@kernel.dk> | |
33 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
34 | ||
35 | --- | |
36 | fs/block_dev.c | 8 ++++---- | |
37 | 1 file changed, 4 insertions(+), 4 deletions(-) | |
38 | ||
39 | --- a/fs/block_dev.c | |
40 | +++ b/fs/block_dev.c | |
41 | @@ -296,10 +296,10 @@ static void blkdev_bio_end_io(struct bio | |
42 | struct blkdev_dio *dio = bio->bi_private; | |
43 | bool should_dirty = dio->should_dirty; | |
44 | ||
45 | - if (dio->multi_bio && !atomic_dec_and_test(&dio->ref)) { | |
46 | - if (bio->bi_status && !dio->bio.bi_status) | |
47 | - dio->bio.bi_status = bio->bi_status; | |
48 | - } else { | |
49 | + if (bio->bi_status && !dio->bio.bi_status) | |
50 | + dio->bio.bi_status = bio->bi_status; | |
51 | + | |
52 | + if (!dio->multi_bio || atomic_dec_and_test(&dio->ref)) { | |
53 | if (!dio->is_sync) { | |
54 | struct kiocb *iocb = dio->iocb; | |
55 | ssize_t ret; |