fuse: change fud->fc to fud->chan

Store pointer to struct fuse_chan instead of struct fuse_conn in fuse_dev.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Miklos Szeredi 2026-03-30 14:27:23 +02:00
parent 794e811d14
commit 994d807943
7 changed files with 95 additions and 95 deletions

View File

@ -523,7 +523,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
*/
fuse_conn_init(&cc->fc, &cc->fm, file->f_cred->user_ns, no_free_ptr(fch));
cc->fc.release = cuse_fc_release;
fud = fuse_dev_alloc_install(&cc->fc);
fud = fuse_dev_alloc_install(cc->fc.chan);
fuse_conn_put(&cc->fc);
if (!fud)
return -ENOMEM;
@ -555,7 +555,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
static int cuse_channel_release(struct inode *inode, struct file *file)
{
struct fuse_dev *fud = __fuse_get_dev(file);
struct cuse_conn *cc = fc_to_cc(fud->fc);
struct cuse_conn *cc = fc_to_cc(fud->chan->conn);
/* remove from the conntbl, no more access from this point on */
mutex_lock(&cuse_lock);

View File

@ -431,34 +431,34 @@ struct fuse_dev *fuse_dev_alloc(void)
}
EXPORT_SYMBOL_GPL(fuse_dev_alloc);
void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc)
void fuse_dev_install(struct fuse_dev *fud, struct fuse_chan *fch)
{
struct fuse_conn *old_fc;
struct fuse_chan *old_fch;
spin_lock(&fc->chan->lock);
spin_lock(&fch->lock);
/*
* Pairs with:
* - xchg() in fuse_dev_release()
* - smp_load_acquire() in fuse_dev_fc_get()
*/
old_fc = cmpxchg(&fud->fc, NULL, fc);
if (old_fc) {
old_fch = cmpxchg(&fud->chan, NULL, fch);
if (old_fch) {
/*
* failed to set fud->fc because
* failed to set fud->chan because
* - it was already set to a different fc
* - it was set to disconneted
*/
fc->chan->connected = 0;
fch->connected = 0;
} else {
list_add_tail(&fud->entry, &fc->chan->devices);
fuse_conn_get(fc);
list_add_tail(&fud->entry, &fch->devices);
fuse_conn_get(fch->conn);
wake_up_all(&fuse_dev_waitq);
}
spin_unlock(&fc->chan->lock);
spin_unlock(&fch->lock);
}
EXPORT_SYMBOL_GPL(fuse_dev_install);
struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc)
struct fuse_dev *fuse_dev_alloc_install(struct fuse_chan *fch)
{
struct fuse_dev *fud;
@ -466,26 +466,26 @@ struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc)
if (!fud)
return NULL;
fuse_dev_install(fud, fc);
fuse_dev_install(fud, fch);
return fud;
}
EXPORT_SYMBOL_GPL(fuse_dev_alloc_install);
void fuse_dev_put(struct fuse_dev *fud)
{
struct fuse_conn *fc;
struct fuse_chan *fch;
if (!refcount_dec_and_test(&fud->ref))
return;
fc = fuse_dev_fc_get(fud);
if (fc && fc != FUSE_DEV_FC_DISCONNECTED) {
fch = fuse_dev_chan_get(fud);
if (fch && fch != FUSE_DEV_CHAN_DISCONNECTED) {
/* This is the virtiofs case (fuse_dev_release() not called) */
spin_lock(&fc->chan->lock);
spin_lock(&fch->lock);
list_del(&fud->entry);
spin_unlock(&fc->chan->lock);
spin_unlock(&fch->lock);
fuse_conn_put(fc);
fuse_conn_put(fch->conn);
}
kfree(fud->pq.processing);
kfree(fud);
@ -494,17 +494,17 @@ EXPORT_SYMBOL_GPL(fuse_dev_put);
bool fuse_dev_is_installed(struct fuse_dev *fud)
{
struct fuse_conn *fc = fuse_dev_fc_get(fud);
struct fuse_chan *fch = fuse_dev_chan_get(fud);
return fc != NULL && fc != FUSE_DEV_FC_DISCONNECTED;
return fch != NULL && fch != FUSE_DEV_CHAN_DISCONNECTED;
}
/*
* Checks if @fc matches the one installed in @fud
*/
bool fuse_dev_verify(struct fuse_dev *fud, struct fuse_conn *fc)
bool fuse_dev_verify(struct fuse_dev *fud, struct fuse_chan *fch)
{
return fuse_dev_fc_get(fud) == fc;
return fuse_dev_chan_get(fud) == fch;
}
bool fuse_dev_is_sync_init(struct fuse_dev *fud)
@ -1490,8 +1490,8 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
struct fuse_copy_state *cs, size_t nbytes)
{
ssize_t err;
struct fuse_conn *fc = fud->fc;
struct fuse_iqueue *fiq = &fc->chan->iq;
struct fuse_chan *fch = fud->chan;
struct fuse_iqueue *fiq = &fch->iq;
struct fuse_pqueue *fpq = &fud->pq;
struct fuse_req *req;
struct fuse_args *args;
@ -1513,7 +1513,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) +
fc->max_write))
fch->conn->max_write))
return -EINVAL;
restart:
@ -1532,7 +1532,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
}
if (!fiq->connected) {
err = fc->chan->abort_with_err ? -ECONNABORTED : -ENODEV;
err = fch->abort_with_err ? -ECONNABORTED : -ENODEV;
goto err_unlock;
}
@ -1544,7 +1544,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(fc, fiq, cs, nbytes);
return fuse_read_forget(fch->conn, fiq, cs, nbytes);
if (fiq->forget_batch <= -8)
fiq->forget_batch = 16;
@ -1588,7 +1588,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
spin_lock(&fpq->lock);
clear_bit(FR_LOCKED, &req->flags);
if (!fpq->connected) {
err = fc->chan->abort_with_err ? -ECONNABORTED : -ENODEV;
err = fch->abort_with_err ? -ECONNABORTED : -ENODEV;
goto out_end;
}
if (err) {
@ -1640,12 +1640,12 @@ struct fuse_dev *fuse_get_dev(struct file *file)
struct fuse_dev *fud = fuse_file_to_fud(file);
int err;
if (unlikely(!fuse_dev_fc_get(fud))) {
if (unlikely(!fuse_dev_chan_get(fud))) {
/* only block waiting for mount if sync init was requested */
if (!fud->sync_init)
return ERR_PTR(-EPERM);
err = wait_event_interruptible(fuse_dev_waitq, fuse_dev_fc_get(fud) != NULL);
err = wait_event_interruptible(fuse_dev_waitq, fuse_dev_chan_get(fud) != NULL);
if (err)
return ERR_PTR(err);
}
@ -2276,7 +2276,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
struct fuse_copy_state *cs, size_t nbytes)
{
int err;
struct fuse_conn *fc = fud->fc;
struct fuse_chan *fch = fud->chan;
struct fuse_pqueue *fpq = &fud->pq;
struct fuse_req *req;
struct fuse_out_header oh;
@ -2298,7 +2298,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
* and error contains notification code.
*/
if (!oh.unique) {
err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs);
err = fuse_notify(fch->conn, oh.error, nbytes - sizeof(oh), cs);
goto copy_finish;
}
@ -2326,7 +2326,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
if (nbytes != sizeof(struct fuse_out_header))
err = -EINVAL;
else if (oh.error == -ENOSYS)
fc->chan->no_interrupt = true;
fch->no_interrupt = 1;
else if (oh.error == -EAGAIN)
err = queue_interrupt(req);
@ -2486,7 +2486,7 @@ static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
if (IS_ERR(fud))
return EPOLLERR;
fiq = &fud->fc->chan->iq;
fiq = &fud->chan->iq;
poll_wait(file, &fiq->waitq, wait);
spin_lock(&fiq->lock);
@ -2636,9 +2636,9 @@ int fuse_dev_release(struct inode *inode, struct file *file)
{
struct fuse_dev *fud = fuse_file_to_fud(file);
/* Pairs with cmpxchg() in fuse_dev_install() */
struct fuse_conn *fc = xchg(&fud->fc, FUSE_DEV_FC_DISCONNECTED);
struct fuse_chan *fch = xchg(&fud->chan, FUSE_DEV_CHAN_DISCONNECTED);
if (fc) {
if (fch) {
struct fuse_pqueue *fpq = &fud->pq;
LIST_HEAD(to_end);
unsigned int i;
@ -2652,17 +2652,17 @@ int fuse_dev_release(struct inode *inode, struct file *file)
fuse_dev_end_requests(&to_end);
spin_lock(&fc->chan->lock);
spin_lock(&fch->lock);
list_del(&fud->entry);
/* Are we the last open device? */
last = list_empty(&fc->chan->devices);
spin_unlock(&fc->chan->lock);
last = list_empty(&fch->devices);
spin_unlock(&fch->lock);
if (last) {
WARN_ON(fc->chan->iq.fasync != NULL);
fuse_chan_abort(fc->chan, false);
WARN_ON(fch->iq.fasync != NULL);
fuse_chan_abort(fch, false);
}
fuse_conn_put(fc);
fuse_conn_put(fch->conn);
}
fuse_dev_put(fud);
return 0;
@ -2677,7 +2677,7 @@ static int fuse_dev_fasync(int fd, struct file *file, int on)
return PTR_ERR(fud);
/* No locking - fasync_helper does its own locking */
return fasync_helper(fd, file, on, &fud->fc->chan->iq.fasync);
return fasync_helper(fd, file, on, &fud->chan->iq.fasync);
}
static long fuse_dev_ioctl_clone(struct file *file, __u32 __user *argp)
@ -2704,10 +2704,10 @@ static long fuse_dev_ioctl_clone(struct file *file, __u32 __user *argp)
return PTR_ERR(fud);
new_fud = fuse_file_to_fud(file);
if (fuse_dev_fc_get(new_fud))
if (fuse_dev_chan_get(new_fud))
return -EINVAL;
fuse_dev_install(new_fud, fud->fc);
fuse_dev_install(new_fud, fud->chan);
return 0;
}
@ -2727,7 +2727,7 @@ static long fuse_dev_ioctl_backing_open(struct file *file,
if (copy_from_user(&map, argp, sizeof(map)))
return -EFAULT;
return fuse_backing_open(fud->fc, &map);
return fuse_backing_open(fud->chan->conn, &map);
}
static long fuse_dev_ioctl_backing_close(struct file *file, __u32 __user *argp)
@ -2744,7 +2744,7 @@ static long fuse_dev_ioctl_backing_close(struct file *file, __u32 __user *argp)
if (get_user(backing_id, argp))
return -EFAULT;
return fuse_backing_close(fud->fc, backing_id);
return fuse_backing_close(fud->chan->conn, backing_id);
}
static long fuse_dev_ioctl_sync_init(struct file *file)
@ -2753,7 +2753,7 @@ static long fuse_dev_ioctl_sync_init(struct file *file)
struct fuse_dev *fud = fuse_file_to_fud(file);
mutex_lock(&fuse_mutex);
if (!fuse_dev_fc_get(fud)) {
if (!fuse_dev_chan_get(fud)) {
fud->sync_init = true;
err = 0;
}
@ -2791,7 +2791,7 @@ static void fuse_dev_show_fdinfo(struct seq_file *seq, struct file *file)
if (!fud)
return;
seq_printf(seq, "fuse_connection:\t%u\n", fud->fc->dev);
seq_printf(seq, "fuse_connection:\t%u\n", fud->chan->conn->dev);
}
#endif

