Skip to content

Commit ceaa762

Browse files
committed
block: move direct_IO into our own read_iter handler
Don't call into generic_file_read_iter() if we know it's O_DIRECT, just set it up ourselves and call our own handler. This avoids an indirect call for O_DIRECT. Fall back to filemap_read() if we fail. Signed-off-by: Jens Axboe <[email protected]>
1 parent 4bdcd1d commit ceaa762

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

block/fops.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -566,21 +566,48 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
566566
{
567567
struct block_device *bdev = iocb->ki_filp->private_data;
568568
loff_t size = bdev_nr_bytes(bdev);
569+
size_t count = iov_iter_count(to);
569570
loff_t pos = iocb->ki_pos;
570571
size_t shorted = 0;
571-
ssize_t ret;
572+
ssize_t ret = 0;
572573

573-
if (unlikely(pos + iov_iter_count(to) > size)) {
574+
if (unlikely(pos + count > size)) {
574575
if (pos >= size)
575576
return 0;
576577
size -= pos;
577-
if (iov_iter_count(to) > size) {
578-
shorted = iov_iter_count(to) - size;
578+
if (count > size) {
579+
shorted = count - size;
579580
iov_iter_truncate(to, size);
580581
}
581582
}
582583

583-
ret = generic_file_read_iter(iocb, to);
584+
if (iocb->ki_flags & IOCB_DIRECT) {
585+
struct address_space *mapping = iocb->ki_filp->f_mapping;
586+
587+
if (iocb->ki_flags & IOCB_NOWAIT) {
588+
if (filemap_range_needs_writeback(mapping, iocb->ki_pos,
589+
iocb->ki_pos + count - 1))
590+
return -EAGAIN;
591+
} else {
592+
ret = filemap_write_and_wait_range(mapping,
593+
iocb->ki_pos,
594+
iocb->ki_pos + count - 1);
595+
if (ret < 0)
596+
return ret;
597+
}
598+
599+
file_accessed(iocb->ki_filp);
600+
601+
ret = blkdev_direct_IO(iocb, to);
602+
if (ret >= 0) {
603+
iocb->ki_pos += ret;
604+
count -= ret;
605+
}
606+
if (ret < 0 || !count)
607+
return ret;
608+
}
609+
610+
ret = filemap_read(iocb, to, ret);
584611

585612
if (unlikely(shorted))
586613
iov_iter_reexpand(to, iov_iter_count(to) + shorted);

0 commit comments

Comments
 (0)