From: NeilBrown <neilb@suse.de>
Subject: Cause IO to O_DIRECT|O_NONBLOCK devices to use REQ_FAILFAST_DEV
Patch-mainline: unlikely
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(-)

Index: linux-3.0-SLE11-SP2/fs/block_dev.c
===================================================================
--- linux-3.0-SLE11-SP2.orig/fs/block_dev.c
+++ linux-3.0-SLE11-SP2/fs/block_dev.c
@@ -139,15 +139,25 @@ blkdev_get_block(struct inode *inode, se
 	return 0;
 }
 
+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(int rw, struct kiocb *iocb, const struct iovec *iov,
 			loff_t offset, unsigned long nr_segs)
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
+	dio_submit_t *submit_io = NULL;
 
+	if (file->f_flags & O_NONBLOCK)
+		submit_io = submit_failfast_bio;
 	return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
-				    nr_segs, blkdev_get_block, NULL, NULL, 0);
+				    nr_segs, blkdev_get_block, NULL, submit_io, 0);
 }
 
 int __sync_blockdev(struct block_device *bdev, int wait)
