]> Git Repo - linux.git/blob - fs/fuse/dev_uring_i.h
Linux 6.14-rc3
[linux.git] / fs / fuse / dev_uring_i.h
1 /* SPDX-License-Identifier: GPL-2.0
2  *
3  * FUSE: Filesystem in Userspace
4  * Copyright (c) 2023-2024 DataDirect Networks.
5  */
6
7 #ifndef _FS_FUSE_DEV_URING_I_H
8 #define _FS_FUSE_DEV_URING_I_H
9
10 #include "fuse_i.h"
11
12 #ifdef CONFIG_FUSE_IO_URING
13
14 #define FUSE_URING_TEARDOWN_TIMEOUT (5 * HZ)
15 #define FUSE_URING_TEARDOWN_INTERVAL (HZ/20)
16
17 enum fuse_ring_req_state {
18         FRRS_INVALID = 0,
19
20         /* The ring entry received from userspace and it is being processed */
21         FRRS_COMMIT,
22
23         /* The ring entry is waiting for new fuse requests */
24         FRRS_AVAILABLE,
25
26         /* The ring entry got assigned a fuse req */
27         FRRS_FUSE_REQ,
28
29         /* The ring entry is in or on the way to user space */
30         FRRS_USERSPACE,
31
32         /* The ring entry is in teardown */
33         FRRS_TEARDOWN,
34
35         /* The ring entry is released, but not freed yet */
36         FRRS_RELEASED,
37 };
38
39 /** A fuse ring entry, part of the ring queue */
40 struct fuse_ring_ent {
41         /* userspace buffer */
42         struct fuse_uring_req_header __user *headers;
43         void __user *payload;
44
45         /* the ring queue that owns the request */
46         struct fuse_ring_queue *queue;
47
48         /* fields below are protected by queue->lock */
49
50         struct io_uring_cmd *cmd;
51
52         struct list_head list;
53
54         enum fuse_ring_req_state state;
55
56         struct fuse_req *fuse_req;
57 };
58
59 struct fuse_ring_queue {
60         /*
61          * back pointer to the main fuse uring structure that holds this
62          * queue
63          */
64         struct fuse_ring *ring;
65
66         /* queue id, corresponds to the cpu core */
67         unsigned int qid;
68
69         /*
70          * queue lock, taken when any value in the queue changes _and_ also
71          * a ring entry state changes.
72          */
73         spinlock_t lock;
74
75         /* available ring entries (struct fuse_ring_ent) */
76         struct list_head ent_avail_queue;
77
78         /*
79          * entries in the process of being committed or in the process
80          * to be sent to userspace
81          */
82         struct list_head ent_w_req_queue;
83         struct list_head ent_commit_queue;
84
85         /* entries in userspace */
86         struct list_head ent_in_userspace;
87
88         /* entries that are released */
89         struct list_head ent_released;
90
91         /* fuse requests waiting for an entry slot */
92         struct list_head fuse_req_queue;
93
94         /* background fuse requests */
95         struct list_head fuse_req_bg_queue;
96
97         struct fuse_pqueue fpq;
98
99         unsigned int active_background;
100
101         bool stopped;
102 };
103
104 /**
105  * Describes if uring is for communication and holds alls the data needed
106  * for uring communication
107  */
108 struct fuse_ring {
109         /* back pointer */
110         struct fuse_conn *fc;
111
112         /* number of ring queues */
113         size_t nr_queues;
114
115         /* maximum payload/arg size */
116         size_t max_payload_sz;
117
118         struct fuse_ring_queue **queues;
119
120         /*
121          * Log ring entry states on stop when entries cannot be released
122          */
123         unsigned int stop_debug_log : 1;
124
125         wait_queue_head_t stop_waitq;
126
127         /* async tear down */
128         struct delayed_work async_teardown_work;
129
130         /* log */
131         unsigned long teardown_time;
132
133         atomic_t queue_refs;
134
135         bool ready;
136 };
137
138 bool fuse_uring_enabled(void);
139 void fuse_uring_destruct(struct fuse_conn *fc);
140 void fuse_uring_stop_queues(struct fuse_ring *ring);
141 void fuse_uring_abort_end_requests(struct fuse_ring *ring);
142 int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags);
143 void fuse_uring_queue_fuse_req(struct fuse_iqueue *fiq, struct fuse_req *req);
144 bool fuse_uring_queue_bq_req(struct fuse_req *req);
145
146 static inline void fuse_uring_abort(struct fuse_conn *fc)
147 {
148         struct fuse_ring *ring = fc->ring;
149
150         if (ring == NULL)
151                 return;
152
153         if (atomic_read(&ring->queue_refs) > 0) {
154                 fuse_uring_abort_end_requests(ring);
155                 fuse_uring_stop_queues(ring);
156         }
157 }
158
159 static inline void fuse_uring_wait_stopped_queues(struct fuse_conn *fc)
160 {
161         struct fuse_ring *ring = fc->ring;
162
163         if (ring)
164                 wait_event(ring->stop_waitq,
165                            atomic_read(&ring->queue_refs) == 0);
166 }
167
168 static inline bool fuse_uring_ready(struct fuse_conn *fc)
169 {
170         return fc->ring && fc->ring->ready;
171 }
172
173 #else /* CONFIG_FUSE_IO_URING */
174
175 struct fuse_ring;
176
177 static inline void fuse_uring_create(struct fuse_conn *fc)
178 {
179 }
180
181 static inline void fuse_uring_destruct(struct fuse_conn *fc)
182 {
183 }
184
185 static inline bool fuse_uring_enabled(void)
186 {
187         return false;
188 }
189
190 static inline void fuse_uring_abort(struct fuse_conn *fc)
191 {
192 }
193
194 static inline void fuse_uring_wait_stopped_queues(struct fuse_conn *fc)
195 {
196 }
197
198 static inline bool fuse_uring_ready(struct fuse_conn *fc)
199 {
200         return false;
201 }
202
203 #endif /* CONFIG_FUSE_IO_URING */
204
205 #endif /* _FS_FUSE_DEV_URING_I_H */
This page took 0.034302 seconds and 4 git commands to generate.