block: add dma-buf support for raw bdev

Add a simple proxy implementation of init_dma_buf_io_ctx() forwarding
the call to a new struct block_device_operations operation. Also reject
dma-buf backed iterators for buffered IO.

Reviewed-by: Christoph Hellwig <hch@lst.de>
[pavel: reject dma-buf without O_DIRECT]
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://patch.msgid.link/c01c4709dc55a12fb0f2fe1ec847b5f1f0c92789.1791975048.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Pavel Begunkov 2026-10-14 12:02:03 +01:00 committed by Jens Axboe
parent d88e44f43e
commit 839231d193
2 changed files with 26 additions and 0 deletions

View File

@ -709,6 +709,9 @@ blkdev_direct_write(struct kiocb *iocb, struct iov_iter *from)
static ssize_t blkdev_buffered_write(struct kiocb *iocb, struct iov_iter *from)
{
if (unlikely(iov_iter_is_dmabuf_map(from)))
return -EOPNOTSUPP;
return iomap_file_buffered_write(iocb, from, &blkdev_iomap_ops, NULL,
NULL);
}
@ -823,6 +826,11 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
if (ret < 0 || !count)
goto reexpand;
}
if (unlikely(iov_iter_is_dmabuf_map(to))) {
if (!ret)
ret = -EOPNOTSUPP;
goto reexpand;
}
/*
* Take i_rwsem and invalidate_lock to avoid racing with set_blocksize
@ -926,6 +934,21 @@ 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)
{
struct block_device *bdev = file_bdev(file);
struct gendisk *disk = bdev->bd_disk;
if (!(file->f_flags & O_DIRECT))
return -EINVAL;
if (!disk->fops->init_dma_buf_io_ctx)
return -EOPNOTSUPP;
if (bdev_has_integrity_csum(bdev))
return -EOPNOTSUPP;
return disk->fops->init_dma_buf_io_ctx(bdev, ctx);
}
const struct file_operations def_blk_fops = {
.open = blkdev_open,
.release = blkdev_release,
@ -944,6 +967,7 @@ const struct file_operations def_blk_fops = {
.fallocate = blkdev_fallocate,
.uring_cmd = blkdev_uring_cmd,
.fop_flags = FOP_BUFFER_RASYNC | FOP_DONTCACHE,
.init_dma_buf_io_ctx = blkdev_init_dma_buf_io_ctx,
};
static __init int blkdev_init(void)

View File

@ -1596,6 +1596,8 @@ struct block_device_operations {
/* returns the length of the identifier or a negative errno: */
int (*get_unique_id)(struct gendisk *disk, u8 id[16],
enum blk_unique_id id_type);
int (*init_dma_buf_io_ctx)(struct block_device *,
struct dma_buf_io_ctx *);
struct module *owner;
const struct pr_ops *pr_ops;