]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fuse: set params in fuse_chan_set_initialized()
authorMiklos Szeredi <mszeredi@redhat.com>
Tue, 31 Mar 2026 13:50:29 +0000 (15:50 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Jun 2026 12:06:17 +0000 (14:06 +0200)
Set minor, max_write and max_pages in the fuse_chan.  These match the same
fields in fuse_conn but are needed in both layers.

[Dongyang Jin: Pointers should use NULL instead of explicit '0']

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

index 41f6a1b9397f5fb3044397d7f7b08c9058f78f22..ec2f53b3d2c8dd5037e9c137f455b5c66179ec26 100644 (file)
@@ -72,8 +72,14 @@ static void __fuse_put_request(struct fuse_req *req)
        refcount_dec(&req->count);
 }
 
-void fuse_chan_set_initialized(struct fuse_chan *fch)
+void fuse_chan_set_initialized(struct fuse_chan *fch, struct fuse_chan_param *param)
 {
+       if (param) {
+               fch->minor = param->minor;
+               fch->max_write = param->max_write;
+               fch->max_pages = param->max_pages;
+       }
+
        /* Make sure stores before this are seen on another CPU */
        smp_wmb();
        fch->initialized = 1;
@@ -719,12 +725,12 @@ static void __fuse_request_send(struct fuse_req *req)
        smp_rmb();
 }
 
