Linux filesystem development
 help / color / mirror / Atom feed
* [RFC 0/4] fs: support dma-buf backed direct I/O
@ 2026-10-16  9:19 Anuj Gupta
  2026-10-16  9:19 ` [RFC 1/4] block: factor out bdev_init_dma_buf_io_ctx() Anuj Gupta
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Anuj Gupta @ 2026-10-16  9:19 UTC (permalink / raw)
  To: asml.silence, hch, djwong, cem, brauner, axboe
  Cc: linux-block, linux-xfs, linux-fsdevel, joshi.k, anuj20.g,
	nj.shetty

This series lets an application register a dma-buf against a file,
so reads and writes go directly to the device as dma-buf backed
bios with no per-command DMA mapping.

This series builds on Pavel Begunkov's dma-buf block support v11,
https://lore.kernel.org/all/cover.1791975048.git.asml.silence@gmail.com/
which is queued in Jens Axboe's tree:
https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git/log/?h=for-7.4/io_uring-dmabuf

A separate kernel tree is present here:
https://github.com/anuj7781/linux-kernel/tree/anuj/fs-dmabuf-rfc-v11-desc-v2

Nitesh Shetty (4):
  block: factor out bdev_init_dma_buf_io_ctx()
  block: refuse a dma-buf bio for a disk the buffer was not registered
    on
  iomap: add dma-buf direct I/O guards and registration helper
  xfs: support dma-buf registered buffers for direct I/O

 block/bio.c                | 15 +++++++++++++++
 block/fops.c               | 19 +++++++++++++++----
 fs/iomap/direct-io.c       | 31 ++++++++++++++++++++++++++++++-
 fs/xfs/xfs_file.c          | 30 ++++++++++++++++++++++++++++++
 include/linux/blkdev.h     |  3 +++
 include/linux/dma-buf-io.h |  2 ++
 include/linux/iomap.h      |  3 +++
 7 files changed, 98 insertions(+), 5 deletions(-)

-- 
2.43.0


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

* [RFC 1/4] block: factor out bdev_init_dma_buf_io_ctx()
  2026-10-16  9:19 [RFC 0/4] fs: support dma-buf backed direct I/O Anuj Gupta
@ 2026-10-16  9:19 ` Anuj Gupta
  2026-10-16  9:23   ` Christoph Hellwig
  2026-10-16  9:19 ` [RFC 2/4] block: refuse a dma-buf bio for a disk the buffer was not registered on Anuj Gupta
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Anuj Gupta @ 2026-10-16  9:19 UTC (permalink / raw)
  To: asml.silence, hch, djwong, cem, brauner, axboe
  Cc: linux-block, linux-xfs, linux-fsdevel, joshi.k, anuj20.g,
	nj.shetty

From: Nitesh Shetty <nj.shetty@samsung.com>

Factor the checks and driver setup into an exported helper that takes
an explicit block device, so filesystems can initialize a dma-buf I/O
context for the device backing a regular file. The block-device file
operation becomes a wrapper using file_bdev(), so its behavior is
unchanged.

Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
---
 block/fops.c           | 12 +++++++++---
 include/linux/blkdev.h |  3 +++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/block/fops.c b/block/fops.c
index 49ae0302f123..18a755f6e0b0 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -934,10 +934,9 @@ static int blkdev_mmap_prepare(struct vm_area_desc *desc)
 	return generic_file_mmap_prepare(desc);
 }
 
