Linux filesystem development
 help / color / mirror / Atom feed
* [PATCH RESEND 0/5] block: validate direct I/O memory alignment
@ 2026-07-20 20:10 Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 1/5] block: use blkdev_iov_iter_get_pages status for errors Keith Busch
                   ` (6 more replies)
  0 siblings, 7 replies; 21+ messages in thread
From: Keith Busch @ 2026-07-20 20:10 UTC (permalink / raw)
  To: linux-block, linux-fsdevel
  Cc: dm-devel, hch, axboe, brauner, djwong, viro, Keith Busch

From: Keith Busch <kbusch@kernel.org>

Resending in case this got lost.

This addresses the misaligned direct-io problem behind various threads:

 https://lore.kernel.org/linux-xfs/20260610145218.141369-1-cem@kernel.org/
 https://lore.kernel.org/all/CAC_j7i1R7oy+nRhxEjCTba=DUgn02w9X+p94DCu0aHv5+5tKnQ@mail.gmail.com/
 https://lore.kernel.org/linux-block/ai7rnH20IYeSmY8s@gallifrey/
 https://lore.kernel.org/linux-block/20260616154009.2123183-1-kbusch@meta.com/

The previously tested fixes are correct as far as they go, but they
treat the symptom: they only matter because an invalid bio reaches those
drivers in the first place.

The reason it reaches them is an assumption I made when I removed
direct-io alignment checks in 5ff3f74e145a ("block: simplify direct io
validity check") and 7eac331869575 ("iomap: simplify direct io validity
check"): every bio is eventually split to the device limits, and the
upper layers cope with resulting errors once the bio has formed. Both
were optimistic assumptions. Drivers with their own ->submit_bio may
never pass through blk_mq_submit_bio()'s split, so the check never runs
for them, and as numerous threads showed, the consumers don't uniformly
handle this condition.

This series stops the invalid bio at the source instead. It validates
the buffer's alignment against the alignment limits when the bio is
built from the iov_iter. The check is folded into the bvec extraction
that already walks the vectors, so it adds only a comparison on a path
that is pinning direct-io pages anyway. Misalignment is now uniformly
rejected with EINVAL before submission for every direct-io path.

Only changes in this version are just adding the reviewers from the
previous:

https://lore.kernel.org/linux-block/20260624170905.3972095-1-kbusch@meta.com/

Keith Busch (5):
  block: use blkdev_iov_iter_get_pages status for errors
  block: fix dio leak on metadata mapping error
  loop: set dma_alignment from the backing file for direct I/O
  zloop: set dma_alignment from the backing files for direct I/O
  block: validate user space vectors during extraction

 block/bio.c           | 56 ++++++++++++++++++++++++++++++++++++++++---
 block/blk-map.c       |  2 +-
 block/fops.c          | 10 ++++----
 drivers/block/loop.c  | 46 ++++++++++++++++++++++++++++-------
 drivers/block/zloop.c | 35 +++++++++++++++++++--------
 fs/iomap/direct-io.c  |  1 +
 include/linux/bio.h   |  2 +-
 include/linux/uio.h   | 10 +++++++-
 lib/iov_iter.c        |  9 ++++++-
 9 files changed, 142 insertions(+), 29 deletions(-)

-- 
2.52.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH RESEND 1/5] block: use blkdev_iov_iter_get_pages status for errors
  2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
@ 2026-07-20 20:10 ` Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 2/5] block: fix dio leak on metadata mapping error Keith Busch
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Keith Busch @ 2026-07-20 20:10 UTC (permalink / raw)
  To: linux-block, linux-fsdevel
  Cc: dm-devel, hch, axboe, brauner, djwong, viro, Keith Busch,
	Hannes Reinecke

From: Keith Busch <kbusch@kernel.org>

blkdev_iov_iter_get_pages() can return various error values, including
EIO, EFAULT, and ENOMEM. Set the actual reported status so user space
can know why an operation failed.

Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/fops.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/fops.c b/block/fops.c
index 15783a6180dec..0827bb884d473 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -218,7 +218,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
 
 		ret = blkdev_iov_iter_get_pages(bio, iter, bdev);
 		if (unlikely(ret)) {
-			bio_endio_status(bio, BLK_STS_IOERR);
+			bio_endio_status(bio, errno_to_blk_status(ret));
 			break;
 		}
 		if (iocb->ki_flags & IOCB_NOWAIT) {
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RESEND 2/5] block: fix dio leak on metadata mapping error
  2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 1/5] block: use blkdev_iov_iter_get_pages status for errors Keith Busch
@ 2026-07-20 20:10 ` Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 3/5] loop: set dma_alignment from the backing file for direct I/O Keith Busch
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Keith Busch @ 2026-07-20 20:10 UTC (permalink / raw)
  To: linux-block, linux-fsdevel
  Cc: dm-devel, hch, axboe, brauner, djwong, viro, Keith Busch,
	Hannes Reinecke

From: Keith Busch <kbusch@kernel.org>

A failed integrity mapping holds a dio reference, so we need to go
through the full bio ending in case there were previously submitted
bio's in the sequence.

Fixes: 2729a60bbfb92 ("block: don't silently ignore metadata for sync read/write")
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/fops.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/block/fops.c b/block/fops.c
index 0827bb884d473..0098a90a956e1 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -238,8 +238,10 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
 		}
 		if (iocb->ki_flags & IOCB_HAS_METADATA) {
 			ret = bio_integrity_map_iter(bio, iocb->private);
-			if (unlikely(ret))
-				goto fail;
+			if (unlikely(ret)) {
+				bio_endio_status(bio, errno_to_blk_status(ret));
+				break;
+			}
 		}
 
 		if (is_read) {
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RESEND 3/5] loop: set dma_alignment from the backing file for direct I/O
  2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 1/5] block: use blkdev_iov_iter_get_pages status for errors Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 2/5] block: fix dio leak on metadata mapping error Keith Busch
@ 2026-07-20 20:10 ` Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 4/5] zloop: set dma_alignment from the backing files " Keith Busch
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Keith Busch @ 2026-07-20 20:10 UTC (permalink / raw)
  To: linux-block, linux-fsdevel
  Cc: dm-devel, hch, axboe, brauner, djwong, viro, Keith Busch,
	Hannes Reinecke

From: Keith Busch <kbusch@kernel.org>

Direct I/O user pages are forwarded to the backing file unchanged, so
the backing's DMA alignment requirement applies to them. Track the
backing's dio_mem_align and advertise it as the loop device's
dma_alignment so we advertise proper limits and misaligned I/O is
rejected here instead of being dispatched to the backend.

Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 drivers/block/loop.c | 46 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 310de0463beb1..5fe61d542f8b7 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -54,6 +54,7 @@ struct loop_device {
 
 	struct file	*lo_backing_file;
 	unsigned int	lo_min_dio_size;
+	unsigned int	lo_dio_mem_align;
 	struct block_device *lo_device;
 
 	gfp_t		old_gfp_mask;
@@ -447,26 +448,37 @@ static void loop_reread_partitions(struct loop_device *lo)
 			__func__, lo->lo_number, lo->lo_file_name, rc);
 }
 
