aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/fuse_i.h9
-rw-r--r--lib/fuse_lowlevel.c23
-rw-r--r--lib/fuse_uring.c13
3 files changed, 26 insertions, 19 deletions
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index d3d86d4..d35e1e5 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -38,9 +38,11 @@ struct fuse_req {
struct fuse_ctx ctx;
struct fuse_chan *ch;
int interrupted;
- unsigned int ioctl_64bit : 1;
- unsigned int is_uring : 1;
- unsigned int is_copy_file_range_64 : 1;
+ struct {
+ unsigned int ioctl_64bit : 1;
+ unsigned int is_uring : 1;
+ unsigned int is_copy_file_range_64 : 1;
+ } flags;
union {
struct {
uint64_t unique;
@@ -218,6 +220,7 @@ int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo);
int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
int count);
void fuse_free_req(fuse_req_t req);
+void list_init_req(struct fuse_req *req);
void _cuse_lowlevel_init(fuse_req_t req, const fuse_ino_t nodeid,
const void *req_header, const void *req_payload);
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 273d4dc..cacab94 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -146,7 +146,7 @@ static size_t iov_length(const struct iovec *iov, size_t count)
return ret;
}
-static void list_init_req(struct fuse_req *req)
+void list_init_req(struct fuse_req *req)
{
req->next = req;
req->prev = req;
@@ -171,7 +171,7 @@ 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) {
+ if (req->flags.is_uring) {
fuse_log(FUSE_LOG_ERR, "Refusing to destruct uring req\n");
return;
}
@@ -189,7 +189,7 @@ void fuse_free_req(fuse_req_t req)
* It actually might work already, though. But then would add
* a lock across ring queues.
*/
- if (se->conn.no_interrupt || req->is_uring) {
+ if (se->conn.no_interrupt || req->flags.is_uring) {
ctr = --req->ref_cnt;
fuse_chan_put(req->ch);
req->ch = NULL;
@@ -219,7 +219,6 @@ 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;
@@ -260,7 +259,7 @@ static int fuse_send_msg(struct fuse_session *se, struct fuse_chan *ch,
{
struct fuse_out_header *out = iov[0].iov_base;
int err;
- bool is_uring = req && req->is_uring ? true : false;
+ bool is_uring = req && req->flags.is_uring ? true : false;
if (!is_uring)
assert(se != NULL);
@@ -328,7 +327,7 @@ static int send_reply_iov(fuse_req_t req, int error, struct iovec *iov,
static int send_reply(fuse_req_t req, int error, const void *arg,
size_t argsize)
{
- if (req->is_uring)
+ if (req->flags.is_uring)
return send_reply_uring(req, error, arg, argsize);
struct iovec iov[2];
@@ -616,7 +615,7 @@ int fuse_reply_write(fuse_req_t req, size_t count)
* This function is also used by FUSE_COPY_FILE_RANGE and its 64-bit
* variant.
*/
- if (req->is_copy_file_range_64)
+ if (req->flags.is_copy_file_range_64)
return do_fuse_reply_copy(req, count);
else
return do_fuse_reply_write(req, count);
@@ -1023,7 +1022,7 @@ int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv,
struct fuse_out_header out;
int res;
- if (req->is_uring)
+ if (req->flags.is_uring)
return fuse_reply_data_uring(req, bufv, flags);
iov[0].iov_base = &out;
@@ -1141,7 +1140,7 @@ int fuse_reply_ioctl_retry(fuse_req_t req,
}
} else {
/* Can't handle non-compat 64bit ioctls on 32bit */
- if (sizeof(void *) == 4 && req->ioctl_64bit) {
+ if (sizeof(void *) == 4 && req->flags.ioctl_64bit) {
res = fuse_reply_err(req, EINVAL);
goto out;
}
@@ -2349,7 +2348,7 @@ static void _do_ioctl(fuse_req_t req, const fuse_ino_t nodeid,
if (sizeof(void *) == 4 && req->se->conn.proto_minor >= 16 &&
!(flags & FUSE_IOCTL_32BIT)) {
- req->ioctl_64bit = 1;
+ req->flags.ioctl_64bit = 1;
}
if (req->se->op.ioctl)
@@ -2475,7 +2474,7 @@ static void _do_copy_file_range_64(fuse_req_t req, const fuse_ino_t nodeid_in,
const void *op_in, const void *in_payload)
{
(void) in_payload;
- req->is_copy_file_range_64 = 1;
+ req->flags.is_copy_file_range_64 = 1;
/* Limit size on 32bit userspace to avoid conversion overflow */
if (sizeof(size_t) == 4)
_do_copy_file_range(req, nodeid_in, op_in, NULL);
@@ -3375,7 +3374,7 @@ int fuse_req_interrupted(fuse_req_t req)
bool fuse_req_is_uring(fuse_req_t req)
{
- return req->is_uring;
+ return req->flags.is_uring;
}
#ifndef HAVE_URING
diff --git a/lib/fuse_uring.c b/lib/fuse_uring.c
index 85b5a7f..2fea05f 100644
--- a/lib/fuse_uring.c
+++ b/lib/fuse_uring.c
@@ -197,7 +197,7 @@ int fuse_req_get_payload(fuse_req_t req, char **payload, size_t *payload_sz,
struct fuse_ring_ent *ring_ent;
/* Not possible without io-uring interface */
- if (!req->is_uring)
+ if (!req->flags.is_uring)
return -EINVAL;
ring_ent = container_of(req, struct fuse_ring_ent, req);
@@ -560,9 +560,13 @@ static void fuse_uring_handle_cqe(struct fuse_ring_queue *queue,
abort();
}
- req->is_uring = true;
+ memset(&req->flags, 0, sizeof(req->flags));
+ memset(&req->u, 0, sizeof(req->u));
+ req->flags.is_uring = 1;
req->ref_cnt++;
req->ch = NULL; /* not needed for uring */
+ req->interrupted = 0;
+ list_init_req(req);
fuse_session_process_uring_cqe(fuse_ring->se, req, in, &rrh->op_in,
ent->op_payload, ent_in_out->payload_sz);
@@ -696,8 +700,9 @@ static int fuse_uring_init_queue(struct fuse_ring_queue *queue)
req->se = se;
pthread_mutex_init(&req->lock, NULL);
- req->is_uring = true;
- req->ref_cnt = 1;
+ req->flags.is_uring = 1;
+ req->ref_cnt = 1; /* extra ref to avoid destruction */
+ list_init_req(req);
}
res = fuse_uring_prepare_fetch_sqes(queue);