[PATCH 6/8] loop: relax loop dio use condition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



So far loop dio requires the following conditions:

1) lo->lo_offset is aligned with backing queue's logical block size

2) loop queue's logical block size is <= backing queue's logical block
   size

We have supported to fallback to buffered IO, so unaligned IO can't be
completed successfully.

Also the current usage wrt. loop queue's logical block size is hardly
to work as expected, set dio and updating logical block size are done
in different ioctls, and logical block size is often set before setting
direct io. Relaxing dio use in this way won't cause real effect in
reality.

Then we needn't to freeze queue any more when updating dio since loop
IO can be done successfully with the fallback buffered io.

Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx>
---
 drivers/block/loop.c | 36 +-----------------------------------
 1 file changed, 1 insertion(+), 35 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index fee78a640f75..f42630246758 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -215,31 +215,10 @@ static void __loop_update_dio(struct loop_device *lo, bool dio)
 {
 	struct file *file = lo->lo_backing_file;
 	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;
-	}
-
-	/*
-	 * 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 (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
-				!(lo->lo_offset & dio_align) &&
-				mapping->a_ops->direct_IO &&
-				!lo->transfer)
+		if (mapping->a_ops->direct_IO && !lo->transfer)
 			use_dio = true;
 		else
 			use_dio = false;
@@ -253,13 +232,6 @@ static void __loop_update_dio(struct loop_device *lo, bool dio)
 	/* flush dirty pages before changing direct IO */
 	vfs_fsync(file, 0);
 
-	/*
-	 * The flag of LO_FLAGS_DIRECT_IO is handled similarly with
-	 * LO_FLAGS_READ_ONLY, both are set from kernel, and losetup
-	 * will get updated by ioctl(LOOP_GET_STATUS)
-	 */
-	if (lo->lo_state == Lo_bound)
-		blk_mq_freeze_queue(lo->lo_queue);
 	lo->use_dio = use_dio;
 	if (use_dio) {
 		blk_queue_flag_clear(QUEUE_FLAG_NOMERGES, lo->lo_queue);
@@ -268,8 +240,6 @@ static void __loop_update_dio(struct loop_device *lo, bool dio)
 		blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue);
 		lo->lo_flags &= ~LO_FLAGS_DIRECT_IO;
 	}
-	if (lo->lo_state == Lo_bound)
-		blk_mq_unfreeze_queue(lo->lo_queue);
 }
 
 /**
@@ -1248,9 +1218,6 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
 
 	if (config->block_size)
 		bsize = config->block_size;
-	else if ((lo->lo_backing_file->f_flags & O_DIRECT) && inode->i_sb->s_bdev)
-		/* In case of direct I/O, match underlying block size */
-		bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
 	else
 		bsize = 512;
 
@@ -1753,7 +1720,6 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
 	blk_queue_logical_block_size(lo->lo_queue, arg);
 	blk_queue_physical_block_size(lo->lo_queue, arg);
 	blk_queue_io_min(lo->lo_queue, arg);
-	loop_update_dio(lo);
 out_unfreeze:
 	blk_mq_unfreeze_queue(lo->lo_queue);
 
-- 
2.31.1




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux