Skip to content

Commit 0d375a1

Browse files
Darrick J. WongMiklos Szeredi
authored andcommitted
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>
1 parent 26e5c67 commit 0d375a1

4 files changed

Lines changed: 31 additions & 8 deletions

File tree

fs/fuse/dev.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,32 @@ void fuse_dev_queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
371371
}
372372
}
373373

374+
static inline void fuse_request_assign_unique_locked(struct fuse_iqueue *fiq,
375+
struct fuse_req *req)
376+
{
377+
if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
378+
req->in.h.unique = fuse_get_unique_locked(fiq);
379+
380+
/* tracepoint captures in.h.unique and in.h.len */
381+
trace_fuse_request_send(req);
382+
}
383+
384+
inline void fuse_request_assign_unique(struct fuse_iqueue *fiq,
385+
struct fuse_req *req)
386+
{
387+
if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
388+
req->in.h.unique = fuse_get_unique(fiq);
389+
390+
/* tracepoint captures in.h.unique and in.h.len */
391+
trace_fuse_request_send(req);
392+
}
393+
EXPORT_SYMBOL_GPL(fuse_request_assign_unique);
394+
374395
static void fuse_dev_queue_req(struct fuse_iqueue *fiq, struct fuse_req *req)
375396
{
376397
spin_lock(&fiq->lock);
377398
if (fiq->connected) {
378-
if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
379-
req->in.h.unique = fuse_get_unique_locked(fiq);
399+
fuse_request_assign_unique_locked(fiq, req);
380400
list_add_tail(&req->list, &fiq->pending);
381401
fuse_dev_wake_and_unlock(fiq);
382402
} else {
@@ -399,7 +419,6 @@ static void fuse_send_one(struct fuse_iqueue *fiq, struct fuse_req *req)
399419
req->in.h.len = sizeof(struct fuse_in_header) +
400420
fuse_len_args(req->args->in_numargs,
401421
(struct fuse_arg *) req->args->in_args);
402-
trace_fuse_request_send(req);
403422
fiq->ops->send_req(fiq, req);
404423
}
405424

@@ -689,10 +708,10 @@ static bool fuse_request_queue_background_uring(struct fuse_conn *fc,
689708
{
690709
struct fuse_iqueue *fiq = &fc->iq;
691710

692-
req->in.h.unique = fuse_get_unique(fiq);
693711
req->in.h.len = sizeof(struct fuse_in_header) +
694712
fuse_len_args(req->args->in_numargs,
695713
(struct fuse_arg *) req->args->in_args);
714+
fuse_request_assign_unique(fiq, req);
696715

697716
return fuse_uring_queue_bq_req(req);
698717
}

fs/fuse/dev_uring.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "fuse_i.h"
88
#include "dev_uring_i.h"
99
#include "fuse_dev_i.h"
10+
#include "fuse_trace.h"
1011

1112
#include <linux/fs.h>
1213
#include <linux/io_uring/cmd.h>
@@ -1268,8 +1269,7 @@ void fuse_uring_queue_fuse_req(struct fuse_iqueue *fiq, struct fuse_req *req)
12681269
if (!queue)
12691270
goto err;
12701271

1271-
if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
1272-
req->in.h.unique = fuse_get_unique(fiq);
1272+
fuse_request_assign_unique(fiq, req);
12731273

12741274
spin_lock(&queue->lock);
12751275
err = -ENOTCONN;

fs/fuse/fuse_i.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,11 @@ static inline ssize_t fuse_simple_idmap_request(struct mnt_idmap *idmap,
12601260
int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args,
12611261
gfp_t gfp_flags);
12621262

1263+
/**
1264+
* Assign a unique id to a fuse request
1265+
*/
1266+
void fuse_request_assign_unique(struct fuse_iqueue *fiq, struct fuse_req *req);
1267+
12631268
/**
12641269
* End a finished request
12651270
*/

fs/fuse/virtio_fs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,8 +1479,7 @@ static void virtio_fs_send_req(struct fuse_iqueue *fiq, struct fuse_req *req)
14791479
struct virtio_fs_vq *fsvq;
14801480
int ret;
14811481

1482-
if (req->in.h.opcode != FUSE_NOTIFY_REPLY)
1483-
req->in.h.unique = fuse_get_unique(fiq);
1482+
fuse_request_assign_unique(fiq, req);
14841483

14851484
clear_bit(FR_PENDING, &req->flags);
14861485

0 commit comments

Comments
 (0)