From: Joe Jin Date: Thu, 6 Apr 2017 23:56:57 +0000 (+0800) Subject: I/O ERROR WHEN A FILE ON ACFS FILESYSTEM IS ATTACHED TO THE GUEST DOMU X-Git-Tag: v4.1.12-102.0.20170529_2200~7 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=6f4f658526229c5f2476f5b66dfaef30dca5fa31;p=users%2Fjedix%2Flinux-maple.git I/O ERROR WHEN A FILE ON ACFS FILESYSTEM IS ATTACHED TO THE GUEST DOMU 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 Signed-off-by: Aniket Alshi Reviewed-by: Jack Vogel --- diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 58696da97649e..062dfb6dded95 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -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; }