| .. SPDX-License-Identifier: GPL-2.0 | 
 |  | 
 | ======================================= | 
 | FUSE-over-io-uring design documentation | 
 | ======================================= | 
 |  | 
 | This documentation covers basic details how the fuse | 
 | kernel/userspace communication through io-uring is configured | 
 | and works. For generic details about FUSE see fuse.rst. | 
 |  | 
 | This document also covers the current interface, which is | 
 | still in development and might change. | 
 |  | 
 | Limitations | 
 | =========== | 
 | As of now not all requests types are supported through io-uring, userspace | 
 | is required to also handle requests through /dev/fuse after io-uring setup | 
 | is complete. Specifically notifications (initiated from the daemon side) | 
 | and interrupts. | 
 |  | 
 | Fuse io-uring configuration | 
 | =========================== | 
 |  | 
 | Fuse kernel requests are queued through the classical /dev/fuse | 
 | read/write interface - until io-uring setup is complete. | 
 |  | 
 | In order to set up fuse-over-io-uring fuse-server (user-space) | 
 | needs to submit SQEs (opcode = IORING_OP_URING_CMD) to the /dev/fuse | 
 | connection file descriptor. Initial submit is with the sub command | 
 | FUSE_URING_REQ_REGISTER, which will just register entries to be | 
 | available in the kernel. | 
 |  | 
 | Once at least one entry per queue is submitted, kernel starts | 
 | to enqueue to ring queues. | 
 | Note, every CPU core has its own fuse-io-uring queue. | 
 | Userspace handles the CQE/fuse-request and submits the result as | 
 | subcommand FUSE_URING_REQ_COMMIT_AND_FETCH - kernel completes | 
 | the requests and also marks the entry available again. If there are | 
 | pending requests waiting the request will be immediately submitted | 
 | to the daemon again. | 
 |  | 
 | Initial SQE | 
 | -----------:: | 
 |  | 
 |  |                                    |  FUSE filesystem daemon | 
 |  |                                    | | 
 |  |                                    |  >io_uring_submit() | 
 |  |                                    |   IORING_OP_URING_CMD / | 
 |  |                                    |   FUSE_URING_CMD_REGISTER | 
 |  |                                    |  [wait cqe] | 
 |  |                                    |   >io_uring_wait_cqe() or | 
 |  |                                    |   >io_uring_submit_and_wait() | 
 |  |                                    | | 
 |  |  >fuse_uring_cmd()                 | | 
 |  |   >fuse_uring_register()           | | 
 |  | 
 |  | 
 | Sending requests with CQEs | 
 | --------------------------:: | 
 |  | 
 |  |                                           |  FUSE filesystem daemon | 
 |  |                                           |  [waiting for CQEs] | 
 |  |  "rm /mnt/fuse/file"                      | | 
 |  |                                           | | 
 |  |  >sys_unlink()                            | | 
 |  |    >fuse_unlink()                         | | 
 |  |      [allocate request]                   | | 
 |  |      >fuse_send_one()                     | | 
 |  |        ...                                | | 
 |  |       >fuse_uring_queue_fuse_req          | | 
 |  |        [queue request on fg queue]        | | 
 |  |         >fuse_uring_add_req_to_ring_ent() | | 
 |  |         ...                               | | 
 |  |          >fuse_uring_copy_to_ring()       | | 
 |  |          >io_uring_cmd_done()             | | 
 |  |       >request_wait_answer()              | | 
 |  |         [sleep on req->waitq]             | | 
 |  |                                           |  [receives and handles CQE] | 
 |  |                                           |  [submit result and fetch next] | 
 |  |                                           |  >io_uring_submit() | 
 |  |                                           |   IORING_OP_URING_CMD/ | 
 |  |                                           |   FUSE_URING_CMD_COMMIT_AND_FETCH | 
 |  |  >fuse_uring_cmd()                        | | 
 |  |   >fuse_uring_commit_fetch()              | | 
 |  |    >fuse_uring_commit()                   | | 
 |  |     >fuse_uring_copy_from_ring()          | | 
 |  |      [ copy the result to the fuse req]   | | 
 |  |     >fuse_uring_req_end()                 | | 
 |  |      >fuse_request_end()                  | | 
 |  |       [wake up req->waitq]                | | 
 |  |    >fuse_uring_next_fuse_req              | | 
 |  |       [wait or handle next req]           | | 
 |  |                                           | | 
 |  |       [req->waitq woken up]               | | 
 |  |    <fuse_unlink()                         | | 
 |  |  <sys_unlink()                            | | 
 |  | 
 |  | 
 |  |