1.. SPDX-License-Identifier: GPL-2.0 2 3===================================== 4FUSE-over-io-uring uapi documentation 5===================================== 6 7Commands 8======== 9 10``enum fuse_uring_cmd``: 11 12``FUSE_IO_URING_CMD_ADD_QUEUE`` 13 Create a queue identified by ``fuse_uring_cmd_req.qid``. Queue-wide 14 options are passed in ``fuse_uring_cmd_req.flags``: 15 16 ``FUSE_URING_ZERO_COPY`` 17 Enable zero-copy on this queue. Requires ``CAP_SYS_ADMIN`` and a buffer 18 pool, which is added separately via ``ADD_BUFPOOL`` before registering 19 entries (see `Zero-copy`_). 20 21``FUSE_IO_URING_CMD_ADD_BUFPOOL`` 22 Register the payload buffer pool for an existing queue. The server provides 23 a single contiguous region in ``fuse_uring_cmd_req.bufpool.uaddr`` / 24 ``.len``. This command must be issued after ``ADD_QUEUE`` and before 25 registering any payload-carrying entries on that queue. 26 ``fuse_uring_cmd_req.flags`` must be 0. Submitting this command with 27 ``IORING_URING_CMD_FIXED`` marks the pool as registered, which avoids per 28 i/o pinning/unpinning and mapping overhead (see `Buffer pools`_). 29 30``FUSE_IO_URING_CMD_REGISTER`` 31 Register a ring entry (a long-lived SQE that carries the request header 32 iovec). For a zero-copy queue, ``fuse_uring_cmd_req.ent_zero_copy_buf_index`` 33 indicates the reserved registered buffer table slot this entry uses for 34 zero-copy (see `Zero-copy`_). 35 36``FUSE_IO_URING_CMD_COMMIT_AND_FETCH`` 37 Commit the reply for a completed request and fetch the next one. The 38 request is identified by ``fuse_uring_cmd_req.commit_id`` (the value the 39 kernel reported in ``fuse_uring_ent_in_out.commit_id``). 40 41Structures 42========== 43 44``struct fuse_uring_cmd_req`` (80-byte SQE command area): 45 46============================ ================================================== 47Field Meaning 48============================ ================================================== 49``flags`` Command-specific flags (see each command). 50``commit_id`` Request id, for ``COMMIT_AND_FETCH``. 51``qid`` Queue index. 52``bufpool.uaddr`` Pool base address, for ``ADD_BUFPOOL``. 53``bufpool.len`` Pool length in bytes, for ``ADD_BUFPOOL``. 54``bufpool.reserved`` Must be 0, for ``ADD_BUFPOOL``. 55``ent_zero_copy_buf_index`` Per-entry zero-copy slot, for ``REGISTER``. 56============================ ================================================== 57 58``struct fuse_uring_ent_in_out`` (reported by the kernel per request): 59 60============================ ================================================== 61Field Meaning 62============================ ================================================== 63``flags`` ``FUSE_URING_ENT_ZERO_COPY`` if zero-copied. 64``commit_id`` Id to echo back in ``COMMIT_AND_FETCH``. 65``payload_sz`` Total payload size in bytes (see `Zero-copy`_). 66``offset`` Payload buffer offset within the pool. 67============================ ================================================== 68 69Buffer pools 70============ 71Setup: 72 73* Issue ``ADD_QUEUE`` for the qid. 74* Issue ``ADD_BUFPOOL`` with ``bufpool.uaddr`` and ``bufpool.len`` pointing 75 at the region. 76* Register entries with ``REGISTER``. 77 78For every request that has a payload, the kernel reports where the payload 79lives in ``struct fuse_uring_ent_in_out`` (part of 80``struct fuse_uring_req_header``): 81 82``offset`` 83 Byte offset, within the pool region, for this request's payload buffer. 84 The server adds this to the pool base address to locate the payload. 85 86``payload_sz`` 87 Number of payload bytes for this request. 88 89To use registered buffers, the server registers the pool region with io_uring 90and submits ``ADD_BUFPOOL`` with ``IORING_URING_CMD_FIXED`` set in 91``sqe->uring_cmd_flags`` and the index of the registered bufpool in 92``sqe->buf_index``. Every SQE the server submits afterwards must follow the 93same fixed-buffer protocol, carrying ``IORING_URING_CMD_FIXED`` and that same 94``sqe->buf_index``. The same registered buffer can be reused for the server's 95backing-store I/O as well (e.g. ``IORING_OP_READ_FIXED`` / 96``IORING_OP_WRITE_FIXED``). 97 98Zero-copy 99========= 100Requirements: 101 102* The server must be privileged (``CAP_SYS_ADMIN``). 103* A zero-copy queue: ``ADD_QUEUE`` with the ``FUSE_URING_ZERO_COPY`` flag set. 104* A buffer pool: ``ADD_BUFPOOL``. 105* For each entry, ``REGISTER`` with ``ent_zero_copy_buf_index`` set to the 106 index this entry uses in the server's io_uring registered-buffer table. 107 This is where the kernel registers the request's pages for the server to 108 access (it is separate from the payload pool). On a non-zero-copy queue this 109 field must be 0. 110 111Zero-copy is selected per open file. The server sets the open-file flag in 112the ``FUSE_OPEN`` / ``FUSE_CREATE`` reply: 113 114``FOPEN_IO_URING_ZERO_COPY`` 115 Reads/writes on this open file should use zero-copy. 116 117For a request that is zero-copied, the kernel sets ``FUSE_URING_ENT_ZERO_COPY`` 118in ``fuse_uring_ent_in_out.flags`` and places the request's pages at the 119entry's ``ent_zero_copy_buf_index``. The server then issues 120``IORING_OP_READ_FIXED`` / ``IORING_OP_WRITE_FIXED`` against that index to 121transfer the data directly to/from the client's pages. 122 123For such a request, ``payload_sz`` includes the zero-copied page bytes 124(transferred via the registered buffer at ``ent_zero_copy_buf_index``). Any 125non-page-backed args (e.g. op headers) are still copied through the pool 126payload buffer at ``offset``. 127