From: NeilBrown <neilb@suse.de>
Subject: Cause IO to O_DIRECT|O_NONBLOCK devices to use REQ_FAILFAST_DEV
Patch-mainline: Not yet, failfast is poorly defined
References: bnc#750141

Linux can mark IO requests as FAILFAST to the device doesn't try so hard.

This functionality is currently not available via block-special-file access.

It only makes sense with O_DIRECT, and seems to fit with O_NONBLOCK,
so arrange that a block device opened with these two flags causes
REQ_FAILFAST_DEV to be used.

Signed-off-by: Neil Brown <neilb@suse.de>

---
 fs/block_dev.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -156,17 +156,27 @@ blkdev_get_block(struct inode *inode, se
 	return file->f_mapping->host;
 }
 
+static void submit_failfast_bio(int rw, struct bio *bio, struct inode *inode,
+				loff_t offset)
+{
+	bio->bi_rw |= REQ_FAILFAST_DEV;
+	submit_bio(rw, bio);
+}
+
 static ssize_t
 blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset)
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = bdev_file_inode(file);
+	dio_submit_t *submit_io = NULL;
 
+	if (file->f_flags & O_NONBLOCK)
+		submit_io = submit_failfast_bio;
 	if (IS_DAX(inode))
 		return dax_do_io(iocb, inode, iter, offset, blkdev_get_block,
 				NULL, DIO_SKIP_DIO_COUNT);
 	return __blockdev_direct_IO(iocb, inode, I_BDEV(inode), iter, offset,
-				    blkdev_get_block, NULL, NULL,
+				    blkdev_get_block, NULL, submit_io,
 				    DIO_SKIP_DIO_COUNT);
 }
 
