[RFC PATCH v2 2/8] iomap: add dma-buf direct I/O guards

From: Mengmeng Zhao

Date: Fri Nov 13 2026 - 05:18:11 EST


From: Nitesh Shetty <nj.shetty@xxxxxxxxxxx>

Direct I/O copies data from the CPU in four places, zero-filling
holes, inline data, bounce pages and integrity metadata. A dma-buf
iterator has no pages behind it, so refuse it there.

Reads that encounter a hole or unwritten extent therefore return
-EOPNOTSUPP for the entire operation, even if I/O for an earlier
mapped extent was already submitted.

Signed-off-by: Nitesh Shetty <nj.shetty@xxxxxxxxxxx>
Signed-off-by: Anuj Gupta <anuj20.g@xxxxxxxxxxx>
Signed-off-by: Mengmeng Zhao <zhaomengmeng@xxxxxxxxxx>
Signed-off-by: Li Wang <liwang@xxxxxxxxxx>
---
fs/iomap/direct-io.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index ad041ac3252a..4a2b0f9df5a7 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -425,6 +425,11 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
unsigned int alignment;
ssize_t ret = 0;

+ /* integrity metadata is generated from the data pages */
+ if (iov_iter_is_dmabuf_map(dio->submit.iter) &&
+ (iomap->flags & IOMAP_F_INTEGRITY))
+ return -EOPNOTSUPP;
+
/*
* File systems that write out of place and always allocate new blocks
* need each bio to be block aligned as that's the unit of allocation.
@@ -589,7 +594,13 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)

static int iomap_dio_hole_iter(struct iomap_iter *iter, struct iomap_dio *dio)
{
- loff_t copied = iov_iter_zero(iomap_length(iter), dio->submit.iter);
+ loff_t copied;
+
+ /* zero-filling walks the data pages */
+ if (iov_iter_is_dmabuf_map(dio->submit.iter))
+ return -EOPNOTSUPP;
+
+ copied = iov_iter_zero(iomap_length(iter), dio->submit.iter);

if (dio->flags & IOMAP_DIO_FSBLOCK_ALIGNED) {
loff_t aligned_copied = round_down(copied,
@@ -619,6 +630,10 @@ static int iomap_dio_inline_iter(struct iomap_iter *iomi, struct iomap_dio *dio)
loff_t pos = iomi->pos;
u64 copied;

+ /* inline data is copied from the CPU */
+ if (iov_iter_is_dmabuf_map(iter))
+ return -EOPNOTSUPP;
+
if (WARN_ON_ONCE(!inline_data))
return -EIO;

@@ -717,6 +732,10 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
if (!iomi.len)
return NULL;

+ /* bouncing copies the data from the CPU */
+ if (iov_iter_is_dmabuf_map(iter) && (dio_flags & IOMAP_DIO_BOUNCE))
+ return ERR_PTR(-EOPNOTSUPP);
+
dio = kmalloc_obj(*dio);
if (!dio)
return ERR_PTR(-ENOMEM);
--
2.43.0