summaryrefslogtreecommitdiff
path: root/Documentation/filesystems/fuse/uapi/fuse-uapi-io-uring.rst
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/filesystems/fuse/uapi/fuse-uapi-io-uring.rst')
-rw-r--r--Documentation/filesystems/fuse/uapi/fuse-uapi-io-uring.rst126
1 files changed, 126 insertions, 0 deletions
diff --git a/Documentation/filesystems/fuse/uapi/fuse-uapi-io-uring.rst b/Documentation/filesystems/fuse/uapi/fuse-uapi-io-uring.rst
new file mode 100644
index 000000000000..8367be7ea29d
--- /dev/null
+++ b/Documentation/filesystems/fuse/uapi/fuse-uapi-io-uring.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================================
+FUSE-over-io-uring uapi documentation
+=====================================
+
+Commands
+========
+
+``enum fuse_uring_cmd``:
+
+``FUSE_IO_URING_CMD_ADD_QUEUE``
+ Create a queue identified by ``fuse_uring_cmd_req.qid``. Queue-wide
+ options are passed in ``fuse_uring_cmd_req.flags``:
+
+ ``FUSE_URING_ZERO_COPY``
+ Enable zero-copy on this queue. Requires ``CAP_SYS_ADMIN`` and a buffer
+ pool, which is added separately via ``ADD_BUFPOOL`` before registering
+ entries (see `Zero-copy`_).
+
+``FUSE_IO_URING_CMD_ADD_BUFPOOL``
+ Register the payload buffer pool for an existing queue. The server provides
+ a single contiguous region in ``fuse_uring_cmd_req.bufpool.uaddr`` /
+ ``.len``. This command must be issued after ``ADD_QUEUE`` and before
+ registering any payload-carrying entries on that queue.
+ ``fuse_uring_cmd_req.flags`` must be 0. Submitting this command with
+ ``IORING_URING_CMD_FIXED`` marks the pool as registered, which avoids per
+ i/o pinning/unpinning and mapping overhead (see `Buffer pools`_).
+
+``FUSE_IO_URING_CMD_REGISTER``
+ Register a ring entry (a long-lived SQE that carries the request header
+ iovec). For a zero-copy queue, ``fuse_uring_cmd_req.ent_zero_copy_buf_index``
+ indicates the reserved registered buffer table slot this entry uses for
+ zero-copy (see `Zero-copy`_).
+
+``FUSE_IO_URING_CMD_COMMIT_AND_FETCH``
+ Commit the reply for a completed request and fetch the next one. The
+ request is identified by ``fuse_uring_cmd_req.commit_id`` (the value the
+ kernel reported in ``fuse_uring_ent_in_out.commit_id``).
+
+Structures
+==========
+
+``struct fuse_uring_cmd_req`` (80-byte SQE command area):
+
+============================ ==================================================
+Field Meaning
+============================ ==================================================
+``flags`` Command-specific flags (see each command).
+``commit_id`` Request id, for ``COMMIT_AND_FETCH``.
+``qid`` Queue index.
+``bufpool.uaddr`` Pool base address, for ``ADD_BUFPOOL``.
+``bufpool.len`` Pool length in bytes, for ``ADD_BUFPOOL``.
+``bufpool.reserved`` Must be 0, for ``ADD_BUFPOOL``.
+``ent_zero_copy_buf_index`` Per-entry zero-copy slot, for ``REGISTER``.
+============================ ==================================================
+
+``struct fuse_uring_ent_in_out`` (reported by the kernel per request):
+
+============================ ==================================================
+Field Meaning
+============================ ==================================================
+``flags`` ``FUSE_URING_ENT_ZERO_COPY`` if zero-copied.
+``commit_id`` Id to echo back in ``COMMIT_AND_FETCH``.
+``payload_sz`` Total payload size in bytes (see `Zero-copy`_).
+``offset`` Payload buffer offset within the pool.
+============================ ==================================================
+
+Buffer pools
+============
+Setup:
+
+* Issue ``ADD_QUEUE`` for the qid.
+* Issue ``ADD_BUFPOOL`` with ``bufpool.uaddr`` and ``bufpool.len`` pointing
+ at the region.
+* Register entries with ``REGISTER``.
+
+For every request that has a payload, the kernel reports where the payload
+lives in ``struct fuse_uring_ent_in_out`` (part of
+``struct fuse_uring_req_header``):
+
+``offset``
+ Byte offset, within the pool region, for this request's payload buffer.
+ The server adds this to the pool base address to locate the payload.
+
+``payload_sz``
+ Number of payload bytes for this request.
+
+To use registered buffers, the server registers the pool region with io_uring
+and submits ``ADD_BUFPOOL`` with ``IORING_URING_CMD_FIXED`` set in
+``sqe->uring_cmd_flags`` and the index of the registered bufpool in
+``sqe->buf_index``. Every SQE the server submits afterwards must follow the
+same fixed-buffer protocol, carrying ``IORING_URING_CMD_FIXED`` and that same
+``sqe->buf_index``. The same registered buffer can be reused for the server's
+backing-store I/O as well (e.g. ``IORING_OP_READ_FIXED`` /
+``IORING_OP_WRITE_FIXED``).
+
+Zero-copy
+=========
+Requirements:
+
+* The server must be privileged (``CAP_SYS_ADMIN``).
+* A zero-copy queue: ``ADD_QUEUE`` with the ``FUSE_URING_ZERO_COPY`` flag set.
+* A buffer pool: ``ADD_BUFPOOL``.
+* For each entry, ``REGISTER`` with ``ent_zero_copy_buf_index`` set to the
+ index this entry uses in the server's io_uring registered-buffer table.
+ This is where the kernel registers the request's pages for the server to
+ access (it is separate from the payload pool). On a non-zero-copy queue this
+ field must be 0.
+
+Zero-copy is selected per open file. The server sets the open-file flag in
+the ``FUSE_OPEN`` / ``FUSE_CREATE`` reply:
+
+``FOPEN_IO_URING_ZERO_COPY``
+ Reads/writes on this open file should use zero-copy.
+
+For a request that is zero-copied, the kernel sets ``FUSE_URING_ENT_ZERO_COPY``
+in ``fuse_uring_ent_in_out.flags`` and places the request's pages at the
+entry's ``ent_zero_copy_buf_index``. The server then issues
+``IORING_OP_READ_FIXED`` / ``IORING_OP_WRITE_FIXED`` against that index to
+transfer the data directly to/from the client's pages.
+
+For such a request, ``payload_sz`` includes the zero-copied page bytes
+(transferred via the registered buffer at ``ent_zero_copy_buf_index``). Any
+non-page-backed args (e.g. op headers) are still copied through the pool
+payload buffer at ``offset``.