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 <mszeredi@redhat.com>
This commit is contained in:
Miklos Szeredi 2026-03-31 15:50:29 +02:00
parent ca46a4aca6
commit ff572265f2
5 changed files with 44 additions and 17 deletions

View 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;

View 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);

View 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) {

View 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;

View 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)