From: Miklos Szeredi Date: Tue, 31 Mar 2026 13:50:29 +0000 (+0200) Subject: fuse: set params in fuse_chan_set_initialized() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ff572265f29e4ad6d2fe5f625d9bbd741a187266;p=thirdparty%2Flinux.git fuse: set params in fuse_chan_set_initialized() 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 --- diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 41f6a1b9397f5..ec2f53b3d2c8d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -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; diff --git a/fs/fuse/dev.h b/fs/fuse/dev.h index 2bf4aba256d12..6437331058d93 100644 --- a/fs/fuse/dev.h +++ b/fs/fuse/dev.h @@ -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); diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index 109e3d07c3f15..73dc886d967bb 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -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) { diff --git a/fs/fuse/fuse_dev_i.h b/fs/fuse/fuse_dev_i.h index 35475a2f6f0a8..6550952f815bf 100644 --- a/fs/fuse/fuse_dev_i.h +++ b/fs/fuse/fuse_dev_i.h @@ -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; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 9e96bacdfc3e9..79047734ab406 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -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)