View File

@ -36,8 +36,8 @@ void fuse_chan_queue_forget(struct fuse_chan *fch, struct fuse_forget_link *forg
DEFINE_FREE(fuse_chan_free, struct fuse_chan *, if (_T) fuse_chan_free(_T))
void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc);
bool fuse_dev_verify(struct fuse_dev *fud, struct fuse_conn *fc);
void fuse_dev_install(struct fuse_dev *fud, struct fuse_chan *fch);
bool fuse_dev_verify(struct fuse_dev *fud, struct fuse_chan *fch);
void fuse_dev_put(struct fuse_dev *fud);
bool fuse_dev_is_installed(struct fuse_dev *fud);
bool fuse_dev_is_sync_init(struct fuse_dev *fud);

View File

@ -225,14 +225,14 @@ void fuse_uring_destruct(struct fuse_chan *fch)
/*
* Basic ring setup for this connection based on the provided configuration
*/
static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
static struct fuse_ring *fuse_uring_create(struct fuse_chan *fch)
{
struct fuse_ring *ring;
size_t nr_queues = num_possible_cpus();
struct fuse_ring *res = NULL;
size_t max_payload_size;
ring = kzalloc_obj(*fc->chan->ring, GFP_KERNEL_ACCOUNT);
ring = kzalloc_obj(*ring, GFP_KERNEL_ACCOUNT);
if (!ring)
return NULL;
@ -241,29 +241,29 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
if (!ring->queues)
goto out_err;
max_payload_size = max(FUSE_MIN_READ_BUFFER, fc->max_write);
max_payload_size = max(max_payload_size, fc->max_pages * PAGE_SIZE);
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);
spin_lock(&fc->chan->lock);
if (!fc->chan->connected) {
spin_unlock(&fc->chan->lock);
spin_lock(&fch->lock);
if (!fch->connected) {
spin_unlock(&fch->lock);
goto out_err;
}
if (fc->chan->ring) {
if (fch->ring) {
/* race, another thread created the ring in the meantime */
spin_unlock(&fc->chan->lock);
res = fc->chan->ring;
spin_unlock(&fch->lock);
res = fch->ring;
goto out_err;
}
init_waitqueue_head(&ring->stop_waitq);
ring->nr_queues = nr_queues;
ring->fc = fc;
ring->fc = fch->conn;
ring->max_payload_sz = max_payload_size;
smp_store_release(&fc->chan->ring, ring);
smp_store_release(&fch->ring, ring);
spin_unlock(&fc->chan->lock);
spin_unlock(&fch->lock);
return ring;
out_err:
@ -893,13 +893,13 @@ static int fuse_ring_ent_set_commit(struct fuse_ring_ent *ent)
/* FUSE_URING_CMD_COMMIT_AND_FETCH handler */
static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
struct fuse_conn *fc)
struct fuse_chan *fch)
{
const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe128_cmd(cmd->sqe,
struct fuse_uring_cmd_req);
struct fuse_ring_ent *ent;
int err;
struct fuse_ring *ring = fc->chan->ring;
struct fuse_ring *ring = fch->ring;
struct fuse_ring_queue *queue;
uint64_t commit_id = READ_ONCE(cmd_req->commit_id);
unsigned int qid = READ_ONCE(cmd_req->qid);
@ -918,7 +918,7 @@ static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
return err;
fpq = &queue->fpq;
if (!READ_ONCE(fc->chan->connected))
if (!READ_ONCE(fch->connected))
return err;
spin_lock(&queue->lock);
@ -1115,11 +1115,11 @@ fuse_uring_create_ring_ent(struct io_uring_cmd *cmd,
* entry as "ready to get fuse requests" on the queue
*/
static int fuse_uring_register(struct io_uring_cmd *cmd,
unsigned int issue_flags, struct fuse_conn *fc)
unsigned int issue_flags, struct fuse_chan *fch)
{
const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe128_cmd(cmd->sqe,
struct fuse_uring_cmd_req);
struct fuse_ring *ring = smp_load_acquire(&fc->chan->ring);
struct fuse_ring *ring = smp_load_acquire(&fch->ring);
struct fuse_ring_queue *queue;
struct fuse_ring_ent *ent;
int err;
@ -1127,7 +1127,7 @@ static int fuse_uring_register(struct io_uring_cmd *cmd,
err = -ENOMEM;
if (!ring) {
ring = fuse_uring_create(fc);
ring = fuse_uring_create(fch);
if (!ring)
return err;
}
@ -1163,7 +1163,7 @@ static int fuse_uring_register(struct io_uring_cmd *cmd,
int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
{
struct fuse_dev *fud;
struct fuse_conn *fc;
struct fuse_chan *fch;
u32 cmd_op = cmd->cmd_op;
int err;
@ -1181,39 +1181,39 @@ int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
pr_info_ratelimited("No fuse device found\n");
return PTR_ERR(fud);
}
fc = fud->fc;
fch = fud->chan;
/* Once a connection has io-uring enabled on it, it can't be disabled */
if (!enable_uring && !fc->chan->io_uring) {
if (!enable_uring && !fch->io_uring) {
pr_info_ratelimited("fuse-io-uring is disabled\n");
return -EOPNOTSUPP;
}
if (fc->chan->abort_with_err)
if (fch->abort_with_err)
return -ECONNABORTED;
if (!fc->chan->connected)
if (!fch->connected)
return -ENOTCONN;
/*
* fuse_uring_register() needs the ring to be initialized,
* we need to know the max payload size
*/
if (!fc->chan->initialized)
if (!fch->initialized)
return -EAGAIN;
switch (cmd_op) {
case FUSE_IO_URING_CMD_REGISTER:
err = fuse_uring_register(cmd, issue_flags, fc);
err = fuse_uring_register(cmd, issue_flags, fch);
if (err) {
pr_info_once("FUSE_IO_URING_CMD_REGISTER failed err=%d\n",
err);
fc->chan->io_uring = 0;
wake_up_all(&fc->chan->blocked_waitq);
fch->io_uring = 0;
wake_up_all(&fch->blocked_waitq);
return err;
}
break;
case FUSE_IO_URING_CMD_COMMIT_AND_FETCH:
err = fuse_uring_commit_fetch(cmd, issue_flags, fc);
err = fuse_uring_commit_fetch(cmd, issue_flags, fch);
if (err) {
pr_info_once("FUSE_IO_URING_COMMIT_AND_FETCH failed err=%d\n",
err);

View File

@ -283,8 +283,8 @@ struct fuse_dev {
/** Issue FUSE_INIT synchronously */
bool sync_init;
/** Fuse connection for this device */
struct fuse_conn *fc;
/** Fuse channel for this device */
struct fuse_chan *chan;
/** Processing queue */
struct fuse_pqueue pq;
@ -311,21 +311,21 @@ struct fuse_copy_state {
} ring;
};
/* fud->fc gets assigned to this value when /dev/fuse is closed */
#define FUSE_DEV_FC_DISCONNECTED ((struct fuse_conn *) 1)
/* fud->chan gets assigned to this value when /dev/fuse is closed */
#define FUSE_DEV_CHAN_DISCONNECTED ((struct fuse_chan *) 1)
/*
* Lockless access is OK, because fud->fc is set once during mount and is valid
* Lockless access is OK, because fud->chan is set once during mount and is valid
* until the file is released.
*
* fud->fc is set to FUSE_DEV_FC_DISCONNECTED only after the containing file is
* fud->chan is set to FUSE_DEV_CHAN_DISCONNECTED only after the containing file is
* released, so result is safe to dereference in most cases. Exceptions are:
* fuse_dev_put() and fuse_fill_super_common().
*/
static inline struct fuse_conn *fuse_dev_fc_get(struct fuse_dev *fud)
static inline struct fuse_chan *fuse_dev_chan_get(struct fuse_dev *fud)
{
/* Pairs with xchg() in fuse_dev_install() */
return smp_load_acquire(&fud->fc);
return smp_load_acquire(&fud->chan);
}
static inline struct fuse_dev *fuse_file_to_fud(struct file *file)
@ -337,7 +337,7 @@ static inline struct fuse_dev *__fuse_get_dev(struct file *file)
{
struct fuse_dev *fud = fuse_file_to_fud(file);
if (!fuse_dev_fc_get(fud))
if (!fuse_dev_chan_get(fud))
return NULL;
return fud;
@ -378,7 +378,7 @@ void fuse_request_assign_unique(struct fuse_iqueue *fiq, struct fuse_req *req);
*/
u64 fuse_get_unique(struct fuse_iqueue *fiq);
struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc);
struct fuse_dev *fuse_dev_alloc_install(struct fuse_chan *fch);
struct fuse_dev *fuse_dev_alloc(void);
/**

View File

@ -1791,7 +1791,7 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
list_add_tail(&fc->entry, &fuse_conn_list);
sb->s_root = root_dentry;
if (fud)
fuse_dev_install(fud, fc);
fuse_dev_install(fud, fc->chan);
mutex_unlock(&fuse_mutex);
return 0;
@ -1837,7 +1837,7 @@ static int fuse_set_no_super(struct super_block *sb, struct fs_context *fsc)
static int fuse_test_super(struct super_block *sb, struct fs_context *fsc)
{
return fuse_dev_verify(fsc->sget_key, get_fuse_conn_super(sb));
return fuse_dev_verify(fsc->sget_key, get_fuse_conn_super(sb)->chan);
}
static int fuse_get_tree(struct fs_context *fsc)

View File

@ -1607,7 +1607,7 @@ static int virtio_fs_fill_super(struct super_block *sb, struct fs_context *fsc)
for (i = 0; i < fs->nvqs; i++) {
struct virtio_fs_vq *fsvq = &fs->vqs[i];
fuse_dev_install(fsvq->fud, fc);
fuse_dev_install(fsvq->fud, fc->chan);
}
/* Previous unmount will stop all queues. Start these again */