aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBernd Schubert <bschubert@ddn.com>2025-03-24 23:18:10 +0100
committerBernd Schubert <bernd@bsbernd.com>2025-04-28 19:57:39 +0200
commitda355f79362f5724f75147dfd51d58d6ee3e552d (patch)
tree204da0911bdb0f299db1655328d0c22342c2533b /lib
parentdde540e413eba6d22a4515659dd72262b8a01af4 (diff)
downloadlibfuse-da355f79362f5724f75147dfd51d58d6ee3e552d.tar.gz
Add support for ring creation in fuse_lowlevel.c
Signed-off-by: Bernd Schubert <bschubert@ddn.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/fuse_i.h1
-rw-r--r--lib/fuse_loop_mt.c5
-rw-r--r--lib/fuse_lowlevel.c31
-rw-r--r--lib/fuse_uring_i.h27
-rw-r--r--lib/util.h2
5 files changed, 63 insertions, 3 deletions
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index b643e90..23e58ef 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -61,6 +61,7 @@ struct fuse_notify_req {
};
struct fuse_session_uring {
+ bool enable;
unsigned int q_depth;
struct fuse_ring_pool *pool;
};
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c
index 46e2d6e..046256c 100644
--- a/lib/fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
@@ -15,6 +15,7 @@
#include "fuse_misc.h"
#include "fuse_kernel.h"
#include "fuse_i.h"
+#include "fuse_uring_i.h"
#include "util.h"
#include <stdio.h>
@@ -407,12 +408,16 @@ int err;
fuse_join_worker(&mt, mt.main.next);
err = mt.error;
+
+ if (se->uring.pool)
+ fuse_uring_stop(se);
}
pthread_mutex_destroy(&se->mt_lock);
if(se->error != 0)
err = se->error;
+
if (created_config) {
fuse_loop_cfg_destroy(config);
config = NULL;
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 4a4c71e..433594f 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -18,6 +18,7 @@
#include "fuse_misc.h"
#include "mount_util.h"
#include "util.h"
+#include "fuse_uring_i.h"
#include <pthread.h>
#include <stdatomic.h>
@@ -34,6 +35,7 @@
#include <assert.h>
#include <sys/file.h>
#include <sys/ioctl.h>
+#include <stdalign.h>
#ifdef USDT_ENABLED
#include "usdt.h"
@@ -46,7 +48,6 @@
#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
#endif
-
#define PARAM(inarg) (((char *)(inarg)) + sizeof(*(inarg)))
#define OFFSET_MAX 0x7fffffffffffffffLL
@@ -169,6 +170,10 @@ static void list_add_req(struct fuse_req *req, struct fuse_req *next)
static void destroy_req(fuse_req_t req)
{
+ if (req->is_uring) {
+ fuse_log(FUSE_LOG_ERR, "Refusing to destruct uring req\n");
+ return;
+ }
assert(req->ch == NULL);
pthread_mutex_destroy(&req->lock);
free(req);
@@ -179,7 +184,11 @@ void fuse_free_req(fuse_req_t req)
int ctr;
struct fuse_session *se = req->se;
- if (se->conn.no_interrupt) {
+ /* XXX: for now no support for interrupts with io-uring
+ * It actually might work alreasdy, though. But then would add
+ * a lock across ring queues.
+ */
+ if (se->conn.no_interrupt || req->is_uring) {
ctr = --req->ref_cnt;
fuse_chan_put(req->ch);
req->ch = NULL;
@@ -209,6 +218,7 @@ static struct fuse_req *fuse_ll_alloc_req(struct fuse_session *se)
req->ref_cnt = 1;
list_init_req(req);
pthread_mutex_init(&req->lock, NULL);
+ req->is_uring = false;
}
return req;
@@ -2415,6 +2425,8 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in,
uint64_t outargflags = 0;
bool buf_reallocable = se->buf_reallocable;
(void) nodeid;
+ bool enable_io_uring = false;
+
if (se->debug) {
fuse_log(FUSE_LOG_DEBUG, "INIT: %u.%u\n", arg->major, arg->minor);
if (arg->major == 7 && arg->minor >= 6) {
@@ -2673,6 +2685,10 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in,
}
if (se->conn.want_ext & FUSE_CAP_NO_EXPORT_SUPPORT)
outargflags |= FUSE_NO_EXPORT_SUPPORT;
+ if (se->uring.enable && se->conn.want_ext & FUSE_CAP_OVER_IO_URING) {
+ outargflags |= FUSE_OVER_IO_URING;
+ enable_io_uring = true;
+ }
if (inargflags & FUSE_INIT_EXT) {
outargflags |= FUSE_INIT_EXT;
@@ -2721,6 +2737,17 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in,
outargsize = FUSE_COMPAT_22_INIT_OUT_SIZE;
send_reply_ok(req, &outarg, outargsize);
+
+ /* XXX: Split the start, and send SQEs only after send_reply_ok() */
+ if (enable_io_uring) {
+ int ring_rc = fuse_uring_start(se);
+
+ if (ring_rc != 0) {
+ fuse_log(FUSE_LOG_ERR, "fuse: failed to start io-uring: %s\n",
+ strerror(ring_rc));
+ fuse_session_exit(se);
+ }
+ }
}
static __attribute__((no_sanitize("thread"))) void
diff --git a/lib/fuse_uring_i.h b/lib/fuse_uring_i.h
index fefb8a0..e9f2989 100644
--- a/lib/fuse_uring_i.h
+++ b/lib/fuse_uring_i.h
@@ -8,11 +8,38 @@
#ifndef FUSE_URING_I_H_
#define FUSE_URING_I_H_
+#include "fuse_config.h"
#include "fuse_lowlevel.h"
+#include "fuse_kernel.h"
+
+#ifndef HAVE_URING
+#include "util.h"
+#endif
+
+void fuse_session_process_uring_cqe(struct fuse_session *se,
+ struct fuse_req *req,
+ struct fuse_in_header *in, void *in_header,
+ void *in_payload, size_t payload_len);
+
+#ifdef HAVE_URING
struct fuse_in_header;
int fuse_uring_start(struct fuse_session *se);
int fuse_uring_stop(struct fuse_session *se);
+#else // HAVE_URING
+
+static inline int fuse_uring_start(struct fuse_session *se FUSE_VAR_UNUSED)
+{
+ return -ENOTSUP;
+}
+
+static inline int fuse_uring_stop(struct fuse_session *se FUSE_VAR_UNUSED)
+{
+ return -ENOTSUP;
+}
+
+#endif // HAVE_URING
+
#endif // FUSE_URING_I_H_
diff --git a/lib/util.h b/lib/util.h
index d1939cf..96b59d3 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -28,7 +28,7 @@ static inline uint64_t fuse_higher_32_bits(uint64_t nr)
}
#ifndef FUSE_VAR_UNUSED
-#define FUSE_VAR_UNUSED(var) (__attribute__((unused)) var)
+#define FUSE_VAR_UNUSED __attribute__((__unused__))
#endif
#define container_of(ptr, type, member) \