]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: move request blocking related members to fuse_chan
authorMiklos Szeredi <mszeredi@redhat.com>
Tue, 17 Mar 2026 13:48:33 +0000 (14:48 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Jun 2026 12:06:16 +0000 (14:06 +0200)
Move:

 - initialized
 - blocked
 - blocked_waitq
 - connected
 - num_waiting

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/control.c
fs/fuse/cuse.c
fs/fuse/dev.c
fs/fuse/dev_uring.c
fs/fuse/fuse_dev_i.h
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/fuse/req_timeout.c

index 6279a37716c54d54c5383013b291003795944c63..228e1e7114b7ae4ecb564899ca7b6a53e1a7c10b 100644 (file)
@@ -58,7 +58,7 @@ static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf,
                if (!fc)
                        return 0;
 
-               value = atomic_read(&fc->num_waiting);
+               value = atomic_read(&fc->chan->num_waiting);
                file->private_data = (void *)value;
                fuse_conn_put(fc);
        }
@@ -132,9 +132,9 @@ static ssize_t fuse_conn_max_background_write(struct file *file,
                if (fc) {
                        spin_lock(&fc->chan->bg_lock);
                        fc->chan->max_background = val;
-                       fc->blocked = fc->chan->num_background >= fc->chan->max_background;
-                       if (!fc->blocked)
-                               wake_up(&fc->blocked_waitq);
+                       fc->chan->blocked = fc->chan->num_background >= fc->chan->max_background;
+                       if (!fc->chan->blocked)
+                               wake_up(&fc->chan->blocked_waitq);
                        spin_unlock(&fc->chan->bg_lock);
                        fuse_conn_put(fc);
                }
index 36215a6b3e3ae0036e5cf3e492bcfa5556a4e08c..950c070ab3e963f69f412e944f8d69e8286bc8f9 100644 (file)
@@ -529,7 +529,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
 
        INIT_LIST_HEAD(&cc->list);
 
-       cc->fc.initialized = 1;
+       cc->fc.chan->initialized = 1;
        rc = cuse_send_init(cc);
        if (rc) {
                fuse_dev_put(fud);
@@ -586,7 +586,7 @@ static ssize_t cuse_class_waiting_show(struct device *dev,
 {
        struct cuse_conn *cc = dev_get_drvdata(dev);
 
-       return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting));
+       return sprintf(buf, "%d\n", atomic_read(&cc->fc.chan->num_waiting));
 }
 static DEVICE_ATTR(waiting, 0400, cuse_class_waiting_show, NULL);
 
index 1a22d9004c85cd1b9fc50b99dda9c721d07a4434..3c05a84b5d706c688f8ce21c40ac0652525b9f93 100644 (file)
@@ -74,26 +74,26 @@ void fuse_set_initialized(struct fuse_conn *fc)
 {
        /* Make sure stores before this are seen on another CPU */
        smp_wmb();
-       fc->initialized = 1;
+       fc->chan->initialized = 1;
 }
 
 static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
 {
-       return !fc->initialized || (for_background && fc->blocked) ||
-              (fc->io_uring && fc->connected && !fuse_uring_ready(fc));
+       return !fc->chan->initialized || (for_background && fc->chan->blocked) ||
+              (fc->io_uring && fc->chan->connected && !fuse_uring_ready(fc));
 }
 
 static void fuse_drop_waiting(struct fuse_conn *fc)
 {
        /*
-        * lockess check of fc->connected is okay, because atomic_dec_and_test()
+        * lockess check of fc->chan->connected is okay, because atomic_dec_and_test()
         * provides a memory barrier matched with the one in fuse_wait_aborted()
         * to ensure no wake-up is missed.
         */
-       if (atomic_dec_and_test(&fc->num_waiting) &&
-           !READ_ONCE(fc->connected)) {
+       if (atomic_dec_and_test(&fc->chan->num_waiting) &&
+           !READ_ONCE(fc->chan->connected)) {
                /* wake up aborters */
-               wake_up_all(&fc->blocked_waitq);
+               wake_up_all(&fc->chan->blocked_waitq);
        }
 }
 
@@ -110,11 +110,11 @@ static struct fuse_req *fuse_get_req(struct mnt_idmap *idmap,
        kgid_t fsgid;
        int err;
 
-       atomic_inc(&fc->num_waiting);
+       atomic_inc(&fc->chan->num_waiting);
 
        if (fuse_block_alloc(fc, for_background)) {
                err = -EINTR;
-               if (wait_event_state_exclusive(fc->blocked_waitq,
+               if (wait_event_state_exclusive(fc->chan->blocked_waitq,
                                !fuse_block_alloc(fc, for_background),
                                (TASK_KILLABLE | TASK_FREEZABLE)))
                        goto out;
@@ -123,7 +123,7 @@ static struct fuse_req *fuse_get_req(struct mnt_idmap *idmap,
        smp_rmb();
 
        err = -ENOTCONN;
-       if (!fc->connected)
+       if (!fc->chan->connected)
                goto out;
 
        err = -ECONNREFUSED;
@@ -134,7 +134,7 @@ static struct fuse_req *fuse_get_req(struct mnt_idmap *idmap,
        err = -ENOMEM;
        if (!req) {
                if (for_background)
-                       wake_up(&fc->blocked_waitq);
+                       wake_up(&fc->chan->blocked_waitq);
                goto out;
        }
 
@@ -182,8 +182,8 @@ static void fuse_put_request(struct fuse_req *req)
                         * request was allocated but not sent
                         */
                        spin_lock(&fc->chan->bg_lock);
-                       if (!fc->blocked)
-                               wake_up(&fc->blocked_waitq);
+                       if (!fc->chan->blocked)
+                               wake_up(&fc->chan->blocked_waitq);
                        spin_unlock(&fc->chan->bg_lock);
                }
 
@@ -357,7 +357,12 @@ struct fuse_chan *fuse_chan_new(void)
        INIT_LIST_HEAD(&fch->devices);
        spin_lock_init(&fch->bg_lock);
        INIT_LIST_HEAD(&fch->bg_queue);
+       init_waitqueue_head(&fch->blocked_waitq);
+       atomic_set(&fch->num_waiting, 0);
        fch->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
+       fch->initialized = 0;
+       fch->blocked = 0;
+       fch->connected = 1;
 
        return fch;
 }
@@ -426,7 +431,7 @@ void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc)
                 *  - it was already set to a different fc
                 *  - it was set to disconneted
                 */
-               fc->connected = 0;
+               fc->chan->connected = 0;
        } else {
                list_add_tail(&fud->entry, &fc->chan->devices);
                fuse_conn_get(fc);
@@ -503,27 +508,27 @@ static void flush_bg_queue(struct fuse_conn *fc)
        }
 }
 
-void fuse_request_bg_finish(struct fuse_conn *fc, struct fuse_req *req)
+void fuse_request_bg_finish(struct fuse_chan *fch, struct fuse_req *req)
 {
-       lockdep_assert_held(&fc->chan->bg_lock);
+       lockdep_assert_held(&fch->bg_lock);
 
        clear_bit(FR_BACKGROUND, &req->flags);
-       if (fc->chan->num_background == fc->chan->max_background) {
-               fc->blocked = 0;
-               wake_up(&fc->blocked_waitq);
-       } else if (!fc->blocked) {
+       if (fch->num_background == fch->max_background) {
+               fch->blocked = 0;
+               wake_up(&fch->blocked_waitq);
+       } else if (!fch->blocked) {
                /*
                 * Wake up next waiter, if any.  It's okay to use
                 * waitqueue_active(), as we've already synced up
-                * fc->blocked with waiters with the wake_up() call
+                * fch->blocked with waiters with the wake_up() call
                 * above.
                 */
-               if (waitqueue_active(&fc->blocked_waitq))
-                       wake_up(&fc->blocked_waitq);
+               if (waitqueue_active(&fch->blocked_waitq))
+                       wake_up(&fch->blocked_waitq);
        }
 
-       fc->chan->num_background--;
-       fc->chan->active_background--;
+       fch->num_background--;
+       fch->active_background--;
 }
 
 /*
@@ -558,7 +563,7 @@ void fuse_request_end(struct fuse_req *req)
        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, req);
+               fuse_request_bg_finish(fc->chan, req);
                flush_bg_queue(fc);
                spin_unlock(&fc->chan->bg_lock);
        } else {
@@ -737,7 +742,7 @@ ssize_t __fuse_simple_request(struct mnt_idmap *idmap,
        ssize_t ret;
 
        if (args->force) {
-               atomic_inc(&fc->num_waiting);
+               atomic_inc(&fc->chan->num_waiting);
                req = fuse_request_alloc(fm, GFP_KERNEL | __GFP_NOFAIL);
 
                if (!args->nocreds)
@@ -797,7 +802,7 @@ static int fuse_request_queue_background(struct fuse_req *req)
        WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
        if (!test_bit(FR_WAITING, &req->flags)) {
                __set_bit(FR_WAITING, &req->flags);
-               atomic_inc(&fc->num_waiting);
+               atomic_inc(&fc->chan->num_waiting);
        }
        __set_bit(FR_ISREPLY, &req->flags);
 
@@ -807,10 +812,10 @@ static int fuse_request_queue_background(struct fuse_req *req)
 #endif
 
        spin_lock(&fc->chan->bg_lock);
-       if (likely(fc->connected)) {
+       if (likely(fc->chan->connected)) {
                fc->chan->num_background++;
                if (fc->chan->num_background == fc->chan->max_background)
-                       fc->blocked = 1;
+                       fc->chan->blocked = 1;
                list_add_tail(&req->list, &fc->chan->bg_queue);
                flush_bg_queue(fc);
                queued = true;
@@ -2056,7 +2061,7 @@ static void fuse_resend(struct fuse_conn *fc)
        unsigned int i;
 
        spin_lock(&fc->lock);
-       if (!fc->connected) {
+       if (!fc->chan->connected) {
                spin_unlock(&fc->lock);
                return;
        }
@@ -2162,7 +2167,7 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
         * Only allow notifications during while the connection is in an
         * initialized and connected state
         */
-       if (!fc->initialized || !fc->connected)
+       if (!fc->chan->initialized || !fc->chan->connected)
                return -EINVAL;
 
        /* Don't try to move folios (yet) */
@@ -2527,7 +2532,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
        struct fuse_iqueue *fiq = &fc->chan->iq;
 
        spin_lock(&fc->lock);
-       if (fc->connected) {
+       if (fc->chan->connected) {
                struct fuse_dev *fud;
                struct fuse_req *req, *next;
                LIST_HEAD(to_end);
@@ -2536,9 +2541,9 @@ void fuse_abort_conn(struct fuse_conn *fc)
                if (fc->timeout.req_timeout)
                        cancel_delayed_work(&fc->timeout.work);
 
-               /* Background queuing checks fc->connected under bg_lock */
+               /* Background queuing checks fc->chan->connected under bg_lock */
                spin_lock(&fc->chan->bg_lock);
-               fc->connected = 0;
+               fc->chan->connected = 0;
                spin_unlock(&fc->chan->bg_lock);
 
                fuse_set_initialized(fc);
@@ -2564,7 +2569,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
                        spin_unlock(&fpq->lock);
                }
                spin_lock(&fc->chan->bg_lock);
-               fc->blocked = 0;
+               fc->chan->blocked = 0;
                fc->chan->max_background = UINT_MAX;
                flush_bg_queue(fc);
                spin_unlock(&fc->chan->bg_lock);
@@ -2580,7 +2585,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
                spin_unlock(&fiq->lock);
                kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
                end_polls(fc);
-               wake_up_all(&fc->blocked_waitq);
+               wake_up_all(&fc->chan->blocked_waitq);
                spin_unlock(&fc->lock);
 
                fuse_dev_end_requests(&to_end);
@@ -2600,7 +2605,7 @@ void fuse_wait_aborted(struct fuse_conn *fc)
 {
        /* matches implicit memory barrier in fuse_drop_waiting() */
        smp_mb();
-       wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
+       wait_event(fc->chan->blocked_waitq, atomic_read(&fc->chan->num_waiting) == 0);
 
        fuse_uring_wait_stopped_queues(fc);
 }
index 9c553726701e972baee43e7b990c7d2408ce45e0..723f7f2e2b1e7993c6f6b509b99de5988ef802c3 100644 (file)
@@ -90,7 +90,7 @@ static void fuse_uring_req_end(struct fuse_ring_ent *ent, struct fuse_req *req,
        if (test_bit(FR_BACKGROUND, &req->flags)) {
                queue->active_background--;
                spin_lock(&fc->chan->bg_lock);
-               fuse_request_bg_finish(fc, req);
+               fuse_request_bg_finish(fc->chan, req);
                fuse_uring_flush_bg(queue);
                spin_unlock(&fc->chan->bg_lock);
        }
@@ -244,7 +244,7 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
        max_payload_size = max(max_payload_size, fc->max_pages * PAGE_SIZE);
 
        spin_lock(&fc->lock);
-       if (!fc->connected) {
+       if (!fc->chan->connected) {
                spin_unlock(&fc->lock);
                goto out_err;
        }
@@ -917,7 +917,7 @@ static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
                return err;
        fpq = &queue->fpq;
 
-       if (!READ_ONCE(fc->connected))
+       if (!READ_ONCE(fc->chan->connected))
                return err;
 
        spin_lock(&queue->lock);
@@ -1010,7 +1010,7 @@ static int fuse_uring_do_register(struct fuse_ring_ent *ent,
 
        spin_lock(&fc->lock);
        /* abort teardown path is running or has run */
-       if (!fc->connected) {
+       if (!fc->chan->connected) {
                spin_unlock(&fc->lock);
                if (atomic_dec_and_test(&ring->queue_refs))
                        wake_up_all(&ring->stop_waitq);
@@ -1032,7 +1032,7 @@ static int fuse_uring_do_register(struct fuse_ring_ent *ent,
                if (ready) {
                        WRITE_ONCE(fiq->ops, &fuse_io_uring_ops);
                        smp_store_release(&ring->ready, true);
-                       wake_up_all(&fc->blocked_waitq);
+                       wake_up_all(&fc->chan->blocked_waitq);
                }
        }
        return 0;
@@ -1190,14 +1190,14 @@ int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
 
        if (fc->aborted)
                return -ECONNABORTED;
-       if (!fc->connected)
+       if (!fc->chan->connected)
                return -ENOTCONN;
 
        /*
         * fuse_uring_register() needs the ring to be initialized,
         * we need to know the max payload size
         */
-       if (!fc->initialized)
+       if (!fc->chan->initialized)
                return -EAGAIN;
 
        switch (cmd_op) {
@@ -1207,7 +1207,7 @@ int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
                        pr_info_once("FUSE_IO_URING_CMD_REGISTER failed err=%d\n",
                                     err);
                        fc->io_uring = 0;
-                       wake_up_all(&fc->blocked_waitq);
+                       wake_up_all(&fc->chan->blocked_waitq);
                        return err;
                }
                break;
@@ -1373,7 +1373,7 @@ bool fuse_uring_queue_bq_req(struct fuse_req *req)
        spin_lock(&fc->chan->bg_lock);
        fc->chan->num_background++;
        if (fc->chan->num_background == fc->chan->max_background)
-               fc->blocked = 1;
+               fc->chan->blocked = 1;
        fuse_uring_flush_bg(queue);
        spin_unlock(&fc->chan->bg_lock);
 
index db539dbb11f2fc0e88a8e9923e8e64a19e9e06de..3c350dfd31b484dc53a64b9515ded374800caa7b 100644 (file)
@@ -108,6 +108,25 @@ struct fuse_chan {
 
        /** Protects: max_background, num_background, active_background, bg_queue, blocked */
        spinlock_t bg_lock;
+
+       /** Flag indicating that INIT reply has been received. Allocating
+        * any fuse request will be suspended until the flag is set */
+       int initialized;
+
+       /** Flag indicating if connection is blocked.  This will be
+           the case before the INIT reply is received, and if there
+           are too many outstading backgrounds requests */
+       int blocked;
+
+       /** waitq for blocked connection */
+       wait_queue_head_t blocked_waitq;
+
+       /** Connection established, cleared on umount, connection
+           abort and device release */
+       unsigned connected;
+
+       /** The number of requests waiting for completion */
+       atomic_t num_waiting;
 };
 
 #define FUSE_PQ_HASH_BITS 8
@@ -205,7 +224,7 @@ unsigned int fuse_req_hash(u64 unique);
 struct fuse_req *fuse_request_find(struct fuse_pqueue *fpq, u64 unique);
 
 void fuse_dev_end_requests(struct list_head *head);
-void fuse_request_bg_finish(struct fuse_conn *fc, struct fuse_req *req);
+void fuse_request_bg_finish(struct fuse_chan *fch, struct fuse_req *req);
 
 void fuse_copy_init(struct fuse_copy_state *cs, bool write,
                           struct iov_iter *iter);
index ccf0db3a4eeb04e31ddddfb706de7eafe3865ffe..a56e49c7a3249e812b828b95ab8714864a9b8e13 100644 (file)
@@ -569,22 +569,6 @@ struct fuse_conn {
        /** Number of background requests at which congestion starts */
        unsigned congestion_threshold;
 
-       /** Flag indicating that INIT reply has been received. Allocating
-        * any fuse request will be suspended until the flag is set */
-       int initialized;
-
-       /** Flag indicating if connection is blocked.  This will be
-           the case before the INIT reply is received, and if there
-           are too many outstading backgrounds requests */
-       int blocked;
-
-       /** waitq for blocked connection */
-       wait_queue_head_t blocked_waitq;
-
-       /** Connection established, cleared on umount, connection
-           abort and device release */
-       unsigned connected;
-
        /** Connection aborted via sysfs */
        bool aborted;
 
@@ -786,9 +770,6 @@ struct fuse_conn {
        /** Maximum stack depth for passthrough backing files */
        int max_stack_depth;
 
-       /** The number of requests waiting for completion */
-       atomic_t num_waiting;
-
        /** Negotiated minor version */
        unsigned minor;
 
index 6e0ab13b093c9ae2d5cc483b198af34d47b1844b..13d788abe6de1bb64d4a209a73435c4b4d4f5665 100644 (file)
@@ -975,15 +975,10 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
        refcount_set(&fc->count, 1);
        atomic_set(&fc->epoch, 1);
        INIT_WORK(&fc->epoch_work, fuse_epoch_work);
-       init_waitqueue_head(&fc->blocked_waitq);
        INIT_LIST_HEAD(&fc->entry);
-       atomic_set(&fc->num_waiting, 0);
        fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
        atomic64_set(&fc->khctr, 0);
        fc->polled_files = RB_ROOT;
-       fc->blocked = 0;
-       fc->initialized = 0;
-       fc->connected = 1;
        atomic64_set(&fc->attr_version, 1);
        atomic64_set(&fc->evict_ctr, 1);
        get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
@@ -1444,7 +1439,7 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
        }
 
        fuse_set_initialized(fc);
-       wake_up_all(&fc->blocked_waitq);
+       wake_up_all(&fc->chan->blocked_waitq);
 }
 
 static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm)
index ee2b4dc394e0ca084bfc2c2f527591a769abb4d5..ef2e39e4dcf461d3f5388ed2742d73a1fce6fee2 100644 (file)
@@ -74,7 +74,7 @@ static void fuse_check_timeout(struct work_struct *work)
        struct fuse_pqueue *fpq;
        bool expired = false;
 
-       if (!atomic_read(&fc->num_waiting))
+       if (!atomic_read(&fc->chan->num_waiting))
                goto out;
 
        spin_lock(&fiq->lock);
@@ -90,7 +90,7 @@ static void fuse_check_timeout(struct work_struct *work)
                goto abort_conn;
 
        spin_lock(&fc->lock);
-       if (!fc->connected) {
+       if (!fc->chan->connected) {
                spin_unlock(&fc->lock);
                return;
        }