From b93e441e0d733c58bb039bd0cecdba5ad1413f46 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Wed, 4 Sep 2019 21:49:01 +0200 Subject: [PATCH] BACKPORT: loop: change queue block size to match when using DIO The loop driver assumes that if the passed in fd is opened with O_DIRECT, the caller wants to use direct I/O on the loop device. However, if the underlying block device has a different block size than the loop block queue, direct I/O can't be enabled. Instead of requiring userspace to manually change the blocksize and re-enable direct I/O, just change the queue block sizes to match, as well as the io_min size. Bug: 148607611 Reviewed-by: Christoph Hellwig Signed-off-by: Martijn Coenen Signed-off-by: Jens Axboe (cherry picked from commit 85560117d00f5d528e928918b8f61cadcefff98b) Change-Id: I4d55bf99b2cb4cc6bb218a8905f18d3b2c12d5bb --- drivers/block/loop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 4c18b313c9df..45f8b1f354ef 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -996,6 +996,16 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) blk_queue_write_cache(lo->lo_queue, true, false); + if (io_is_direct(lo->lo_backing_file) && inode->i_sb->s_bdev) { + /* In case of direct I/O, match underlying block size */ + unsigned short bsize = bdev_logical_block_size( + inode->i_sb->s_bdev); + + blk_queue_logical_block_size(lo->lo_queue, bsize); + blk_queue_physical_block_size(lo->lo_queue, bsize); + blk_queue_io_min(lo->lo_queue, bsize); + } + loop_update_dio(lo); set_capacity(lo->lo_disk, size); bd_set_size(bdev, size << 9);