-static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
+static void fuse_adjust_compat(struct fuse_chan *fch, struct fuse_args *args)
 {
-       if (fc->minor < 4 && args->opcode == FUSE_STATFS)
+       if (fch->minor < 4 && args->opcode == FUSE_STATFS)
                args->out_args[0].size = FUSE_COMPAT_STATFS_SIZE;
 
-       if (fc->minor < 9) {
+       if (fch->minor < 9) {
                switch (args->opcode) {
                case FUSE_LOOKUP:
                case FUSE_CREATE:
@@ -740,7 +746,7 @@ static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
                        break;
                }
        }
-       if (fc->minor < 12) {
+       if (fch->minor < 12) {
                switch (args->opcode) {
                case FUSE_CREATE:
                        args->in_args[0].size = sizeof(struct fuse_open_in);
@@ -784,8 +790,8 @@ ssize_t fuse_chan_send(struct fuse_chan *fch, struct fuse_args *args)
                        return PTR_ERR(req);
        }
 
-       /* Needs to be done after fuse_get_req() so that fc->minor is valid */
-       fuse_adjust_compat(fch->conn, args);
+       /* Needs to be done after fuse_get_req() so that fch->minor is valid */
+       fuse_adjust_compat(fch, args);
        fuse_args_to_req(req, args);
 
        if (!args->noreply)
@@ -1466,12 +1472,12 @@ __releases(fiq->lock)
        return ih.len;
 }
 
-static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
+static int fuse_read_forget(struct fuse_chan *fch, struct fuse_iqueue *fiq,
                            struct fuse_copy_state *cs,
                            size_t nbytes)
 __releases(fiq->lock)
 {
-       if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
+       if (fch->minor < 16 || fiq->forget_list_head.next->next == NULL)
                return fuse_read_single_forget(fiq, cs, nbytes);
        else
                return fuse_read_batch_forget(fiq, cs, nbytes);
@@ -1513,7 +1519,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
        if (nbytes < max_t(size_t, FUSE_MIN_READ_BUFFER,
                           sizeof(struct fuse_in_header) +
                           sizeof(struct fuse_write_in) +
-                          fch->conn->max_write))
+                          fch->max_write))
                return -EINVAL;
 
  restart:
@@ -1544,7 +1550,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
 
        if (forget_pending(fiq)) {
                if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0)
-                       return fuse_read_forget(fch->conn, fiq, cs, nbytes);
+                       return fuse_read_forget(fch, fiq, cs, nbytes);
 
                if (fiq->forget_batch <= -8)
                        fiq->forget_batch = 16;
@@ -2123,7 +2129,7 @@ void fuse_chan_abort(struct fuse_chan *fch, bool abort_with_err)
                fch->connected = 0;
                spin_unlock(&fch->bg_lock);
 
-               fuse_chan_set_initialized(fch);
+               fuse_chan_set_initialized(fch, NULL);
                list_for_each_entry(fud, &fch->devices, entry) {
                        struct fuse_pqueue *fpq = &fud->pq;
 
index 2bf4aba256d12e6c57c580c47c9bd0087f7e4b0d..6437331058d93767a8878c9ad6e189c1d57831e9 100644 (file)
@@ -17,6 +17,12 @@ struct file;
 struct folio;
 enum fuse_notify_code;
 
+struct fuse_chan_param {
+       unsigned int minor;
+       unsigned int max_write;
+       unsigned int max_pages;
+};
+
 struct fuse_chan *fuse_chan_new(void);
 struct fuse_chan *fuse_dev_chan_new(void);
 void fuse_chan_release(struct fuse_chan *fch);
@@ -26,7 +32,7 @@ unsigned int fuse_chan_max_background(struct fuse_chan *fch);
 void fuse_chan_max_background_set(struct fuse_chan *fch, unsigned int val);
 unsigned int fuse_chan_num_waiting(struct fuse_chan *fch);
 void fuse_chan_set_fc(struct fuse_chan *fch, struct fuse_conn *fc);
-void fuse_chan_set_initialized(struct fuse_chan *fch);
+void fuse_chan_set_initialized(struct fuse_chan *fch, struct fuse_chan_param *param);
 void fuse_chan_io_uring_enable(struct fuse_chan *fch);
 ssize_t fuse_chan_send(struct fuse_chan *fch, struct fuse_args *args);
 int fuse_chan_send_bg(struct fuse_chan *fch, struct fuse_args *args, gfp_t gfp_flags);
index 109e3d07c3f152ce332cb4d70117ac6ecee1b655..73dc886d967bb926e908cba96b66198080cc75e0 100644 (file)
@@ -241,8 +241,8 @@ static struct fuse_ring *fuse_uring_create(struct fuse_chan *fch)
        if (!ring->queues)
                goto out_err;
 
-       max_payload_size = max(FUSE_MIN_READ_BUFFER, fch->conn->max_write);
-       max_payload_size = max(max_payload_size, fch->conn->max_pages * PAGE_SIZE);
+       max_payload_size = max(FUSE_MIN_READ_BUFFER, fch->max_write);
+       max_payload_size = max(max_payload_size, fch->max_pages * PAGE_SIZE);
 
        spin_lock(&fch->lock);
        if (!fch->connected) {
index 35475a2f6f0a8cbbde2306b32f73f52cf36f12b3..6550952f815bf4b49ce4acfbaee4f862fe9a977d 100644 (file)
@@ -238,6 +238,15 @@ struct fuse_chan {
        /* Use io_uring for communication */
        unsigned int io_uring;
 
+       /* Negotiated minor version */
+       unsigned int minor;
+
+       /* Maximum write size */
+       unsigned int max_write;
+
+       /* Maximum number of pages that can be used in a single request */
+       unsigned int max_pages;
+
        /** Connection aborted via sysfs, respond with ECONNABORTED on device I/O */
        bool abort_with_err;
 
index 9e96bacdfc3e921b39b98db93b05e6746aff9f1e..79047734ab4064809ca6d3dffaee09eda6cbe037 100644 (file)
@@ -1426,9 +1426,15 @@ static void process_init_reply(struct fuse_args *args, int error)
        if (!ok) {
                fc->conn_init = 0;
                fc->conn_error = 1;
+               fuse_chan_set_initialized(fc->chan, NULL);
+       } else {
+               struct fuse_chan_param cp = {
+                       .minor = fc->minor,
+                       .max_write = fc->max_write,
+                       .max_pages = fc->max_pages,
+               };
+               fuse_chan_set_initialized(fc->chan, &cp);
        }
-
-       fuse_chan_set_initialized(fc->chan);
 }
 
 static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm)