@@ -62,8 +62,9 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,
struct bio bio;
ssize_t ret;
- if ((pos | iov_iter_alignment(iter)) &
- (bdev_logical_block_size(bdev) - 1))
+ if ((pos | iov_iter_count(iter)) & (bdev_logical_block_size(bdev) - 1))
+ return -EINVAL;
+ if (iov_iter_alignment(iter) & bdev_dma_alignment(bdev))
return -EINVAL;
if (nr_pages <= DIO_INLINE_BIO_VECS)
@@ -193,8 +194,9 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
loff_t pos = iocb->ki_pos;
int ret = 0;
- if ((pos | iov_iter_alignment(iter)) &
- (bdev_logical_block_size(bdev) - 1))
+ if ((pos | iov_iter_count(iter)) & (bdev_logical_block_size(bdev) - 1))
+ return -EINVAL;
+ if (iov_iter_alignment(iter) & bdev_dma_alignment(bdev))
return -EINVAL;
bio = bio_alloc_kiocb(iocb, bdev, nr_pages, opf, &blkdev_dio_pool);
@@ -316,8 +318,9 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
loff_t pos = iocb->ki_pos;
int ret = 0;
- if ((pos | iov_iter_alignment(iter)) &
- (bdev_logical_block_size(bdev) - 1))
+ if ((pos | iov_iter_count(iter)) & (bdev_logical_block_size(bdev) - 1))
+ return -EINVAL;
+ if (iov_iter_alignment(iter) & bdev_dma_alignment(bdev))
return -EINVAL;
bio = bio_alloc_kiocb(iocb, bdev, nr_pages, opf, &blkdev_dio_pool);
@@ -1132,7 +1132,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
struct dio_submit sdio = { 0, };
struct buffer_head map_bh = { 0, };
struct blk_plug plug;
- unsigned long align = offset | iov_iter_alignment(iter);
+ unsigned long align = iov_iter_alignment(iter);
/*
* Avoid references to bdev if not absolutely needed to give
@@ -1166,11 +1166,14 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
goto fail_dio;
}
- if (align & blocksize_mask) {
- if (bdev)
+ if ((offset | align) & blocksize_mask) {
+ if (bdev) {
blkbits = blksize_bits(bdev_logical_block_size(bdev));
+ if (align & bdev_dma_alignment(bdev))
+ goto fail_dio;
+ }
blocksize_mask = (1 << blkbits) - 1;
- if (align & blocksize_mask)
+ if ((offset | count) & blocksize_mask)
goto fail_dio;
}
@@ -243,7 +243,8 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
size_t copied = 0;
size_t orig_count;
- if ((pos | length | align) & ((1 << blkbits) - 1))
+ if ((pos | length) & ((1 << blkbits) - 1) ||
+ align & bdev_dma_alignment(iomap->bdev))
return -EINVAL;
if (iomap->type == IOMAP_UNWRITTEN) {
@@ -1378,6 +1378,11 @@ static inline int queue_dma_alignment(const struct request_queue *q)
return q ? q->dma_alignment : 511;
}
+static inline unsigned int bdev_dma_alignment(struct block_device *bdev)
+{
+ return queue_dma_alignment(bdev_get_queue(bdev));
+}
+
static inline int blk_rq_aligned(struct request_queue *q, unsigned long addr,
unsigned int len)
{