-static int blkdev_init_dma_buf_io_ctx(struct file *file,
-				      struct dma_buf_io_ctx *ctx)
+int bdev_init_dma_buf_io_ctx(struct file *file, struct block_device *bdev,
+			     struct dma_buf_io_ctx *ctx)
 {
-	struct block_device *bdev = file_bdev(file);
 	struct gendisk *disk = bdev->bd_disk;
 
 	if (!(file->f_flags & O_DIRECT))
@@ -948,6 +947,13 @@ static int blkdev_init_dma_buf_io_ctx(struct file *file,
 		return -EOPNOTSUPP;
 	return disk->fops->init_dma_buf_io_ctx(bdev, ctx);
 }
+EXPORT_SYMBOL_GPL(bdev_init_dma_buf_io_ctx);
+
+static int blkdev_init_dma_buf_io_ctx(struct file *file,
+				      struct dma_buf_io_ctx *ctx)
+{
+	return bdev_init_dma_buf_io_ctx(file, file_bdev(file), ctx);
+}
 
 const struct file_operations def_blk_fops = {
 	.open		= blkdev_open,
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2d555a992e75..a0abdf94e7d6 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1609,6 +1609,9 @@ struct block_device_operations {
 	int (*alternative_gpt_sector)(struct gendisk *disk, sector_t *sector);
 };
 
+int bdev_init_dma_buf_io_ctx(struct file *file, struct block_device *bdev,
+			     struct dma_buf_io_ctx *ctx);
+
 #ifdef CONFIG_COMPAT
 extern int blkdev_compat_ptr_ioctl(struct block_device *, blk_mode_t,
 				      unsigned int, unsigned long);
-- 
2.43.0


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

* [RFC 2/4] block: refuse a dma-buf bio for a disk the buffer was not registered on
  2026-10-16  9:19 [RFC 0/4] fs: support dma-buf backed direct I/O Anuj Gupta
  2026-10-16  9:19 ` [RFC 1/4] block: factor out bdev_init_dma_buf_io_ctx() Anuj Gupta
@ 2026-10-16  9:19 ` Anuj Gupta
  2026-10-16  9:24   ` Christoph Hellwig
  2026-10-16  9:19 ` [RFC 3/4] iomap: add dma-buf direct I/O guards and registration helper Anuj Gupta
  2026-10-16  9:19 ` [RFC 4/4] xfs: support dma-buf registered buffers for direct I/O Anuj Gupta
  3 siblings, 1 reply; 9+ messages in thread
From: Anuj Gupta @ 2026-10-16  9:19 UTC (permalink / raw)
  To: asml.silence, hch, djwong, cem, brauner, axboe
  Cc: linux-block, linux-xfs, linux-fsdevel, joshi.k, anuj20.g,
	nj.shetty

From: Nitesh Shetty <nj.shetty@samsung.com>

A registered dma-buf map belongs to the device it was mapped for.
The device backing a file can change after registration. Record
the registered disk's dev_t at init and refuse a bio that targets
a different one.

Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
---
 block/bio.c                | 15 +++++++++++++++
 block/fops.c               |  7 ++++++-
 include/linux/dma-buf-io.h |  2 ++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/block/bio.c b/block/bio.c
index 795b88e4a994..b9e5c73cd3d1 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -19,6 +19,7 @@
 #include <linux/blk-crypto.h>
 #include <linux/xarray.h>
 #include <linux/kmemleak.h>
+#include <linux/dma-buf-io.h>
 
 #include <trace/events/block.h>
 #include "blk.h"
@@ -1269,6 +1270,17 @@ static inline bool bio_iov_bvec_aligned(const struct bio *bio,
 }
 #endif
 
+/*
+ * A dma-buf map is only valid for the disk it was registered on, but
+ * the device backing a file can change after the registration.
+ */
+static bool bio_dmabuf_map_valid(const struct bio *bio,
+				 const struct iov_iter *iter)
+{
+	return iter->dmabuf_map->ctx->registered_devt ==
+		disk_devt(bio->bi_bdev->bd_disk);
+}
+
 /**
  * bio_iov_iter_get_pages - add user or kernel pages to a bio
  * @bio: bio to add pages to
@@ -1300,6 +1312,9 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
 	if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
 		return -EIO;
 
+	if (iov_iter_is_dmabuf_map(iter) && !bio_dmabuf_map_valid(bio, iter))
+		return -EXDEV;
+
 	if (bio_iov_iter_set(bio, iter)) {
 		if (iov_iter_is_bvec(iter) &&
 		    !bio_iov_bvec_aligned(bio, mem_align_mask))
diff --git a/block/fops.c b/block/fops.c
index 18a755f6e0b0..b36dde10a4ac 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -19,6 +19,7 @@
 #include <linux/iomap.h>
 #include <linux/module.h>
 #include <linux/io_uring/cmd.h>
+#include <linux/dma-buf-io.h>
 #include "blk.h"
 
 static inline struct inode *bdev_file_inode(struct file *file)
@@ -938,6 +939,7 @@ int bdev_init_dma_buf_io_ctx(struct file *file, struct block_device *bdev,
 			     struct dma_buf_io_ctx *ctx)
 {
 	struct gendisk *disk = bdev->bd_disk;
+	int ret;
 
 	if (!(file->f_flags & O_DIRECT))
 		return -EINVAL;
@@ -945,7 +947,10 @@ int bdev_init_dma_buf_io_ctx(struct file *file, struct block_device *bdev,
 		return -EOPNOTSUPP;
 	if (bdev_has_integrity_csum(bdev))
 		return -EOPNOTSUPP;
-	return disk->fops->init_dma_buf_io_ctx(bdev, ctx);
+	ret = disk->fops->init_dma_buf_io_ctx(bdev, ctx);
+	if (!ret)
+		ctx->registered_devt = disk_devt(disk);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(bdev_init_dma_buf_io_ctx);
 
diff --git a/include/linux/dma-buf-io.h b/include/linux/dma-buf-io.h
index b9bbeca1744f..d42a79f2ac9b 100644
--- a/include/linux/dma-buf-io.h
+++ b/include/linux/dma-buf-io.h
@@ -50,6 +50,8 @@ struct dma_buf_io_ctx {
 
 	void					*dev_priv;
 	const struct dma_buf_io_ops		*dev_ops;
+
+	dev_t					registered_devt;
 };
 
 int dma_buf_io_ctx_create(struct file *file,
-- 
2.43.0


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

* [RFC 3/4] iomap: add dma-buf direct I/O guards and registration helper
  2026-10-16  9:19 [RFC 0/4] fs: support dma-buf backed direct I/O Anuj Gupta
  2026-10-16  9:19 ` [RFC 1/4] block: factor out bdev_init_dma_buf_io_ctx() Anuj Gupta
  2026-10-16  9:19 ` [RFC 2/4] block: refuse a dma-buf bio for a disk the buffer was not registered on Anuj Gupta
@ 2026-10-16  9:19 ` Anuj Gupta
  2026-10-16  9:26   ` Christoph Hellwig
  2026-10-16  9:19 ` [RFC 4/4] xfs: support dma-buf registered buffers for direct I/O Anuj Gupta
  3 siblings, 1 reply; 9+ messages in thread
From: Anuj Gupta @ 2026-10-16  9:19 UTC (permalink / raw)
  To: asml.silence, hch, djwong, cem, brauner, axboe
  Cc: linux-block, linux-xfs, linux-fsdevel, joshi.k, anuj20.g,
	nj.shetty

From: Nitesh Shetty <nj.shetty@samsung.com>

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

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.

Also add iomap_file_init_dma_buf_io_ctx(), so filesystems can register
without open-coding the DAX check. The filesystem picks the device,
iomap does the rest.

Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
---
 fs/iomap/direct-io.c  | 31 ++++++++++++++++++++++++++++++-
 include/linux/iomap.h |  3 +++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index 8b4039d16ce8..fc40f4367ee7 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -427,6 +427,10 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
 	unsigned int alignment;
 	ssize_t ret = 0;
 
+	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.
@@ -595,7 +599,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 length = iov_iter_zero(iomap_length(iter), dio->submit.iter);
+	loff_t length;
+
+	/* a device mapping cannot be zeroed from the CPU */
+	if (iov_iter_is_dmabuf_map(dio->submit.iter))
+		return -EOPNOTSUPP;
+
+	length = iov_iter_zero(iomap_length(iter), dio->submit.iter);
 
 	dio->size += length;
 	if (!length)
@@ -612,6 +622,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, which a device mapping bypasses */
+	if (iov_iter_is_dmabuf_map(iter))
+		return -EOPNOTSUPP;
+
 	if (WARN_ON_ONCE(!inline_data))
 		return -EIO;
 
@@ -710,6 +724,10 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
 	if (!iomi.len)
 		return NULL;
 
+	/* bouncing copies the data from the CPU, which a device mapping bypasses */
+	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);
@@ -915,6 +933,17 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
 }
 EXPORT_SYMBOL_GPL(iomap_dio_rw);
 
