fuse: change req->fm to req->chan

Store a struct fuse_chan pointer in fuse_req instead of a struct fuse_mount
pointer.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Miklos Szeredi 2026-03-30 12:36:59 +02:00
parent a697d95fcd
commit 28d733cc3e
4 changed files with 61 additions and 65 deletions

View File

@ -35,22 +35,22 @@ static DECLARE_WAIT_QUEUE_HEAD(fuse_dev_waitq);
static struct kmem_cache *fuse_req_cachep;
static void fuse_request_init(struct fuse_mount *fm, struct fuse_req *req)
static void fuse_request_init(struct fuse_chan *fch, struct fuse_req *req)
{
INIT_LIST_HEAD(&req->list);
INIT_LIST_HEAD(&req->intr_entry);
init_waitqueue_head(&req->waitq);
refcount_set(&req->count, 1);
__set_bit(FR_PENDING, &req->flags);
req->fm = fm;
req->chan = fch;
req->create_time = jiffies;
}
static struct fuse_req *fuse_request_alloc(struct fuse_mount *fm, gfp_t flags)
static struct fuse_req *fuse_request_alloc(struct fuse_chan *fch, gfp_t flags)
{
struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
if (req)
fuse_request_init(fm, req);
fuse_request_init(fch, req);
return req;
}
@ -86,17 +86,17 @@ static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
(fc->chan->io_uring && fc->chan->connected && !fuse_uring_ready(fc->chan));
}
static void fuse_drop_waiting(struct fuse_conn *fc)
static void fuse_drop_waiting(struct fuse_chan *fch)
{
/*
* lockess check of fc->chan->connected is okay, because atomic_dec_and_test()
* lockess check of fch->connected is okay, because atomic_dec_and_test()
* provides a memory barrier matched with the one in fuse_chan_wait_aborted()
* to ensure no wake-up is missed.
*/
if (atomic_dec_and_test(&fc->chan->num_waiting) &&
!READ_ONCE(fc->chan->connected)) {
if (atomic_dec_and_test(&fch->num_waiting) &&
!READ_ONCE(fch->connected)) {
/* wake up aborters */
wake_up_all(&fc->chan->blocked_waitq);
wake_up_all(&fch->blocked_waitq);
}
}
@ -133,7 +133,7 @@ static struct fuse_req *fuse_get_req(struct mnt_idmap *idmap,
if (fc->conn_error)
goto out;
req = fuse_request_alloc(fm, GFP_KERNEL);
req = fuse_request_alloc(fc->chan, GFP_KERNEL);
err = -ENOMEM;
if (!req) {
if (for_background)
@ -170,13 +170,13 @@ static struct fuse_req *fuse_get_req(struct mnt_idmap *idmap,
return req;
out:
fuse_drop_waiting(fc);
fuse_drop_waiting(fc->chan);
return ERR_PTR(err);
}
static void fuse_put_request(struct fuse_req *req)
{
struct fuse_conn *fc = req->fm->fc;
struct fuse_chan *fch = req->chan;
if (refcount_dec_and_test(&req->count)) {
if (test_bit(FR_BACKGROUND, &req->flags)) {
@ -184,15 +184,15 @@ static void fuse_put_request(struct fuse_req *req)
* We get here in the unlikely case that a background
* request was allocated but not sent
*/
spin_lock(&fc->chan->bg_lock);
if (!fc->chan->blocked)
wake_up(&fc->chan->blocked_waitq);
spin_unlock(&fc->chan->bg_lock);
spin_lock(&fch->bg_lock);
if (!fch->blocked)
wake_up(&fch->blocked_waitq);
spin_unlock(&fch->bg_lock);
}
if (test_bit(FR_WAITING, &req->flags)) {
__clear_bit(FR_WAITING, &req->flags);
fuse_drop_waiting(fc);
fuse_drop_waiting(fch);
}
fuse_request_free(req);
@ -618,9 +618,8 @@ void fuse_request_bg_finish(struct fuse_chan *fch, struct fuse_req *req)
*/
void fuse_request_end(struct fuse_req *req)
{
struct fuse_mount *fm = req->fm;
struct fuse_conn *fc = fm->fc;
struct fuse_iqueue *fiq = &fc->chan->iq;
struct fuse_chan *fch = req->chan;
struct fuse_iqueue *fiq = &fch->iq;
if (test_and_set_bit(FR_FINISHED, &req->flags))
goto put_request;
@ -639,10 +638,10 @@ void fuse_request_end(struct fuse_req *req)
WARN_ON(test_bit(FR_PENDING, &req->flags));
WARN_ON(test_bit(FR_SENT, &req->flags));
if (test_bit(FR_BACKGROUND, &req->flags)) {
spin_lock(&fc->chan->bg_lock);
fuse_request_bg_finish(fc->chan, req);
flush_bg_queue(fc->chan);
spin_unlock(&fc->chan->bg_lock);
spin_lock(&fch->bg_lock);
fuse_request_bg_finish(fch, req);
flush_bg_queue(fch);
spin_unlock(&fch->bg_lock);
} else {
/* Wake up waiter sleeping in request_wait_answer() */
wake_up(&req->waitq);
@ -657,7 +656,7 @@ EXPORT_SYMBOL_GPL(fuse_request_end);
static int queue_interrupt(struct fuse_req *req)
{
struct fuse_iqueue *fiq = &req->fm->fc->chan->iq;
struct fuse_iqueue *fiq = &req->chan->iq;
/* Check for we've sent request to interrupt this req */
if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags)))
@ -688,11 +687,11 @@ bool fuse_remove_pending_req(struct fuse_req *req, spinlock_t *lock)
static void request_wait_answer(struct fuse_req *req)
{
struct fuse_conn *fc = req->fm->fc;
struct fuse_iqueue *fiq = &fc->chan->iq;
struct fuse_chan *fch = req->chan;
struct fuse_iqueue *fiq = &fch->iq;
int err;
if (!fc->chan->no_interrupt) {
if (!fch->no_interrupt) {
/* Any signal may interrupt this */
err = wait_event_interruptible(req->waitq,
test_bit(FR_FINISHED, &req->flags));
@ -716,7 +715,7 @@ static void request_wait_answer(struct fuse_req *req)
return;
if (req->args->abort_on_kill) {
fuse_chan_abort(fc->chan, false);
fuse_chan_abort(fch, false);
return;
}
@ -737,7 +736,7 @@ static void request_wait_answer(struct fuse_req *req)
static void __fuse_request_send(struct fuse_req *req)
{
struct fuse_iqueue *fiq = &req->fm->fc->chan->iq;
struct fuse_iqueue *fiq = &req->chan->iq;
BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
@ -784,11 +783,11 @@ static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
}
}
static void fuse_force_creds(struct fuse_req *req)
static void fuse_force_creds(struct fuse_mount *fm, struct fuse_req *req)
{
struct fuse_conn *fc = req->fm->fc;
struct fuse_conn *fc = fm->fc;
if (!req->fm->sb || req->fm->sb->s_iflags & SB_I_NOIDMAP) {
if (!fm->sb || fm->sb->s_iflags & SB_I_NOIDMAP) {
req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
} else {
@ -820,10 +819,10 @@ ssize_t __fuse_simple_request(struct mnt_idmap *idmap,
if (args->force) {
atomic_inc(&fc->chan->num_waiting);
req = fuse_request_alloc(fm, GFP_KERNEL | __GFP_NOFAIL);
req = fuse_request_alloc(fc->chan, GFP_KERNEL | __GFP_NOFAIL);
if (!args->nocreds)
fuse_force_creds(req);
fuse_force_creds(fm, req);
__set_bit(FR_WAITING, &req->flags);
if (!args->abort_on_kill)
@ -853,10 +852,9 @@ ssize_t __fuse_simple_request(struct mnt_idmap *idmap,
}
#ifdef CONFIG_FUSE_IO_URING
static bool fuse_request_queue_background_uring(struct fuse_conn *fc,
struct fuse_req *req)
static bool fuse_request_queue_background_uring(struct fuse_req *req)
{
struct fuse_iqueue *fiq = &fc->chan->iq;
struct fuse_iqueue *fiq = &req->chan->iq;
req->in.h.len = sizeof(struct fuse_in_header) +
fuse_len_args(req->args->in_numargs,
@ -872,32 +870,31 @@ static bool fuse_request_queue_background_uring(struct fuse_conn *fc,
*/
static int fuse_request_queue_background(struct fuse_req *req)
{
struct fuse_mount *fm = req->fm;
struct fuse_conn *fc = fm->fc;
struct fuse_chan *fch = req->chan;
bool queued = false;
WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
if (!test_bit(FR_WAITING, &req->flags)) {
__set_bit(FR_WAITING, &req->flags);
atomic_inc(&fc->chan->num_waiting);
atomic_inc(&fch->num_waiting);
}
__set_bit(FR_ISREPLY, &req->flags);
#ifdef CONFIG_FUSE_IO_URING
if (fuse_uring_ready(fc->chan))
return fuse_request_queue_background_uring(fc, req);
if (fuse_uring_ready(fch))
return fuse_request_queue_background_uring(req);
#endif
spin_lock(&fc->chan->bg_lock);
if (likely(fc->chan->connected)) {
fc->chan->num_background++;
if (fc->chan->num_background == fc->chan->max_background)
fc->chan->blocked = 1;
list_add_tail(&req->list, &fc->chan->bg_queue);
flush_bg_queue(fc->chan);
spin_lock(&fch->bg_lock);
if (likely(fch->connected)) {
fch->num_background++;
if (fch->num_background == fch->max_background)
fch->blocked = 1;
list_add_tail(&req->list, &fch->bg_queue);
flush_bg_queue(fch);
queued = true;
}
spin_unlock(&fc->chan->bg_lock);
spin_unlock(&fch->bg_lock);
return queued;
}
@ -909,7 +906,7 @@ int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args,
if (args->force) {
WARN_ON(!args->nocreds);
req = fuse_request_alloc(fm, gfp_flags);
req = fuse_request_alloc(fm->fc->chan, gfp_flags);
if (!req)
return -ENOMEM;
__set_bit(FR_BACKGROUND, &req->flags);

View File

@ -1307,8 +1307,7 @@ static void fuse_uring_dispatch_ent(struct fuse_ring_ent *ent)
/* queue a fuse request and send it if a ring entry is available */
void fuse_uring_queue_fuse_req(struct fuse_iqueue *fiq, struct fuse_req *req)
{
struct fuse_conn *fc = req->fm->fc;
struct fuse_ring *ring = fc->chan->ring;
struct fuse_ring *ring = req->chan->ring;
struct fuse_ring_queue *queue;
struct fuse_ring_ent *ent = NULL;
int err;
@ -1350,8 +1349,8 @@ void fuse_uring_queue_fuse_req(struct fuse_iqueue *fiq, struct fuse_req *req)
bool fuse_uring_queue_bq_req(struct fuse_req *req)
{
struct fuse_conn *fc = req->fm->fc;
struct fuse_ring *ring = fc->chan->ring;
struct fuse_chan *fch = req->chan;
struct fuse_ring *ring = fch->ring;
struct fuse_ring_queue *queue;
struct fuse_ring_ent *ent = NULL;
@ -1371,12 +1370,12 @@ bool fuse_uring_queue_bq_req(struct fuse_req *req)
ent = list_first_entry_or_null(&queue->ent_avail_queue,
struct fuse_ring_ent, list);
spin_lock(&fc->chan->bg_lock);
fc->chan->num_background++;
if (fc->chan->num_background == fc->chan->max_background)
fc->chan->blocked = 1;
spin_lock(&fch->bg_lock);
fch->num_background++;
if (fch->num_background == fch->max_background)
fch->blocked = 1;
fuse_uring_flush_bg(queue);
spin_unlock(&fc->chan->bg_lock);
spin_unlock(&fch->bg_lock);
/*
* Due to bg_queue flush limits there might be other bg requests

View File

@ -97,8 +97,8 @@ struct fuse_req {
void *argbuf;
#endif
/** fuse_mount this request belongs to */
struct fuse_mount *fm;
/** fuse_chan this request belongs to */
struct fuse_chan *chan;
#ifdef CONFIG_FUSE_IO_URING
void *ring_entry;

View File

@ -90,7 +90,7 @@ TRACE_EVENT(fuse_request_send,
),
TP_fast_assign(
__entry->connection = req->fm->fc->dev;
__entry->connection = req->chan->conn->dev;
__entry->unique = req->in.h.unique;
__entry->opcode = req->in.h.opcode;
__entry->len = req->in.h.len;
@ -114,7 +114,7 @@ TRACE_EVENT(fuse_request_end,
),
TP_fast_assign(
__entry->connection = req->fm->fc->dev;
__entry->connection = req->chan->conn->dev;
__entry->unique = req->in.h.unique;
__entry->len = req->out.h.len;
__entry->error = req->out.h.error;