summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2025-09-15 17:24:48 -0700
committerMiklos Szeredi <mszeredi@redhat.com>2025-09-23 11:32:17 +0200
commit0d375a1385ed80d8c84433fb54062a9253ccf7e5 (patch)
treeddc78d406c003efa169296b48e47a284595dcf1d
parent26e5c67deb2e1f42a951f022fdf5b9f7eb747b01 (diff)
fuse: capture the unique id of fuse commands being sent
The fuse_request_{send,end} tracepoints capture the value of req->in.h.unique in the trace output. It would be really nice if we could use this to match a request to its response for debugging and latency analysis, but the call to trace_fuse_request_send occurs before the unique id has been set: fuse_request_send: connection 8388608 req 0 opcode 1 (FUSE_LOOKUP) len 107 fuse_request_end: connection 8388608 req 6 len 16 error -2 (Notice that req moves from 0 to 6) Move the callsites to trace_fuse_request_send to after the unique id has been set by introducing a helper to do that for standard fuse_req requests. FUSE_FORGET requests are not covered by this because they appear to be synthesized into the event stream without a fuse_req object and are never replied to. Requests that are aborted without ever having been submitted to the fuse server retain the behavior that only the fuse_request_end tracepoint shows up in the trace record, and with req==0. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/fuse/dev.c27
-rw-r--r--fs/fuse/dev_uring.c4
-rw-r--r--fs/fuse/fuse_i.h5
-rw-r--r--fs/fuse/virtio_fs.c3
4 files changed, 31 insertions, 8 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 4229b38546bb..1941f93190e4 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -371,12 +371,32 @@ void fuse_dev_queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
}
}
+static inline void fuse_request_assign_unique_locked(struct fuse_iqueue *fiq,
+ struct fuse_req *req)
+{
+ if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
+ req->in.h.unique = fuse_get_unique_locked(fiq);
+
+ /* tracepoint captures in.h.unique and in.h.len */
+ trace_fuse_request_send(req);
+}
+
+inline void fuse_request_assign_unique(struct fuse_iqueue *fiq,
+ struct fuse_req *req)
+{
+ if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
+ req->in.h.unique = fuse_get_unique(fiq);
+
+ /* tracepoint captures in.h.unique and in.h.len */
+ trace_fuse_request_send(req);
+}
+EXPORT_SYMBOL_GPL(fuse_request_assign_unique);
+
static void fuse_dev_queue_req(struct fuse_iqueue *fiq, struct fuse_req *req)
{
spin_lock(&fiq->lock);
if (fiq->connected) {
- if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
- req->in.h.unique = fuse_get_unique_locked(fiq);
+ fuse_request_assign_unique_locked(fiq, req);
list_add_tail(&req->list, &fiq->pending);
fuse_dev_wake_and_unlock(fiq);
} else {
@@ -399,7 +419,6 @@ static void fuse_send_one(struct fuse_iqueue *fiq, struct fuse_req *req)
req->in.h.len = sizeof(struct fuse_in_header) +
fuse_len_args(req->args->in_numargs,
(struct fuse_arg *) req->args->in_args);
- trace_fuse_request_send(req);
fiq->ops->send_req(fiq, req);
}
@@ -689,10 +708,10 @@ static bool fuse_request_queue_background_uring(struct fuse_conn *fc,
{
struct fuse_iqueue *fiq = &fc->iq;
- req->in.h.unique = fuse_get_unique(fiq);
req->in.h.len = sizeof(struct fuse_in_header) +
fuse_len_args(req->args->in_numargs,
(struct fuse_arg *) req->args->in_args);
+ fuse_request_assign_unique(fiq, req);
return fuse_uring_queue_bq_req(req);
}
diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c
index bef38ed78249..6862fe6b7799 100644
--- a/fs/fuse/dev_uring.c
+++ b/fs/fuse/dev_uring.c
@@ -7,6 +7,7 @@
#include "fuse_i.h"
#include "dev_uring_i.h"
#include "fuse_dev_i.h"
+#include "fuse_trace.h"
#include <linux/fs.h>
#include <linux/io_uring/cmd.h>
@@ -1268,8 +1269,7 @@ void fuse_uring_queue_fuse_req(struct fuse_iqueue *fiq, struct fuse_req *req)
if (!queue)
goto err;
- if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
- req->in.h.unique = fuse_get_unique(fiq);
+ fuse_request_assign_unique(fiq, req);
spin_lock(&queue->lock);
err = -ENOTCONN;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index fb6604120b53..48ec7812a1e9 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -1261,6 +1261,11 @@ int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args,
gfp_t gfp_flags);
/**
+ * Assign a unique id to a fuse request
+ */
+void fuse_request_assign_unique(struct fuse_iqueue *fiq, struct fuse_req *req);
+
+/**
* End a finished request
*/
void fuse_request_end(struct fuse_req *req);
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index c3a39061363e..7164961cb053 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -1479,8 +1479,7 @@ static void virtio_fs_send_req(struct fuse_iqueue *fiq, struct fuse_req *req)
struct virtio_fs_vq *fsvq;
int ret;
- if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
- req->in.h.unique = fuse_get_unique(fiq);
+ fuse_request_assign_unique(fiq, req);
clear_bit(FR_PENDING, &req->flags);