-static unsigned int loop_query_min_dio_size(struct loop_device *lo)
+static void loop_update_dio_alignment(struct loop_device *lo)
 {
 	struct file *file = lo->lo_backing_file;
 	struct block_device *sb_bdev = file->f_mapping->host->i_sb->s_bdev;
 	struct kstat st;
 
 	/*
-	 * Use the minimal dio alignment of the file system if provided.
+	 * Use the dio alignment of the file system if provided.  The incomoing
+	 * request's bio_vec is forwarded to the backing file unchanged, so its
+	 * required memory alignment becomes the device's dma_alignment when
+	 * used for direct-io.
 	 */
 	if (!vfs_getattr(&file->f_path, &st, STATX_DIOALIGN, 0) &&
-	    (st.result_mask & STATX_DIOALIGN))
-		return st.dio_offset_align;
+	    (st.result_mask & STATX_DIOALIGN)) {
+		lo->lo_min_dio_size = st.dio_offset_align;
+		lo->lo_dio_mem_align = st.dio_mem_align - 1;
+		return;
+	}
 
 	/*
 	 * In a perfect world this wouldn't be needed, but as of Linux 6.13 only
 	 * a handful of file systems support the STATX_DIOALIGN flag.
 	 */
-	if (sb_bdev)
-		return bdev_logical_block_size(sb_bdev);
-	return SECTOR_SIZE;
+	if (sb_bdev) {
+		lo->lo_min_dio_size = bdev_logical_block_size(sb_bdev);
+		lo->lo_dio_mem_align = bdev_dma_alignment(sb_bdev);
+		return;
+	}
+
+	lo->lo_min_dio_size = SECTOR_SIZE;
+	lo->lo_dio_mem_align = SECTOR_SIZE - 1;
 }
 
 static inline int is_loop_device(struct file *file)
@@ -509,7 +521,7 @@ static void loop_assign_backing_file(struct loop_device *lo, struct file *file)
 			lo->old_gfp_mask & ~(__GFP_IO | __GFP_FS));
 	if (lo->lo_backing_file->f_flags & O_DIRECT)
 		lo->lo_flags |= LO_FLAGS_DIRECT_IO;
-	lo->lo_min_dio_size = loop_query_min_dio_size(lo);
+	loop_update_dio_alignment(lo);
 }
 
 static int loop_check_backing_file(struct file *file)
@@ -940,6 +952,19 @@ static unsigned int loop_default_blocksize(struct loop_device *lo)
 	return SECTOR_SIZE;
 }
 
+static void loop_set_dma_limit(struct loop_device *lo, struct queue_limits *lim)
+{
+	/*
+	 * Direct I/O forwards the user pages to the backing file unchanged, so
+	 * track the backing's DMA alignment requirement as the mode is toggled.
+	 */
+	if (lo->lo_flags & LO_FLAGS_DIRECT_IO)
+		lim->dma_alignment = max_t(unsigned int, lo->lo_dio_mem_align,
+					   SECTOR_SIZE - 1);
+	else
+		lim->dma_alignment = SECTOR_SIZE - 1;
+}
+
 static void loop_update_limits(struct loop_device *lo, struct queue_limits *lim,
 		unsigned int bsize)
 {
@@ -961,6 +986,7 @@ static void loop_update_limits(struct loop_device *lo, struct queue_limits *lim,
 	lim->logical_block_size = bsize;
 	lim->physical_block_size = bsize;
 	lim->io_min = bsize;
+	loop_set_dma_limit(lo, lim);
 	lim->features &= ~(BLK_FEAT_WRITE_CACHE | BLK_FEAT_ROTATIONAL);
 	if (file->f_op->fsync && !(lo->lo_flags & LO_FLAGS_READ_ONLY))
 		lim->features |= BLK_FEAT_WRITE_CACHE;
@@ -1416,6 +1442,7 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg)
 {
 	bool use_dio = !!arg;
 	unsigned int memflags;
+	struct queue_limits lim;
 
 	if (lo->lo_state != Lo_bound)
 		return -ENXIO;
@@ -1434,6 +1461,9 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg)
 		lo->lo_flags |= LO_FLAGS_DIRECT_IO;
 	else
 		lo->lo_flags &= ~LO_FLAGS_DIRECT_IO;
+	lim = queue_limits_start_update(lo->lo_queue);
+	loop_set_dma_limit(lo, &lim);
+	queue_limits_commit_update(lo->lo_queue, &lim);
 	blk_mq_unfreeze_queue(lo->lo_queue, memflags);
 	return 0;
 }
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RESEND 4/5] zloop: set dma_alignment from the backing files for direct I/O
  2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
                   ` (2 preceding siblings ...)
  2026-07-20 20:10 ` [PATCH RESEND 3/5] loop: set dma_alignment from the backing file for direct I/O Keith Busch
@ 2026-07-20 20:10 ` Keith Busch
  2026-07-20 20:10 ` [PATCH RESEND 5/5] block: validate user space vectors during extraction Keith Busch
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Keith Busch @ 2026-07-20 20:10 UTC (permalink / raw)
  To: linux-block, linux-fsdevel
  Cc: dm-devel, hch, axboe, brauner, djwong, viro, Keith Busch,
	Hannes Reinecke

From: Keith Busch <kbusch@kernel.org>

