From: Jens Axboe Date: Thu, 11 Feb 2021 15:35:43 +0000 (-0700) Subject: iomap: relax memory alignment restriction for O_DIRECT X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=refs%2Fheads%2Fdio-mem-align;p=linux-2.6-block.git iomap: relax memory alignment restriction for O_DIRECT We currently require blocksize alignment for both position/length and the memory range. The latter is overly restrictive, as most devices can do DMA at a much finer granularity. Honor the bdev setting for DMA alignment, and use that for checking if we can process the IO or need to error it. Signed-off-by: Jens Axboe --- diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index 933f234d5bec..7f962011fa0c 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -207,7 +207,8 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, { unsigned int blkbits = blksize_bits(bdev_logical_block_size(iomap->bdev)); unsigned int fs_block_size = i_blocksize(inode), pad; - unsigned int align = iov_iter_alignment(dio->submit.iter); + struct request_queue *q = bdev_get_queue(iomap->bdev); + unsigned long mem_align = q->dma_alignment; struct bio *bio; bool need_zeroout = false; bool use_fua = false; @@ -215,7 +216,9 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, size_t copied = 0; size_t orig_count; - if ((pos | length | align) & ((1 << blkbits) - 1)) + if ((pos | length) & ((1 << blkbits) - 1)) + return -EINVAL; + if (iov_iter_alignment(dio->submit.iter) & mem_align) return -EINVAL; if (iomap->type == IOMAP_UNWRITTEN) { @@ -237,8 +240,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, * cache flushes on IO completion. */ if (!(iomap->flags & (IOMAP_F_SHARED|IOMAP_F_DIRTY)) && - (dio->flags & IOMAP_DIO_WRITE_FUA) && - blk_queue_fua(bdev_get_queue(iomap->bdev))) + (dio->flags & IOMAP_DIO_WRITE_FUA) && blk_queue_fua(q)) use_fua = true; }