Skip to content

Commit

Permalink
block: Fix __blkdev_direct_IO() for bio fragments
Browse files Browse the repository at this point in the history
The recent fix to properly handle IOCB_NOWAIT for async O_DIRECT IO
(patch 6a43074) introduced two problems with BIO fragment handling
for direct IOs:
1) The dio size processed is calculated by incrementing the ret variable
by the size of the bio fragment issued for the dio. However, this size
is obtained directly from bio->bi_iter.bi_size AFTER the bio submission
which may result in referencing the bi_size value after the bio
completed, resulting in an incorrect value use.
2) The ret variable is not incremented by the size of the last bio
fragment issued for the bio, leading to an invalid IO size being
returned to the user.

Fix both problem by using dio->size (which is incremented before the bio
submission) to update the value of ret after bio submissions, including
for the last bio fragment issued.

Fixes: 6a43074 ("block: properly handle IOCB_NOWAIT for async O_DIRECT IO")
Reported-by: Masato Suzuki <[email protected]>
Signed-off-by: Damien Le Moal <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
damien-lemoal authored and axboe committed Aug 1, 2019
1 parent 3d0b63c commit 0eb6ddf
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
ret = -EAGAIN;
goto error;
}
ret = dio->size;

if (polled)
WRITE_ONCE(iocb->ki_cookie, qc);
Expand All @@ -465,7 +466,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
ret = -EAGAIN;
goto error;
}
ret += bio->bi_iter.bi_size;
ret = dio->size;

bio = bio_alloc(gfp, nr_pages);
if (!bio) {
Expand Down

0 comments on commit 0eb6ddf

Please sign in to comment.