Direct I/O request's use pages handed to the backing files unchanged, so
the backing's DMA alignment requirement applies. Track dio_mem_align and
advertise it as the device's dma_alignment so we communicate proper
limits and misaligned I/O is rejected here instead of reaching the
backend.

Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 drivers/block/zloop.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/block/zloop.c b/drivers/block/zloop.c
index 55eeb6aac0ea3..f97a20cfdb7ce 100644
--- a/drivers/block/zloop.c
+++ b/drivers/block/zloop.c
@@ -144,6 +144,7 @@ struct zloop_device {
 	unsigned int		nr_conv_zones;
 	unsigned int		max_open_zones;
 	unsigned int		block_size;
+	unsigned int		dio_mem_align;
 
 	spinlock_t		open_zones_lock;
 	struct list_head	open_zones_lru_list;
@@ -1037,20 +1038,30 @@ static int zloop_get_block_size(struct zloop_device *zlo,
 	struct kstat st;
 
 	/*
-	 * If the FS block size is lower than or equal to 4K, use that as the
-	 * device block size. Otherwise, fallback to the FS direct IO alignment
-	 * constraint if that is provided, and to the FS underlying device
-	 * physical block size if the direct IO alignment is unknown.
+	 * Use the dio alignment of the file system if provided.  The incoming
+	 * request's bio_vec is forwarded to the backing file unchanged, so its
+	 * required memory alignment becomes the device's dma_alignment when
+	 * used for direct-io.
 	 */
-	if (file_inode(zone->file)->i_sb->s_blocksize <= SZ_4K)
-		zlo->block_size = file_inode(zone->file)->i_sb->s_blocksize;
-	else if (!vfs_getattr(&zone->file->f_path, &st, STATX_DIOALIGN, 0) &&
-		 (st.result_mask & STATX_DIOALIGN))
+	if (!vfs_getattr(&zone->file->f_path, &st, STATX_DIOALIGN, 0) &&
+	    (st.result_mask & STATX_DIOALIGN)) {
 		zlo->block_size = st.dio_offset_align;
-	else if (sb_bdev)
+		zlo->dio_mem_align = st.dio_mem_align - 1;
+	} else if (sb_bdev) {
 		zlo->block_size = bdev_physical_block_size(sb_bdev);
-	else
+		zlo->dio_mem_align = bdev_dma_alignment(sb_bdev);
+	} else {
 		zlo->block_size = SECTOR_SIZE;
+		zlo->dio_mem_align = SECTOR_SIZE - 1;
+	}
+
+	/*
+	 * Prefer the FS block size for the device block size when it is no
+	 * larger than 4K; otherwise keep the direct I/O / physical block size
+	 * selected above.
+	 */
+	if (file_inode(zone->file)->i_sb->s_blocksize <= SZ_4K)
+		zlo->block_size = file_inode(zone->file)->i_sb->s_blocksize;
 
 	if (zlo->zone_capacity & ((zlo->block_size >> SECTOR_SHIFT) - 1)) {
 		pr_err("Zone capacity is not aligned to block size %u\n",
@@ -1279,6 +1290,10 @@ static int zloop_ctl_add(struct zloop_options *opts)
 
 	lim.physical_block_size = zlo->block_size;
 	lim.logical_block_size = zlo->block_size;
+	/* Direct I/O forwards the request pages to the backing files as-is. */
+	if (!opts->buffered_io)
+		lim.dma_alignment = max_t(unsigned int, zlo->dio_mem_align,
+					  SECTOR_SIZE - 1);
 	if (zlo->zone_append)
 		lim.max_hw_zone_append_sectors = lim.max_hw_sectors;
 	lim.max_open_zones = zlo->max_open_zones;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RESEND 5/5] block: validate user space vectors during extraction
  2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
                   ` (3 preceding siblings ...)
  2026-07-20 20:10 ` [PATCH RESEND 4/5] zloop: set dma_alignment from the backing files " Keith Busch
@ 2026-07-20 20:10 ` Keith Busch
  2026-08-05 12:46   ` Shin'ichiro Kawasaki
  2026-07-29 19:15 ` [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
  2026-07-31 14:11 ` Jens Axboe
  6 siblings, 1 reply; 21+ messages in thread
From: Keith Busch @ 2026-07-20 20:10 UTC (permalink / raw)
  To: linux-block, linux-fsdevel
  Cc: dm-devel, hch, axboe, brauner, djwong, viro, Keith Busch, stable,
	Hannes Reinecke

From: Keith Busch <kbusch@kernel.org>

The bio-based drivers don't necessarily check the alignment split, and
stacking block drivers don't always handle a misalignment detected after
submitting the bio. Validate user vectors against the device's
dma_alignment as the bio is built from the iov_iter, rejecting
misaligned early with -EINVAL.

Cc: stable@vger.kernel.org
Fixes: 5ff3f74e145a ("block: simplify direct io validity check")
Fixes: 7eac33186957 ("iomap: simplify direct io validity check")
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/bio.c          | 56 +++++++++++++++++++++++++++++++++++++++++---
 block/blk-map.c      |  2 +-
 block/fops.c         |  2 +-
 fs/iomap/direct-io.c |  1 +
 include/linux/bio.h  |  2 +-
 include/linux/uio.h  | 10 +++++++-
 lib/iov_iter.c       |  9 ++++++-
 7 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index f2a5f4d0a9672..faad41a72ac77 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1220,10 +1220,45 @@ static int bio_iov_iter_align_down(struct bio *bio, struct iov_iter *iter,
 	return 0;
 }
 
+#ifdef CONFIG_DEBUG_KERNEL
+static inline bool bio_iov_bvec_aligned(const struct bio *bio,
+					unsigned mem_align_mask)
+{
+	struct bvec_iter iter;
+	struct bio_vec bv;
+
+	/*
+	 * Correct callers never break the alignment requirements, so this
+	 * exhaustive check is only paid for in debug builds.
+	 */
+	for_each_mp_bvec(bv, bio->bi_io_vec, iter, bio->bi_iter)
+		if ((bv.bv_offset | bv.bv_len) & mem_align_mask)
+			return false;
+	return true;
+}
+#else
+static inline bool bio_iov_bvec_aligned(const struct bio *bio,
+					unsigned mem_align_mask)
+{
+	/*
+	 * We forward the bio_vec as-is, so ITER_BVEC callers must provide
+	 * segments already aligned to the device's DMA alignment. The only
+	 * unchecked user-controllable offset that reaches here is an io_uring
+	 * registered buffer where just the first segment can be unaligned
+	 * (the rest is virtually contiguous), so checking only that one is
+	 * sufficient to know if the entire vector is valid.
+	 */
+	return !(mp_bvec_iter_offset(bio->bi_io_vec, bio->bi_iter) &
+							mem_align_mask);
+}
+#endif
+
 /**
  * bio_iov_iter_get_pages - add user or kernel pages to a bio
  * @bio: bio to add pages to
  * @iter: iov iterator describing the region to be added
+ * @mem_align_mask: the mask the source address and length must be aligned to,
+ *	0 for no requirement
  * @len_align_mask: the mask to align the total size to, 0 for any length
  *
  * This takes either an iterator pointing to user memory, or one pointing to
@@ -1242,7 +1277,7 @@ static int bio_iov_iter_align_down(struct bio *bio, struct iov_iter *iter,
  * is returned only if 0 pages could be pinned.
  */
 int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
-			   unsigned len_align_mask)
+			   unsigned mem_align_mask, unsigned len_align_mask)
 {
 	iov_iter_extraction_t flags = 0;
 
@@ -1251,6 +1286,10 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
 
 	if (iov_iter_is_bvec(iter)) {
 		bio_iov_bvec_set(bio, iter);
+
+		if (!bio_iov_bvec_aligned(bio, mem_align_mask))
+			return -EINVAL;
+
 		iov_iter_advance(iter, bio->bi_iter.bi_size);
 		return 0;
 	}
@@ -1265,8 +1304,19 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
 
 		ret = iov_iter_extract_bvecs(iter, bio->bi_io_vec,
 				BIO_MAX_SIZE - bio->bi_iter.bi_size,
-				&bio->bi_vcnt, bio->bi_max_vecs, flags);
+				&bio->bi_vcnt, bio->bi_max_vecs,
+				mem_align_mask, flags);
 		if (ret <= 0) {
+			/*
+			 * A misaligned vector fails the whole I/O.  Release any
+			 * pages pinned by earlier iterations before returning
+			 * since this bio won't be submitted to release them.
+			 */
+			if (ret == -EINVAL) {
+				bio_release_pages(bio, false);
+				bio_clear_flag(bio, BIO_PAGE_PINNED);
+				bio->bi_vcnt = 0;
+			}
 			if (!bio->bi_vcnt)
 				return ret;
 			break;
@@ -1377,7 +1427,7 @@ static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter,
 		ssize_t ret;
 
 		ret = iov_iter_extract_bvecs(iter, bio->bi_io_vec + 1, len,
-				&bio->bi_vcnt, bio->bi_max_vecs - 1, 0);
+				&bio->bi_vcnt, bio->bi_max_vecs - 1, 0, 0);
 		if (ret <= 0) {
 			if (!bio->bi_vcnt) {
 				folio_put(folio);
diff --git a/block/blk-map.c b/block/blk-map.c
index 768549f19f97e..c9535efe1a913 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -274,7 +274,7 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
 	 * No alignment requirements on our part to support arbitrary
 	 * passthrough commands.
 	 */
-	ret = bio_iov_iter_get_pages(bio, iter, 0);
+	ret = bio_iov_iter_get_pages(bio, iter, 0, 0);
 	if (ret)
 		goto out_put;
 	ret = blk_rq_append_bio(rq, bio);
diff --git a/block/fops.c b/block/fops.c
index 0098a90a956e1..e519d7f43b310 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -46,7 +46,7 @@ static bool blkdev_dio_invalid(struct block_device *bdev, struct kiocb *iocb,
 static inline int blkdev_iov_iter_get_pages(struct bio *bio,
 		struct iov_iter *iter, struct block_device *bdev)
 {
-	return bio_iov_iter_get_pages(bio, iter,
+	return bio_iov_iter_get_pages(bio, iter, bdev_dma_alignment(bdev),
 			bdev_logical_block_size(bdev) - 1);
 }
 
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index b485e3b191daf..ff458aa12ae29 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -358,6 +358,7 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter,
 				iomap_max_bio_size(&iter->iomap), alignment);
 	else
 		ret = bio_iov_iter_get_pages(bio, dio->submit.iter,
+					     bdev_dma_alignment(bio->bi_bdev),
 					     alignment - 1);
 	if (unlikely(ret))
 		goto out_put_bio;
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 8f33f717b14f5..ce34ea49ef358 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -477,7 +477,7 @@ int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data,
 		size_t len, enum req_op op);
 
 int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
-		unsigned len_align_mask);
+		unsigned mem_align_mask, unsigned len_align_mask);
 
 void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter);
 void __bio_release_pages(struct bio *bio, bool mark_dirty);
