File Index
Files and directories
Sign in
FILE

dev_uring_i.h

File preview with syntax highlighting.

linux-6.19.14/fs/fuse/dev_uring_i.h C
  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
 17enum 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 */
 40struct 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
 59struct 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 */
108struct 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
138bool fuse_uring_enabled(void);
139void fuse_uring_destruct(struct fuse_conn *fc);
140void fuse_uring_stop_queues(struct fuse_ring *ring);
141void fuse_uring_abort_end_requests(struct fuse_ring *ring);
142int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags);
143void fuse_uring_queue_fuse_req(struct fuse_iqueue *fiq, struct fuse_req *req);
144bool fuse_uring_queue_bq_req(struct fuse_req *req);
145bool fuse_uring_remove_pending_req(struct fuse_req *req);
146bool fuse_uring_request_expired(struct fuse_conn *fc);
147
148static inline void fuse_uring_abort(struct fuse_conn *fc)
149{
150	struct fuse_ring *ring = fc->ring;
151
152	if (ring == NULL)
153		return;
154
155	if (atomic_read(&ring->queue_refs) > 0) {
156		fuse_uring_abort_end_requests(ring);
157		fuse_uring_stop_queues(ring);
158	}
159}
160
161static inline void fuse_uring_wait_stopped_queues(struct fuse_conn *fc)
162{
163	struct fuse_ring *ring = fc->ring;
164
165	if (ring)
166		wait_event(ring->stop_waitq,
167			   atomic_read(&ring->queue_refs) == 0);
168}
169
170static inline bool fuse_uring_ready(struct fuse_conn *fc)
171{
172	return fc->ring && fc->ring->ready;
173}
174
175#else /* CONFIG_FUSE_IO_URING */
176
177static inline void fuse_uring_destruct(struct fuse_conn *fc)
178{
179}
180
181static inline bool fuse_uring_enabled(void)
182{
183	return false;
184}
185
186static inline void fuse_uring_abort(struct fuse_conn *fc)
187{
188}
189
190static inline void fuse_uring_wait_stopped_queues(struct fuse_conn *fc)
191{
192}
193
194static inline bool fuse_uring_ready(struct fuse_conn *fc)
195{
196	return false;
197}
198
199static inline bool fuse_uring_remove_pending_req(struct fuse_req *req)
200{
201	return false;
202}
203
204static inline bool fuse_uring_request_expired(struct fuse_conn *fc)
205{
206	return false;
207}
208
209#endif /* CONFIG_FUSE_IO_URING */
210
211#endif /* _FS_FUSE_DEV_URING_I_H */
~/ Read-only file preview.