summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2015-10-27 14:09:51 +0900
committerJens Axboe <axboe@fb.com>2015-11-07 10:40:47 -0700
commit15c4f638f3d41bae52105ca4c0c8760afbcbeaab (patch)
tree4de68193b0c318d6b1b00ec2a06ae40c8ec8069e
parenta0fa9647a54e81883abd57c5c865d1747f68a577 (diff)
directio: add block polling support
This adds support for sync O_DIRECT read/write poll support. Signed-off-by: Jens Axboe <axboe@fb.com> [hch: split from a larger patch, minor updates] Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Keith Busch <keith.busch@intel.com>
-rw-r--r--fs/direct-io.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 3ae0e0427191..7025029c666f 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -109,6 +109,8 @@ struct dio_submit {
struct dio {
int flags; /* doesn't change */
int rw;
+ blk_qc_t bio_cookie;
+ struct block_device *bio_bdev;
struct inode *inode;
loff_t i_size; /* i_size when submitted */
dio_iodone_t *end_io; /* IO completion function */
@@ -397,11 +399,14 @@ static inline void dio_bio_submit(struct dio *dio, struct dio_submit *sdio)
if (dio->is_async && dio->rw == READ && dio->should_dirty)
bio_set_pages_dirty(bio);
- if (sdio->submit_io)
+ if (sdio->submit_io) {
sdio->submit_io(dio->rw, bio, dio->inode,
sdio->logical_offset_in_bio);
- else
- submit_bio(dio->rw, bio);
+ dio->bio_cookie = BLK_QC_T_NONE;
+ } else {
+ dio->bio_cookie = submit_bio(dio->rw, bio);
+ dio->bio_bdev = bio->bi_bdev;
+ }
sdio->bio = NULL;
sdio->boundary = 0;
@@ -440,7 +445,8 @@ static struct bio *dio_await_one(struct dio *dio)
__set_current_state(TASK_UNINTERRUPTIBLE);
dio->waiter = current;
spin_unlock_irqrestore(&dio->bio_lock, flags);
- io_schedule();
+ if (!blk_poll(bdev_get_queue(dio->bio_bdev), dio->bio_cookie))
+ io_schedule();
/* wake up sets us TASK_RUNNING */
spin_lock_irqsave(&dio->bio_lock, flags);
dio->waiter = NULL;