1*a7040a06SBernd Schubert.. SPDX-License-Identifier: GPL-2.0 2*a7040a06SBernd Schubert 3*a7040a06SBernd Schubert======================================= 4*a7040a06SBernd SchubertFUSE-over-io-uring design documentation 5*a7040a06SBernd Schubert======================================= 6*a7040a06SBernd Schubert 7*a7040a06SBernd SchubertThis documentation covers basic details how the fuse 8*a7040a06SBernd Schubertkernel/userspace communication through io-uring is configured 9*a7040a06SBernd Schubertand works. For generic details about FUSE see fuse.rst. 10*a7040a06SBernd Schubert 11*a7040a06SBernd SchubertThis document also covers the current interface, which is 12*a7040a06SBernd Schubertstill in development and might change. 13*a7040a06SBernd Schubert 14*a7040a06SBernd SchubertLimitations 15*a7040a06SBernd Schubert=========== 16*a7040a06SBernd SchubertAs of now not all requests types are supported through io-uring, userspace 17*a7040a06SBernd Schubertis required to also handle requests through /dev/fuse after io-uring setup 18*a7040a06SBernd Schubertis complete. Specifically notifications (initiated from the daemon side) 19*a7040a06SBernd Schubertand interrupts. 20*a7040a06SBernd Schubert 21*a7040a06SBernd SchubertFuse io-uring configuration 22*a7040a06SBernd Schubert=========================== 23*a7040a06SBernd Schubert 24*a7040a06SBernd SchubertFuse kernel requests are queued through the classical /dev/fuse 25*a7040a06SBernd Schubertread/write interface - until io-uring setup is complete. 26*a7040a06SBernd Schubert 27*a7040a06SBernd SchubertIn order to set up fuse-over-io-uring fuse-server (user-space) 28*a7040a06SBernd Schubertneeds to submit SQEs (opcode = IORING_OP_URING_CMD) to the /dev/fuse 29*a7040a06SBernd Schubertconnection file descriptor. Initial submit is with the sub command 30*a7040a06SBernd SchubertFUSE_URING_REQ_REGISTER, which will just register entries to be 31*a7040a06SBernd Schubertavailable in the kernel. 32*a7040a06SBernd Schubert 33*a7040a06SBernd SchubertOnce at least one entry per queue is submitted, kernel starts 34*a7040a06SBernd Schubertto enqueue to ring queues. 35*a7040a06SBernd SchubertNote, every CPU core has its own fuse-io-uring queue. 36*a7040a06SBernd SchubertUserspace handles the CQE/fuse-request and submits the result as 37*a7040a06SBernd Schubertsubcommand FUSE_URING_REQ_COMMIT_AND_FETCH - kernel completes 38*a7040a06SBernd Schubertthe requests and also marks the entry available again. If there are 39*a7040a06SBernd Schubertpending requests waiting the request will be immediately submitted 40*a7040a06SBernd Schubertto the daemon again. 41*a7040a06SBernd Schubert 42*a7040a06SBernd SchubertInitial SQE 43*a7040a06SBernd Schubert-----------:: 44*a7040a06SBernd Schubert 45*a7040a06SBernd Schubert | | FUSE filesystem daemon 46*a7040a06SBernd Schubert | | 47*a7040a06SBernd Schubert | | >io_uring_submit() 48*a7040a06SBernd Schubert | | IORING_OP_URING_CMD / 49*a7040a06SBernd Schubert | | FUSE_URING_CMD_REGISTER 50*a7040a06SBernd Schubert | | [wait cqe] 51*a7040a06SBernd Schubert | | >io_uring_wait_cqe() or 52*a7040a06SBernd Schubert | | >io_uring_submit_and_wait() 53*a7040a06SBernd Schubert | | 54*a7040a06SBernd Schubert | >fuse_uring_cmd() | 55*a7040a06SBernd Schubert | >fuse_uring_register() | 56*a7040a06SBernd Schubert 57*a7040a06SBernd Schubert 58*a7040a06SBernd SchubertSending requests with CQEs 59*a7040a06SBernd Schubert--------------------------:: 60*a7040a06SBernd Schubert 61*a7040a06SBernd Schubert | | FUSE filesystem daemon 62*a7040a06SBernd Schubert | | [waiting for CQEs] 63*a7040a06SBernd Schubert | "rm /mnt/fuse/file" | 64*a7040a06SBernd Schubert | | 65*a7040a06SBernd Schubert | >sys_unlink() | 66*a7040a06SBernd Schubert | >fuse_unlink() | 67*a7040a06SBernd Schubert | [allocate request] | 68*a7040a06SBernd Schubert | >fuse_send_one() | 69*a7040a06SBernd Schubert | ... | 70*a7040a06SBernd Schubert | >fuse_uring_queue_fuse_req | 71*a7040a06SBernd Schubert | [queue request on fg queue] | 72*a7040a06SBernd Schubert | >fuse_uring_add_req_to_ring_ent() | 73*a7040a06SBernd Schubert | ... | 74*a7040a06SBernd Schubert | >fuse_uring_copy_to_ring() | 75*a7040a06SBernd Schubert | >io_uring_cmd_done() | 76*a7040a06SBernd Schubert | >request_wait_answer() | 77*a7040a06SBernd Schubert | [sleep on req->waitq] | 78*a7040a06SBernd Schubert | | [receives and handles CQE] 79*a7040a06SBernd Schubert | | [submit result and fetch next] 80*a7040a06SBernd Schubert | | >io_uring_submit() 81*a7040a06SBernd Schubert | | IORING_OP_URING_CMD/ 82*a7040a06SBernd Schubert | | FUSE_URING_CMD_COMMIT_AND_FETCH 83*a7040a06SBernd Schubert | >fuse_uring_cmd() | 84*a7040a06SBernd Schubert | >fuse_uring_commit_fetch() | 85*a7040a06SBernd Schubert | >fuse_uring_commit() | 86*a7040a06SBernd Schubert | >fuse_uring_copy_from_ring() | 87*a7040a06SBernd Schubert | [ copy the result to the fuse req] | 88*a7040a06SBernd Schubert | >fuse_uring_req_end() | 89*a7040a06SBernd Schubert | >fuse_request_end() | 90*a7040a06SBernd Schubert | [wake up req->waitq] | 91*a7040a06SBernd Schubert | >fuse_uring_next_fuse_req | 92*a7040a06SBernd Schubert | [wait or handle next req] | 93*a7040a06SBernd Schubert | | 94*a7040a06SBernd Schubert | [req->waitq woken up] | 95*a7040a06SBernd Schubert | <fuse_unlink() | 96*a7040a06SBernd Schubert | <sys_unlink() | 97*a7040a06SBernd Schubert 98*a7040a06SBernd Schubert 99*a7040a06SBernd Schubert 100