xref: /linux/Documentation/filesystems/fuse-io-uring.rst (revision 92cc9acff7194b1b9db078901f2a83182bb73202)
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