.. 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``.