]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
I/O ERROR WHEN A FILE ON ACFS FILESYSTEM IS ATTACHED TO THE GUEST DOMU
authorJoe Jin <joe.jin@oracle.com>
Thu, 6 Apr 2017 23:56:57 +0000 (07:56 +0800)
committerChuck Anderson <chuck.anderson@oracle.com>
Tue, 30 May 2017 05:45:11 +0000 (22:45 -0700)
Orabug: 25831471

commit "block: loop: prepare for supporing direct IO" used old codes
from lkml, synced it with upstream codes.

Signed-off-by: Joe Jin <joe.jin@oracle.com>
Signed-off-by: Aniket Alshi <aniket.alshi@oracle.com>
Reviewed-by: Jack Vogel <jack.vogel@oracle.com>
drivers/block/loop.c

index 58696da97649e52d3dd502199da419d5c666f05c..062dfb6dded95f8e3a7d2359bb8b25578d1ed039 100644 (file)
@@ -549,24 +549,35 @@ struct switch_request {
 static void __loop_update_dio(struct loop_device *lo, bool dio)
 {
        struct file *file = lo->lo_backing_file;
-       struct inode *inode = file->f_mapping->host;
+       struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
+       unsigned short sb_bsize = 0;
+       unsigned dio_align = 0;
        bool use_dio;
 
+       if (inode->i_sb->s_bdev) {
+               sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
+               dio_align = sb_bsize - 1;
+       }
+
        /*
-        * loop block's logical block size is 512, now
-        * we support direct I/O only if the backing
-        * block devices' minimize I/O size is 512 and
-        * the offset is aligned with 512.
+        * We support direct I/O only if lo_offset is aligned with the
+        * logical I/O size of backing device, and the logical block
+        * size of loop is bigger than the backing device's and the loop
+        * needn't transform transfer.
+        *
+        * TODO: the above condition may be loosed in the future, and
+        * direct I/O may be switched runtime at that time because most
+        * of requests in sane applications should be PAGE_SIZE aligned
         */
        if (dio) {
-               if (inode->i_sb->s_bdev) {
-                       if (bdev_io_min(inode->i_sb->s_bdev) == 512 &&
-                           !(lo->lo_offset & 511))
-                               use_dio = true;
-                       else
-                               use_dio = false;
-               } else
+               if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
+                               !(lo->lo_offset & dio_align) &&
+                               mapping->a_ops->direct_IO &&
+                               !lo->transfer)
                        use_dio = true;
+               else
+                       use_dio = false;
        } else {
                use_dio = false;
        }