+int iomap_file_init_dma_buf_io_ctx(struct file *file, struct block_device *bdev,
+				   struct dma_buf_io_ctx *ctx)
+{
+	struct inode *inode = file_inode(file);
+
+	if (IS_DAX(inode))
+		return -EOPNOTSUPP;
+	return bdev_init_dma_buf_io_ctx(file, bdev, ctx);
+}
+EXPORT_SYMBOL_GPL(iomap_file_init_dma_buf_io_ctx);
+
 struct iomap_dio_simple {
 	struct kiocb		*iocb;
 	size_t			size;
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index bc7ae6327dbf..ce97df81c644 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -682,6 +682,9 @@ struct iomap_dio *__iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
 ssize_t iomap_dio_complete(struct iomap_dio *dio);
 void iomap_dio_bio_end_io(struct bio *bio);
 
+int iomap_file_init_dma_buf_io_ctx(struct file *file, struct block_device *bdev,
+				   struct dma_buf_io_ctx *ctx);
+
 /*
  * Fast path for small, block-aligned direct I/Os that map to a single
  * contiguous on-disk extent.
-- 
2.43.0


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

* [RFC 4/4] xfs: support dma-buf registered buffers for direct I/O
  2026-10-16  9:19 [RFC 0/4] fs: support dma-buf backed direct I/O Anuj Gupta
                   ` (2 preceding siblings ...)
  2026-10-16  9:19 ` [RFC 3/4] iomap: add dma-buf direct I/O guards and registration helper Anuj Gupta
@ 2026-10-16  9:19 ` Anuj Gupta
  2026-10-16  9:28   ` Christoph Hellwig
  3 siblings, 1 reply; 9+ messages in thread
From: Anuj Gupta @ 2026-10-16  9:19 UTC (permalink / raw)
  To: asml.silence, hch, djwong, cem, brauner, axboe
  Cc: linux-block, linux-xfs, linux-fsdevel, joshi.k, anuj20.g,
	nj.shetty

From: Nitesh Shetty <nj.shetty@samsung.com>

Add the init_dma_buf_io_ctx fop for XFS files.
XFS picks the device and calls the iomap layer with
the relevant device.

Refuse the iterator from every CPU-copy path: DAX, buffered
fallback from a -ENOTBLK direct write, and read/writes
without O_DIRECT.

If a file is switched between the data and realtime devices
after registration, the block layer cross-device check refuses
the I/O.

Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
---
 fs/xfs/xfs_file.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 426a67b813a7..f97d5acfaf68 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -340,6 +340,11 @@ xfs_file_read_iter(
 	if (xfs_is_shutdown(mp))
 		return -EIO;
 
+	/* a device mapping can only be read by a direct I/O bio */
+	if (iov_iter_is_dmabuf_map(to) &&
+	    (IS_DAX(inode) || !(iocb->ki_flags & IOCB_DIRECT)))
+		return -EOPNOTSUPP;
+
 	if (IS_DAX(inode))
 		ret = xfs_file_dax_read(iocb, to);
 	else if (iocb->ki_flags & IOCB_DIRECT)
@@ -1196,6 +1201,11 @@ xfs_file_write_iter(
 			return ret;
 	}
 
+	/* a device mapping can only be written by a direct I/O bio */
+	if (iov_iter_is_dmabuf_map(from) &&
+	    (IS_DAX(inode) || !(iocb->ki_flags & IOCB_DIRECT)))
+		return -EOPNOTSUPP;
+
 	if (IS_DAX(inode))
 		return xfs_file_dax_write(iocb, from);
 
@@ -1209,6 +1219,9 @@ xfs_file_write_iter(
 		ret = xfs_file_dio_write(iocb, from);
 		if (ret != -ENOTBLK)
 			return ret;
+		/* the page cache cannot copy from a device mapping */
+		if (iov_iter_is_dmabuf_map(from))
+			return -EOPNOTSUPP;
 	}
 
 	if (xfs_is_zoned_inode(ip))
@@ -2173,10 +2186,27 @@ xfs_file_mmap_prepare(
 	return 0;
 }
 
+/*
+ * A realtime file's data lives on the realtime device, anything else on the
+ * data device. If a file is switched between them after registration, the
+ * block layer cross-device check refuses the I/O.
+ */
+static int
+xfs_file_init_dma_buf_io_ctx(
+	struct file		*file,
+	struct dma_buf_io_ctx	*ctx)
+{
+	struct xfs_inode	*ip = XFS_I(file_inode(file));
+
+	return iomap_file_init_dma_buf_io_ctx(file,
+			xfs_inode_buftarg(ip)->bt_bdev, ctx);
+}
+
 const struct file_operations xfs_file_operations = {
 	.llseek		= xfs_file_llseek,
 	.read_iter	= xfs_file_read_iter,
 	.write_iter	= xfs_file_write_iter,
+	.init_dma_buf_io_ctx = xfs_file_init_dma_buf_io_ctx,
 	.splice_read	= xfs_file_splice_read,
 	.splice_write	= iter_file_splice_write,
 	.iopoll		= iocb_bio_iopoll,
-- 
2.43.0


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

* Re: [RFC 1/4] block: factor out bdev_init_dma_buf_io_ctx()
  2026-10-16  9:19 ` [RFC 1/4] block: factor out bdev_init_dma_buf_io_ctx() Anuj Gupta
@ 2026-10-16  9:23   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2026-10-16  9:23 UTC (permalink / raw)
  To: Anuj Gupta
  Cc: asml.silence, hch, djwong, cem, brauner, axboe, linux-block,
	linux-xfs, linux-fsdevel, joshi.k, anuj20.g, nj.shetty

On Fri, Oct 16, 2026 at 02:49:11PM +0530, Anuj Gupta wrote:
> From: Nitesh Shetty <nj.shetty@samsung.com>
> 
> Factor the checks and driver setup into an exported helper that takes
> an explicit block device, so filesystems can initialize a dma-buf I/O
> context for the device backing a regular file. The block-device file
> operation becomes a wrapper using file_bdev(), so its behavior is
> unchanged.

Please move hte helper out of block/fops.c, as that only is for
the block device file operations.


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

* Re: [RFC 2/4] block: refuse a dma-buf bio for a disk the buffer was not registered on
  2026-10-16  9:19 ` [RFC 2/4] block: refuse a dma-buf bio for a disk the buffer was not registered on Anuj Gupta
@ 2026-10-16  9:24   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2026-10-16  9:24 UTC (permalink / raw)
  To: Anuj Gupta
  Cc: asml.silence, hch, djwong, cem, brauner, axboe, linux-block,
	linux-xfs, linux-fsdevel, joshi.k, anuj20.g, nj.shetty

On Fri, Oct 16, 2026 at 02:49:12PM +0530, Anuj Gupta wrote:
> From: Nitesh Shetty <nj.shetty@samsung.com>
> 
> A registered dma-buf map belongs to the device it was mapped for.
> The device backing a file can change after registration. Record
> the registered disk's dev_t at init and refuse a bio that targets
> a different one.

Can you explain a bit better what this is trying to solve?


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

* Re: [RFC 3/4] iomap: add dma-buf direct I/O guards and registration helper
  2026-10-16  9:19 ` [RFC 3/4] iomap: add dma-buf direct I/O guards and registration helper Anuj Gupta
@ 2026-10-16  9:26   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2026-10-16  9:26 UTC (permalink / raw)
  To: Anuj Gupta
  Cc: asml.silence, hch, djwong, cem, brauner, axboe, linux-block,
	linux-xfs, linux-fsdevel, joshi.k, anuj20.g, nj.shetty

On Fri, Oct 16, 2026 at 02:49:13PM +0530, Anuj Gupta wrote:
> From: Nitesh Shetty <nj.shetty@samsung.com>
> 
> Direct I/O copies data from the CPU in three places, zero-filling
> holes, inline data, and bounce pages. A dma-buf iterator has no
> CPU-visible pages, so refuse it.
> 
> 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.
> 
> Also add iomap_file_init_dma_buf_io_ctx(), so filesystems can register
> without open-coding the DAX check. The filesystem picks the device,
> iomap does the rest.
> 
> Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
> Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
> ---
>  fs/iomap/direct-io.c  | 31 ++++++++++++++++++++++++++++++-
>  include/linux/iomap.h |  3 +++
>  2 files changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
> index 8b4039d16ce8..fc40f4367ee7 100644
> --- a/fs/iomap/direct-io.c
> +++ b/fs/iomap/direct-io.c
> @@ -427,6 +427,10 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
>  	unsigned int alignment;
>  	ssize_t ret = 0;
>  
> +	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.
> @@ -595,7 +599,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 length = iov_iter_zero(iomap_length(iter), dio->submit.iter);
> +	loff_t length;
> +
> +	/* a device mapping cannot be zeroed from the CPU */
> +	if (iov_iter_is_dmabuf_map(dio->submit.iter))
> +		return -EOPNOTSUPP;
> +
> +	length = iov_iter_zero(iomap_length(iter), dio->submit.iter);
>  
>  	dio->size += length;
>  	if (!length)
> @@ -612,6 +622,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, which a device mapping bypasses */

Overly lone line here.

> +	/* bouncing copies the data from the CPU, which a device mapping bypasses */

.. and here.  Note that could still copy to/from the device memory in
either case, but that's probably rather pointless at least for actual
device dmabufs.  It might be useful for udmabuf or other kernel
allocations, though.


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

* Re: [RFC 4/4] xfs: support dma-buf registered buffers for direct I/O
  2026-10-16  9:19 ` [RFC 4/4] xfs: support dma-buf registered buffers for direct I/O Anuj Gupta
@ 2026-10-16  9:28   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2026-10-16  9:28 UTC (permalink / raw)
  To: Anuj Gupta
  Cc: asml.silence, hch, djwong, cem, brauner, axboe, linux-block,
	linux-xfs, linux-fsdevel, joshi.k, anuj20.g, nj.shetty

On Fri, Oct 16, 2026 at 02:49:14PM +0530, Anuj Gupta wrote:
> From: Nitesh Shetty <nj.shetty@samsung.com>
> 
> Add the init_dma_buf_io_ctx fop for XFS files.
> XFS picks the device and calls the iomap layer with
> the relevant device.
> 
> Refuse the iterator from every CPU-copy path: DAX, buffered
> fallback from a -ENOTBLK direct write, and read/writes
> without O_DIRECT.
> 
> If a file is switched between the data and realtime devices
> after registration, the block layer cross-device check refuses
> the I/O.
> 
> Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
> ---
>  fs/xfs/xfs_file.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 426a67b813a7..f97d5acfaf68 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -340,6 +340,11 @@ xfs_file_read_iter(
>  	if (xfs_is_shutdown(mp))
>  		return -EIO;
>  
> +	/* a device mapping can only be read by a direct I/O bio */
> +	if (iov_iter_is_dmabuf_map(to) &&
> +	    (IS_DAX(inode) || !(iocb->ki_flags & IOCB_DIRECT)))
> +		return -EOPNOTSUPP;

Maybe move this into the actual methods for dax/buffered instead
to avoid extra conditionals?  Same for the write side.

>  
> @@ -1209,6 +1219,9 @@ xfs_file_write_iter(
>  		ret = xfs_file_dio_write(iocb, from);
>  		if (ret != -ENOTBLK)
>  			return ret;
> +		/* the page cache cannot copy from a device mapping */
> +		if (iov_iter_is_dmabuf_map(from))
> +			return -EOPNOTSUPP;

I suspect these random fallbacks are going to cause trouble, but
I'm not really sure what to do about it either.

> +/*
> + * A realtime file's data lives on the realtime device, anything else on the
> + * data device. If a file is switched between them after registration, the
> + * block layer cross-device check refuses the I/O.
> + */
> +static int
> +xfs_file_init_dma_buf_io_ctx(
> +	struct file		*file,
> +	struct dma_buf_io_ctx	*ctx)
> +{
> +	struct xfs_inode	*ip = XFS_I(file_inode(file));
> +
> +	return iomap_file_init_dma_buf_io_ctx(file,
> +			xfs_inode_buftarg(ip)->bt_bdev, ctx);
> +}

Ah, this is where the previous cross check comes from.  What about
simply disallowing toggling the RT flag with outstanding reservations
instead?


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

end of thread, other threads:[~2026-10-16  9:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16  9:19 [RFC 0/4] fs: support dma-buf backed direct I/O Anuj Gupta
2026-10-16  9:19 ` [RFC 1/4] block: factor out bdev_init_dma_buf_io_ctx() Anuj Gupta
2026-10-16  9:23   ` Christoph Hellwig
2026-10-16  9:19 ` [RFC 2/4] block: refuse a dma-buf bio for a disk the buffer was not registered on Anuj Gupta
2026-10-16  9:24   ` Christoph Hellwig
2026-10-16  9:19 ` [RFC 3/4] iomap: add dma-buf direct I/O guards and registration helper Anuj Gupta
2026-10-16  9:26   ` Christoph Hellwig
2026-10-16  9:19 ` [RFC 4/4] xfs: support dma-buf registered buffers for direct I/O Anuj Gupta
2026-10-16  9:28   ` Christoph Hellwig

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