diff --git a/include/linux/uio.h b/include/linux/uio.h
index a9bc5b3067e32..fe2e985d74d24 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -389,9 +389,17 @@ ssize_t iov_iter_extract_pages(struct iov_iter *i, struct page ***pages,
 			       size_t maxsize, unsigned int maxpages,
 			       iov_iter_extraction_t extraction_flags,
 			       size_t *offset0);
+/*
+ * Block-layer consumers (e.g. bio_iov_iter_get_pages()) require that the
+ * segments of an ITER_BVEC iterator are already aligned to the target device's
+ * DMA alignment, and forward them as-is.  In-kernel users that build their own
+ * bvecs must not create sub-aligned segments; iov_iter_extract_bvecs() enforces
+ * the same for the segments it extracts via @mem_align_mask.
+ */
 ssize_t iov_iter_extract_bvecs(struct iov_iter *iter, struct bio_vec *bv,
 		size_t max_size, unsigned short *nr_vecs,
-		unsigned short max_vecs, iov_iter_extraction_t extraction_flags);
+		unsigned short max_vecs, unsigned mem_align_mask,
+		iov_iter_extraction_t extraction_flags);
 
 /**
  * iov_iter_extract_will_pin - Indicate how pages from the iterator will be retained
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 273919b161617..c343075951ded 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1886,6 +1886,8 @@ static unsigned int get_contig_folio_len(struct page **pages,
  * @max_size:	maximum size to extract from @iter
  * @nr_vecs:	number of vectors in @bv (on in and output)
  * @max_vecs:	maximum vectors in @bv, including those filled before calling
+ * @mem_align_mask:	reject with -EINVAL if the source address or
+ *		length is not aligned to this mask
  * @extraction_flags: flags to qualify request
  *
  * Like iov_iter_extract_pages(), but returns physically contiguous ranges
@@ -1897,14 +1899,19 @@ static unsigned int get_contig_folio_len(struct page **pages,
  */
 ssize_t iov_iter_extract_bvecs(struct iov_iter *iter, struct bio_vec *bv,
 		size_t max_size, unsigned short *nr_vecs,
-		unsigned short max_vecs, iov_iter_extraction_t extraction_flags)
+		unsigned short max_vecs, unsigned mem_align_mask,
+		iov_iter_extraction_t extraction_flags)
 {
+	unsigned long start = (unsigned long)iter_iov_addr(iter);
 	unsigned short entries_left = max_vecs - *nr_vecs;
 	unsigned short nr_pages, i = 0;
 	size_t left, offset, len;
 	struct page **pages;
 	ssize_t size;
 
+	if ((start | iter_iov_len(iter)) & mem_align_mask)
+		return -EINVAL;
+
 	/*
 	 * Move page array up in the allocated memory for the bio vecs as far as
 	 * possible so that we can start filling biovecs from the beginning
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
                   ` (4 preceding siblings ...)
  2026-07-20 20:10 ` [PATCH RESEND 5/5] block: validate user space vectors during extraction Keith Busch
@ 2026-07-29 19:15 ` Keith Busch
  2026-07-29 19:18   ` Jens Axboe
  2026-07-31 14:11 ` Jens Axboe
  6 siblings, 1 reply; 21+ messages in thread
From: Keith Busch @ 2026-07-29 19:15 UTC (permalink / raw)
  To: Keith Busch
  Cc: linux-block, linux-fsdevel, dm-devel, hch, axboe, brauner, djwong,
	viro

On Mon, Jul 20, 2026 at 01:10:52PM -0700, Keith Busch wrote:
> This addresses the misaligned direct-io problem behind various threads:

Hi Jens, have you had a chance to look at this one yet? This addresses
previous issues with certain device mappers under direct io.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-29 19:15 ` [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
@ 2026-07-29 19:18   ` Jens Axboe
  2026-07-29 20:03     ` Keith Busch
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Axboe @ 2026-07-29 19:18 UTC (permalink / raw)
  To: Keith Busch, Keith Busch
  Cc: linux-block, linux-fsdevel, dm-devel, hch, brauner, djwong, viro

On 7/29/26 1:15 PM, Keith Busch wrote:
> On Mon, Jul 20, 2026 at 01:10:52PM -0700, Keith Busch wrote:
>> This addresses the misaligned direct-io problem behind various threads:
> 
> Hi Jens, have you had a chance to look at this one yet? This addresses
> previous issues with certain device mappers under direct io.

I they look fine, but at this point we should toss them into 7.3. Yes
I know there are regressions around this, but from 6.1x days. And the
series doesn't apply to the current block-7.2 anyway.

What do you think?

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-29 19:18   ` Jens Axboe
@ 2026-07-29 20:03     ` Keith Busch
  2026-07-29 23:34       ` Jens Axboe
  2026-07-30 11:26       ` Christoph Hellwig
  0 siblings, 2 replies; 21+ messages in thread
From: Keith Busch @ 2026-07-29 20:03 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Keith Busch, linux-block, linux-fsdevel, dm-devel, hch, brauner,
	djwong, viro

On Wed, Jul 29, 2026 at 01:18:40PM -0600, Jens Axboe wrote:
> On 7/29/26 1:15 PM, Keith Busch wrote:
> > On Mon, Jul 20, 2026 at 01:10:52PM -0700, Keith Busch wrote:
> >> This addresses the misaligned direct-io problem behind various threads:
> > 
> > Hi Jens, have you had a chance to look at this one yet? This addresses
> > previous issues with certain device mappers under direct io.
> 
> I they look fine, but at this point we should toss them into 7.3. Yes
> I know there are regressions around this, but from 6.1x days. And the
> series doesn't apply to the current block-7.2 anyway.

This series is kind of old at this point, but yes, it's not fixing a new
regression either. I'm okay if this goes to the next window, and I will
handle the stable follow-up.

Are you planning to start the for-7.3/block branch soon? I can rebase
the series if there's a conflict, and would be great to get this exposed
to linux-next.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-29 20:03     ` Keith Busch
@ 2026-07-29 23:34       ` Jens Axboe
  2026-07-30 11:26       ` Christoph Hellwig
  1 sibling, 0 replies; 21+ messages in thread
From: Jens Axboe @ 2026-07-29 23:34 UTC (permalink / raw)
  To: Keith Busch
  Cc: Keith Busch, linux-block, linux-fsdevel, dm-devel, hch, brauner,
	djwong, viro

On 7/29/26 2:03 PM, Keith Busch wrote:
> On Wed, Jul 29, 2026 at 01:18:40PM -0600, Jens Axboe wrote:
>> On 7/29/26 1:15 PM, Keith Busch wrote:
>>> On Mon, Jul 20, 2026 at 01:10:52PM -0700, Keith Busch wrote:
>>>> This addresses the misaligned direct-io problem behind various threads:
>>>
>>> Hi Jens, have you had a chance to look at this one yet? This addresses
>>> previous issues with certain device mappers under direct io.
>>
>> I they look fine, but at this point we should toss them into 7.3. Yes
>> I know there are regressions around this, but from 6.1x days. And the
>> series doesn't apply to the current block-7.2 anyway.
> 
> This series is kind of old at this point, but yes, it's not fixing a new
> regression either. I'm okay if this goes to the next window, and I will
> handle the stable follow-up.

OK good, let's do that then.

> Are you planning to start the for-7.3/block branch soon? I can rebase
> the series if there's a conflict, and would be great to get this exposed
> to linux-next.

Pushed one out - send a new version and I'll get it applied when it
shows up.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-29 20:03     ` Keith Busch
  2026-07-29 23:34       ` Jens Axboe
@ 2026-07-30 11:26       ` Christoph Hellwig
  2026-07-30 12:52         ` Keith Busch
  2026-07-30 13:25         ` Thorsten Leemhuis
  1 sibling, 2 replies; 21+ messages in thread
From: Christoph Hellwig @ 2026-07-30 11:26 UTC (permalink / raw)
  To: Keith Busch
  Cc: Jens Axboe, Keith Busch, linux-block, linux-fsdevel, dm-devel,
	hch, brauner, djwong, viro, regressions, torvalds

On Wed, Jul 29, 2026 at 02:03:07PM -0600, Keith Busch wrote:
> > > Hi Jens, have you had a chance to look at this one yet? This addresses
> > > previous issues with certain device mappers under direct io.
> > 
> > I they look fine, but at this point we should toss them into 7.3. Yes
> > I know there are regressions around this, but from 6.1x days. And the
> > series doesn't apply to the current block-7.2 anyway.
> 
> This series is kind of old at this point, but yes, it's not fixing a new
> regression either. I'm okay if this goes to the next window, and I will
> handle the stable follow-up.

Honestly, I think that'a a reall bad idea.  This is a regression in 6.18,
and while it took a while for people to hit this with their a little
more complicated lvm/md setups, it has stopped real systems from being
used.  We need to fix this ASAP.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-30 11:26       ` Christoph Hellwig
@ 2026-07-30 12:52         ` Keith Busch
  2026-07-30 16:22           ` Jens Axboe
  2026-07-30 13:25         ` Thorsten Leemhuis
  1 sibling, 1 reply; 21+ messages in thread
From: Keith Busch @ 2026-07-30 12:52 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jens Axboe, Keith Busch, linux-block, linux-fsdevel, dm-devel,
	brauner, djwong, viro, regressions, torvalds

On Thu, Jul 30, 2026 at 01:26:26PM +0200, Christoph Hellwig wrote:
> On Wed, Jul 29, 2026 at 02:03:07PM -0600, Keith Busch wrote:
> > > > Hi Jens, have you had a chance to look at this one yet? This addresses
> > > > previous issues with certain device mappers under direct io.
> > > 
> > > I they look fine, but at this point we should toss them into 7.3. Yes
> > > I know there are regressions around this, but from 6.1x days. And the
> > > series doesn't apply to the current block-7.2 anyway.
> > 
> > This series is kind of old at this point, but yes, it's not fixing a new
> > regression either. I'm okay if this goes to the next window, and I will
> > handle the stable follow-up.
> 
> Honestly, I think that'a a reall bad idea.  This is a regression in 6.18,
> and while it took a while for people to hit this with their a little
> more complicated lvm/md setups, it has stopped real systems from being
> used.  We need to fix this ASAP.

This should have gone in several weeks ago, IMO. You can most readily
hit a problem running qemu against one of those lvm setups. We're just
so late in this release cycle that I'm not pushing hard for 7.2, but I
would support that choice too.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-30 11:26       ` Christoph Hellwig
  2026-07-30 12:52         ` Keith Busch
@ 2026-07-30 13:25         ` Thorsten Leemhuis
  2026-07-30 16:23           ` Jens Axboe
  1 sibling, 1 reply; 21+ messages in thread
From: Thorsten Leemhuis @ 2026-07-30 13:25 UTC (permalink / raw)
  To: Christoph Hellwig, Keith Busch
  Cc: Jens Axboe, Keith Busch, linux-block, linux-fsdevel, dm-devel,
	brauner, djwong, viro, regressions, torvalds

On 7/30/26 13:26, Christoph Hellwig wrote:
> On Wed, Jul 29, 2026 at 02:03:07PM -0600, Keith Busch wrote:
>>>> Hi Jens, have you had a chance to look at this one yet? This addresses
>>>> previous issues with certain device mappers under direct io.
>>>
>>> I they look fine, but at this point we should toss them into 7.3. Yes
>>> I know there are regressions around this, but from 6.1x days. And the
>>> series doesn't apply to the current block-7.2 anyway.
>>
>> This series is kind of old at this point, but yes, it's not fixing a new
>> regression either. I'm okay if this goes to the next window, and I will
>> handle the stable follow-up.
> 
> Honestly, I think that'a a reall bad idea.  This is a regression in 6.18,
> and while it took a while for people to hit this with their a little
> more complicated lvm/md setups, it has stopped real systems from being
> used.  We need to fix this ASAP.
Thx for this, as I had been thinking along the same lines already and
was still considering if I wanted to speak up.

6.18 still qualifies as recent in my book, but YMMV. And it's not like
people "took forever to notice"[1], as they reported this for a while
now -- and there were a few attempts to fix this; it just took us some
time to see the full problem (@Keith: many thx for that and the fixes
for them). And some of the linked reports are quite recent, so people
really hit this.

Sure, as always there is the risk that this will cause other, bigger
regressions. Maybe that's why it's one of those situations where the
right approach is "submit this separately to Linus and let him decide",
unless of course he speaks up here.

Another reason to maybe merge this now is that Btrfs regression that
likely will only be fixed next week[2] -- so we already risk needing an
rc8 anyway.

Ciao, Thorsten

[1]
https://lore.kernel.org/all/CAHk-=wis_qQy4oDNynNKi5b7Qhosmxtoj1jxo5wmB6SRUwQUBQ@mail.gmail.com/
[2]
https://lore.kernel.org/linux-btrfs/69d0043e0f6a3d17048dfde857127ab0bf331154.1785190866.git.boris@bur.io/



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-30 12:52         ` Keith Busch
@ 2026-07-30 16:22           ` Jens Axboe
  0 siblings, 0 replies; 21+ messages in thread
From: Jens Axboe @ 2026-07-30 16:22 UTC (permalink / raw)
  To: Keith Busch, Christoph Hellwig
  Cc: Keith Busch, linux-block, linux-fsdevel, dm-devel, brauner,
	djwong, viro, regressions, torvalds

On 7/30/26 6:52 AM, Keith Busch wrote:
> On Thu, Jul 30, 2026 at 01:26:26PM +0200, Christoph Hellwig wrote:
>> On Wed, Jul 29, 2026 at 02:03:07PM -0600, Keith Busch wrote:
>>>>> Hi Jens, have you had a chance to look at this one yet? This addresses
>>>>> previous issues with certain device mappers under direct io.
>>>>
>>>> I they look fine, but at this point we should toss them into 7.3. Yes
>>>> I know there are regressions around this, but from 6.1x days. And the
>>>> series doesn't apply to the current block-7.2 anyway.
>>>
>>> This series is kind of old at this point, but yes, it's not fixing a new
>>> regression either. I'm okay if this goes to the next window, and I will
>>> handle the stable follow-up.
>>
>> Honestly, I think that'a a reall bad idea.  This is a regression in 6.18,
>> and while it took a while for people to hit this with their a little
>> more complicated lvm/md setups, it has stopped real systems from being
>> used.  We need to fix this ASAP.
> 
> This should have gone in several weeks ago, IMO. You can most readily
> hit a problem running qemu against one of those lvm setups. We're just
> so late in this release cycle that I'm not pushing hard for 7.2, but I
> would support that choice too.

Exactly, it's been floating for a bit, and the last week is surely on
me. But merging at the time it was posted would've been late for fairly
substantial changes.

Hence why I think 7.3 is just the better choice. We're talking weeks in
difference on when it gets to stable anyway, which is what matters.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-30 13:25         ` Thorsten Leemhuis
@ 2026-07-30 16:23           ` Jens Axboe
  2026-07-30 16:46             ` Linus Torvalds
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Axboe @ 2026-07-30 16:23 UTC (permalink / raw)
  To: Thorsten Leemhuis, Christoph Hellwig, Keith Busch
  Cc: Keith Busch, linux-block, linux-fsdevel, dm-devel, brauner,
	djwong, viro, regressions, torvalds

On 7/30/26 7:25 AM, Thorsten Leemhuis wrote:
> On 7/30/26 13:26, Christoph Hellwig wrote:
>> On Wed, Jul 29, 2026 at 02:03:07PM -0600, Keith Busch wrote:
>>>>> Hi Jens, have you had a chance to look at this one yet? This addresses
>>>>> previous issues with certain device mappers under direct io.
>>>>
>>>> I they look fine, but at this point we should toss them into 7.3. Yes
>>>> I know there are regressions around this, but from 6.1x days. And the
>>>> series doesn't apply to the current block-7.2 anyway.
>>>
>>> This series is kind of old at this point, but yes, it's not fixing a new
>>> regression either. I'm okay if this goes to the next window, and I will
>>> handle the stable follow-up.
>>
>> Honestly, I think that'a a reall bad idea.  This is a regression in 6.18,
>> and while it took a while for people to hit this with their a little
>> more complicated lvm/md setups, it has stopped real systems from being
>> used.  We need to fix this ASAP.
> Thx for this, as I had been thinking along the same lines already and
> was still considering if I wanted to speak up.
> 
> 6.18 still qualifies as recent in my book, but YMMV. And it's not like
> people "took forever to notice"[1], as they reported this for a while
> now -- and there were a few attempts to fix this; it just took us some
> time to see the full problem (@Keith: many thx for that and the fixes
> for them). And some of the linked reports are quite recent, so people
> really hit this.
> 
> Sure, as always there is the risk that this will cause other, bigger
> regressions. Maybe that's why it's one of those situations where the
> right approach is "submit this separately to Linus and let him decide",
> unless of course he speaks up here.

Sorry that's nonsense, because how is Linus going to make that call if
we can't. It's on us/me to make that call. We're not first-timers around
here, we've been around and know how to make the call that we can stand
by.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-30 16:23           ` Jens Axboe
@ 2026-07-30 16:46             ` Linus Torvalds
  0 siblings, 0 replies; 21+ messages in thread
From: Linus Torvalds @ 2026-07-30 16:46 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Thorsten Leemhuis, Christoph Hellwig, Keith Busch, Keith Busch,
	linux-block, linux-fsdevel, dm-devel, brauner, djwong, viro,
	regressions

On Thu, 30 Jul 2026 at 09:23, Jens Axboe <axboe@kernel.dk> wrote:
>
> Sorry that's nonsense, because how is Linus going to make that call if
> we can't.

There's not a big enough thumbs up emoji in the whole universe for this.

          Linus

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 0/5] block: validate direct I/O memory alignment
  2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
                   ` (5 preceding siblings ...)
  2026-07-29 19:15 ` [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
@ 2026-07-31 14:11 ` Jens Axboe
  6 siblings, 0 replies; 21+ messages in thread
From: Jens Axboe @ 2026-07-31 14:11 UTC (permalink / raw)
  To: linux-block, linux-fsdevel, Keith Busch
  Cc: dm-devel, hch, brauner, djwong, viro, Keith Busch


On Mon, 20 Jul 2026 13:10:52 -0700, Keith Busch wrote:
> Resending in case this got lost.
> 
> This addresses the misaligned direct-io problem behind various threads:
> 
>  https://lore.kernel.org/linux-xfs/20260610145218.141369-1-cem@kernel.org/
>  https://lore.kernel.org/all/CAC_j7i1R7oy+nRhxEjCTba=DUgn02w9X+p94DCu0aHv5+5tKnQ@mail.gmail.com/
>  https://lore.kernel.org/linux-block/ai7rnH20IYeSmY8s@gallifrey/
>  https://lore.kernel.org/linux-block/20260616154009.2123183-1-kbusch@meta.com/
> 
> [...]

Applied, thanks!

[1/5] block: use blkdev_iov_iter_get_pages status for errors
      commit: 75ae18ca942674f9d5b55d7e8a2975485125f715
[2/5] block: fix dio leak on metadata mapping error
      commit: 702a2a9f3dfe066a7481698c858371112f3cb697
[3/5] loop: set dma_alignment from the backing file for direct I/O
      commit: 6c8dec275ccc35e8f86cb9287283d31c5d8e9ab7
[4/5] zloop: set dma_alignment from the backing files for direct I/O
      commit: c5059c1af2bd22bc1435b99d27d800164162cb72
[5/5] block: validate user space vectors during extraction
      commit: 14b007e178811db72fbb1ebb3535160db6ec1e6a

Best regards,
-- 
Jens Axboe




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 5/5] block: validate user space vectors during extraction
  2026-07-20 20:10 ` [PATCH RESEND 5/5] block: validate user space vectors during extraction Keith Busch
@ 2026-08-05 12:46   ` Shin'ichiro Kawasaki
  2026-08-06  8:03     ` Shin'ichiro Kawasaki
  0 siblings, 1 reply; 21+ messages in thread
From: Shin'ichiro Kawasaki @ 2026-08-05 12:46 UTC (permalink / raw)
  To: Keith Busch
  Cc: linux-block, linux-fsdevel, dm-devel, hch, axboe, brauner, djwong,
	viro, Keith Busch, stable, Hannes Reinecke, 0wnerD1ed

Cc+: 0wnerD1ed

On Jul 20, 2026 / 13:10, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
> 
> The bio-based drivers don't necessarily check the alignment split, and
> stacking block drivers don't always handle a misalignment detected after
> submitting the bio. Validate user vectors against the device's
> dma_alignment as the bio is built from the iov_iter, rejecting
> misaligned early with -EINVAL.

Recently, the new test case block/045 was added to blkests through a GitHub PR
[1]. The test case passes with the Linux master branch tags v7.2-rcX. Today, I
found that it fails with block/for-next branch tip [2]. I bisected and found
that this patch triggers the failure.

0wnerDied, Keith, may I ask your help to resolve the failure? I'm guessing
the test case needs to care device's dma alignment, but not so sure.


[1] https://github.com/linux-blktests/blktests/pull/251

[2] failure log of block/045

block/045 (test direct I/O full-trim bvec alignment)         [failed]
    runtime  0.550s  ...  0.630s
    --- tests/block/045.out     2026-08-03 19:26:40.407053612 +0900
    +++ /home/shin/Blktests/blktests/results/nodev/block/045.out.bad    2026-08-05 20:48:33.366932845 +0900
    @@ -1,2 +1,4 @@
     Running block/045
    +bio-full-trim: pread returned -1 (errno 22)
    +bio-full-trim helper failed
     Test complete
block/045 (zoned) (test direct I/O full-trim bvec alignment) [failed]
    runtime  0.578s  ...  0.636s
    --- tests/block/045.out     2026-08-03 19:26:40.407053612 +0900
    +++ /home/shin/Blktests/blktests/results/nodev_zoned/block/045.out.bad      2026-08-05 20:48:34.550929436 +0900
    @@ -1,2 +1,4 @@
     Running block/045
    +bio-full-trim: pread returned -1 (errno 22)
    +bio-full-trim helper failed
     Test complete

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 5/5] block: validate user space vectors during extraction
  2026-08-05 12:46   ` Shin'ichiro Kawasaki
@ 2026-08-06  8:03     ` Shin'ichiro Kawasaki
  2026-08-06  8:29       ` 0wnerD1ed
  0 siblings, 1 reply; 21+ messages in thread
From: Shin'ichiro Kawasaki @ 2026-08-06  8:03 UTC (permalink / raw)
  To: Keith Busch
  Cc: linux-block, linux-fsdevel, dm-devel, hch, axboe, brauner, djwong,
	viro, Keith Busch, stable, Hannes Reinecke, 0wnerD1ed

On Aug 05, 2026 / 21:46, Shin'ichiro Kawasaki wrote:
> Cc+: 0wnerD1ed
> 
> On Jul 20, 2026 / 13:10, Keith Busch wrote:
> > From: Keith Busch <kbusch@kernel.org>
> > 
> > The bio-based drivers don't necessarily check the alignment split, and
> > stacking block drivers don't always handle a misalignment detected after
> > submitting the bio. Validate user vectors against the device's
> > dma_alignment as the bio is built from the iov_iter, rejecting
> > misaligned early with -EINVAL.
> 
> Recently, the new test case block/045 was added to blkests through a GitHub PR
> [1]. The test case passes with the Linux master branch tags v7.2-rcX. Today, I
> found that it fails with block/for-next branch tip [2]. I bisected and found
> that this patch triggers the failure.
> 
> 0wnerDied, Keith, may I ask your help to resolve the failure? I'm guessing
> the test case needs to care device's dma alignment, but not so sure.

I took a closer look. I modified the test case to respect the dma alignment [*],
and now the test case passes. This approach looks working. Will post the change
as a formal patch for review.

[*] fix trial patch for blktests

diff --git a/src/bio-full-trim.c b/src/bio-full-trim.c
index e304b2c..7cea3f9 100644
--- a/src/bio-full-trim.c
+++ b/src/bio-full-trim.c
@@ -12,20 +12,38 @@
 #include <sys/mman.h>
 #include <unistd.h>
 
+int msb(unsigned int v)
+{
+	unsigned int b = 0;
+
+	while (v >>= 1)
+		b++;
+
+	return b;
+}
+
 int main(int argc, char **argv)
 {
 	unsigned int block_size;
 	unsigned char *p;
 	long page_size;
+	unsigned int dma_alignment;
+	unsigned int dma_aligned_offset;
 	ssize_t ret;
 	int fd;
 
-	if (argc != 2)
+	if (argc != 3)
 		return EXIT_FAILURE;
+
 	page_size = sysconf(_SC_PAGESIZE);
 	if (page_size <= 0)
 		errx(EXIT_FAILURE, "invalid page size");
 
+	dma_alignment = atoi(argv[2]);
+	dma_aligned_offset = 1 << (msb(dma_alignment) + 1);
+	if (dma_aligned_offset >= page_size)
+		err(EXIT_FAILURE, "unexpected dma_alignment");
+
 	fd = open(argv[1], O_RDONLY | O_DIRECT);
 	if (fd < 0)
 		err(EXIT_FAILURE, "open %s", argv[1]);
@@ -40,7 +58,7 @@ int main(int argc, char **argv)
 		err(EXIT_FAILURE, "mprotect");
 
 	errno = 0;
-	ret = pread(fd, p + page_size - 1, block_size, 0);
+	ret = pread(fd, p + page_size - dma_aligned_offset, block_size, 0);
 	if (ret == -1 && errno == EFAULT)
 		return EXIT_SUCCESS;
 	errx(EXIT_FAILURE, "pread returned %zd (errno %d)", ret, errno);
diff --git a/tests/block/045 b/tests/block/045
index 65bfcb9..6e112b6 100755
--- a/tests/block/045
+++ b/tests/block/045
@@ -25,7 +25,8 @@ test() {
 		return 1
 	fi
 
-	if ! src/bio-full-trim /dev/nullb1; then
+	if ! src/bio-full-trim /dev/nullb1 \
+	     $(< /sys/block/nullb1/queue/dma_alignment); then
 		echo "bio-full-trim helper failed"
 	fi
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 5/5] block: validate user space vectors during extraction
  2026-08-06  8:03     ` Shin'ichiro Kawasaki
@ 2026-08-06  8:29       ` 0wnerD1ed
  2026-08-06  9:54         ` Shin'ichiro Kawasaki
  0 siblings, 1 reply; 21+ messages in thread
From: 0wnerD1ed @ 2026-08-06  8:29 UTC (permalink / raw)
  To: Shin'ichiro Kawasaki
  Cc: Keith Busch, linux-block, linux-fsdevel, dm-devel, hch, axboe,
	brauner, djwong, viro, Keith Busch, stable, Hannes Reinecke

On Aug 06, 2026 / 16:04, Shin'ichiro Kawasaki wrote:
> I took a closer look. I modified the test case to respect the dma alignment [*],
> and now the test case passes. This approach looks working. Will post the change
> as a formal patch for review.

Sorry for the slow reply, I have been busy lately.

Thanks for chasing this down. The test is mine and its assumption is
wrong, not the kernel, src/bio-full-trim puts the destination at
p + page_size - 1, and null_blk advertises dma_alignment = 1 since
commit 3451cf34f51b ("null_blk: allow byte aligned memory offsets"),
so iov_iter_extract_bvecs() now rejects that odd address before
anything is extracted and bio_iov_iter_align_down() is never reached.
That restores the behaviour we had until 5ff3f74e145a ("block:
simplify direct io validity check"), so the test is what has to
respect dma_alignment. Your approach is the right one.

One problem in the trial patch, the guard has to be against the
logical block size, not the page size. What the test needs is a
fragment that bio_iov_iter_align_down() removes completely, i.e. one
smaller than the block size, and the read has to reach the PROT_NONE
page. With dma_alignment = 511 and a 512 byte block size (the block
layer default for drivers that do not set dma_alignment),
dma_aligned_offset becomes 512, which is below page_size and passes
the check, but the read then lies entirely within the first page,
succeeds, and the helper reports

      pread returned 512 (errno 0)

instead of taking the "unexpected dma_alignment" exit. block/045 only
uses null_blk so this cannot bite today, but the check does not do
what it intends. block_size comes from BLKSSZGET, so it also has to
move below that ioctl:

      if (dma_aligned_offset >= block_size)
              errx(EXIT_FAILURE,
                   "unexpected dma_alignment %u for block size %u",
                   dma_alignment, block_size);

While there, err() should be errx(), errno is not meaningful at that
point.

I am short on time at the moment, so please go ahead with the formal
posting. I will send a Tested-by once I get a chance to run it.

Regards,

0wnerD1ed
l7z@0b1t.tech

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RESEND 5/5] block: validate user space vectors during extraction
  2026-08-06  8:29       ` 0wnerD1ed
@ 2026-08-06  9:54         ` Shin'ichiro Kawasaki
  0 siblings, 0 replies; 21+ messages in thread
From: Shin'ichiro Kawasaki @ 2026-08-06  9:54 UTC (permalink / raw)
  To: 0wnerD1ed
  Cc: Keith Busch, linux-block, linux-fsdevel, dm-devel, hch, axboe,
	brauner, djwong, viro, Keith Busch, stable, Hannes Reinecke

On Aug 06, 2026 / 16:29, 0wnerD1ed wrote:
> On Aug 06, 2026 / 16:04, Shin'ichiro Kawasaki wrote:
> > I took a closer look. I modified the test case to respect the dma alignment [*],
> > and now the test case passes. This approach looks working. Will post the change
> > as a formal patch for review.
> 
> Sorry for the slow reply, I have been busy lately.
> 
> Thanks for chasing this down. The test is mine and its assumption is
> wrong, not the kernel, src/bio-full-trim puts the destination at
> p + page_size - 1, and null_blk advertises dma_alignment = 1 since
> commit 3451cf34f51b ("null_blk: allow byte aligned memory offsets"),
> so iov_iter_extract_bvecs() now rejects that odd address before
> anything is extracted and bio_iov_iter_align_down() is never reached.
> That restores the behaviour we had until 5ff3f74e145a ("block:
> simplify direct io validity check"), so the test is what has to
> respect dma_alignment. Your approach is the right one.

Good, thanks for the confirmation.

> 
> One problem in the trial patch, the guard has to be against the
> logical block size, not the page size. What the test needs is a
> fragment that bio_iov_iter_align_down() removes completely, i.e. one
> smaller than the block size, and the read has to reach the PROT_NONE
> page. With dma_alignment = 511 and a 512 byte block size (the block
> layer default for drivers that do not set dma_alignment),
> dma_aligned_offset becomes 512, which is below page_size and passes
> the check, but the read then lies entirely within the first page,
> succeeds, and the helper reports
> 
>       pread returned 512 (errno 0)
> 
> instead of taking the "unexpected dma_alignment" exit. block/045 only
> uses null_blk so this cannot bite today, but the check does not do
> what it intends. block_size comes from BLKSSZGET, so it also has to
> move below that ioctl:
> 
>       if (dma_aligned_offset >= block_size)
>               errx(EXIT_FAILURE,
>                    "unexpected dma_alignment %u for block size %u",
>                    dma_alignment, block_size);
> 
> While there, err() should be errx(), errno is not meaningful at that
> point.

Yep, I reflected this change to the patch.

> 
> I am short on time at the moment, so please go ahead with the formal
> posting. I will send a Tested-by once I get a chance to run it.

Sure, I have posted the patch. Thanks.

https://lore.kernel.org/linux-block/20260806094218.2077413-1-shinichiro.kawasaki@wdc.com/

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-08-06  9:56 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 20:10 [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
2026-07-20 20:10 ` [PATCH RESEND 1/5] block: use blkdev_iov_iter_get_pages status for errors Keith Busch
2026-07-20 20:10 ` [PATCH RESEND 2/5] block: fix dio leak on metadata mapping error Keith Busch
2026-07-20 20:10 ` [PATCH RESEND 3/5] loop: set dma_alignment from the backing file for direct I/O Keith Busch
2026-07-20 20:10 ` [PATCH RESEND 4/5] zloop: set dma_alignment from the backing files " Keith Busch
2026-07-20 20:10 ` [PATCH RESEND 5/5] block: validate user space vectors during extraction Keith Busch
2026-08-05 12:46   ` Shin'ichiro Kawasaki
2026-08-06  8:03     ` Shin'ichiro Kawasaki
2026-08-06  8:29       ` 0wnerD1ed
2026-08-06  9:54         ` Shin'ichiro Kawasaki
2026-07-29 19:15 ` [PATCH RESEND 0/5] block: validate direct I/O memory alignment Keith Busch
2026-07-29 19:18   ` Jens Axboe
2026-07-29 20:03     ` Keith Busch
2026-07-29 23:34       ` Jens Axboe
2026-07-30 11:26       ` Christoph Hellwig
2026-07-30 12:52         ` Keith Busch
2026-07-30 16:22           ` Jens Axboe
2026-07-30 13:25         ` Thorsten Leemhuis
2026-07-30 16:23           ` Jens Axboe
2026-07-30 16:46             ` Linus Torvalds
2026-07-31 14:11 ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox