fuse: move fuse_dev and fuse_pqueue to dev.c

Move function definitions to dev.c, struct definitions to fuse_dev_i.h.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Miklos Szeredi 2026-03-17 12:44:31 +01:00
parent b88fb2b92b
commit d8189630a1
5 changed files with 144 additions and 140 deletions

View File

@ -365,6 +365,100 @@ struct fuse_chan *fuse_dev_chan_new(void)
}
EXPORT_SYMBOL_GPL(fuse_dev_chan_new);
void fuse_pqueue_init(struct fuse_pqueue *fpq)
{
unsigned int i;
spin_lock_init(&fpq->lock);
for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
INIT_LIST_HEAD(&fpq->processing[i]);
INIT_LIST_HEAD(&fpq->io);
fpq->connected = 1;
}
struct fuse_dev *fuse_dev_alloc(void)
{
struct fuse_dev *fud;
struct list_head *pq;
fud = kzalloc_obj(struct fuse_dev);
if (!fud)
return NULL;
refcount_set(&fud->ref, 1);
pq = kzalloc_objs(struct list_head, FUSE_PQ_HASH_SIZE);
if (!pq) {
kfree(fud);
return NULL;
}
fud->pq.processing = pq;
fuse_pqueue_init(&fud->pq);
return fud;
}
EXPORT_SYMBOL_GPL(fuse_dev_alloc);
void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc)
{
struct fuse_conn *old_fc;
spin_lock(&fc->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) {
/*
* failed to set fud->fc because
* - it was already set to a different fc
* - it was set to disconneted
*/
fc->connected = 0;
} else {
list_add_tail(&fud->entry, &fc->devices);
fuse_conn_get(fc);
}
spin_unlock(&fc->lock);
}
EXPORT_SYMBOL_GPL(fuse_dev_install);
struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc)
{
struct fuse_dev *fud;
fud = fuse_dev_alloc();
if (!fud)
return NULL;
fuse_dev_install(fud, fc);
return fud;
}
EXPORT_SYMBOL_GPL(fuse_dev_alloc_install);
void fuse_dev_put(struct fuse_dev *fud)
{
struct fuse_conn *fc;
if (!refcount_dec_and_test(&fud->ref))
return;
fc = fuse_dev_fc_get(fud);
if (fc && fc != FUSE_DEV_FC_DISCONNECTED) {
/* This is the virtiofs case (fuse_dev_release() not called) */
spin_lock(&fc->lock);
list_del(&fud->entry);
spin_unlock(&fc->lock);
fuse_conn_put(fc);
}
kfree(fud->pq.processing);
kfree(fud);
}
EXPORT_SYMBOL_GPL(fuse_dev_put);
static void fuse_send_one(struct fuse_iqueue *fiq, struct fuse_req *req)
{
req->in.h.len = sizeof(struct fuse_in_header) +

View File

@ -7,6 +7,7 @@
struct fuse_conn;
struct fuse_chan;
struct fuse_dev;
struct fuse_chan *fuse_chan_new(void);
struct fuse_chan *fuse_dev_chan_new(void);
@ -14,6 +15,9 @@ void fuse_chan_release(struct fuse_chan *fch);
void fuse_chan_free(struct fuse_chan *fch);
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);
void fuse_dev_put(struct fuse_dev *fud);
void fuse_init_server_timeout(struct fuse_conn *fc, unsigned int timeout);
#endif /* _FS_FUSE_DEV_H */

View File

@ -92,6 +92,43 @@ struct fuse_chan {
struct fuse_iqueue iq;
};
#define FUSE_PQ_HASH_BITS 8
#define FUSE_PQ_HASH_SIZE (1 << FUSE_PQ_HASH_BITS)
struct fuse_pqueue {
/** Connection established */
unsigned connected;
/** Lock protecting accessess to members of this structure */
spinlock_t lock;
/** Hash table of requests being processed */
struct list_head *processing;
/** The list of requests under I/O */
struct list_head io;
};
/**
* Fuse device instance
*/
struct fuse_dev {
/** Reference count of this object */
refcount_t ref;
/** Issue FUSE_INIT synchronously */
bool sync_init;
/** Fuse connection for this device */
struct fuse_conn *fc;
/** Processing queue */
struct fuse_pqueue pq;
/** list entry on fc->devices */
struct list_head entry;
};
struct fuse_copy_state {
struct fuse_req *req;
struct iov_iter *iter;
@ -177,5 +214,14 @@ 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(void);
/**
* Initialize the fuse processing queue
*/
void fuse_pqueue_init(struct fuse_pqueue *fpq);
#endif

View File

@ -469,43 +469,6 @@ struct fuse_req {
unsigned long create_time;
};
#define FUSE_PQ_HASH_BITS 8
#define FUSE_PQ_HASH_SIZE (1 << FUSE_PQ_HASH_BITS)
struct fuse_pqueue {
/** Connection established */
unsigned connected;
/** Lock protecting accessess to members of this structure */
spinlock_t lock;
/** Hash table of requests being processed */
struct list_head *processing;
/** The list of requests under I/O */
struct list_head io;
};
/**
* Fuse device instance
*/
struct fuse_dev {
/** Reference count of this object */
refcount_t ref;
/** Issue FUSE_INIT synchronously */
bool sync_init;
/** Fuse connection for this device */
struct fuse_conn *fc;
/** Processing queue */
struct fuse_pqueue pq;
/** list entry on fc->devices */
struct list_head entry;
};
enum fuse_dax_mode {
FUSE_DAX_INODE_DEFAULT, /* default */
FUSE_DAX_ALWAYS, /* "-o dax=always" */
@ -1227,11 +1190,6 @@ void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o);
*/
struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
/**
* Initialize the fuse processing queue
*/
void fuse_pqueue_init(struct fuse_pqueue *fpq);
/**
* Initialize fuse_conn
*/
@ -1243,10 +1201,6 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
*/
void fuse_conn_put(struct fuse_conn *fc);
struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc);
struct fuse_dev *fuse_dev_alloc(void);
void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc);
void fuse_dev_put(struct fuse_dev *fud);
int fuse_send_init(struct fuse_mount *fm);
/**

View File

@ -969,17 +969,6 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
return 0;
}
void fuse_pqueue_init(struct fuse_pqueue *fpq)
{
unsigned int i;
spin_lock_init(&fpq->lock);
for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
INIT_LIST_HEAD(&fpq->processing[i]);
INIT_LIST_HEAD(&fpq->io);
fpq->connected = 1;
}
void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
struct user_namespace *user_ns, struct fuse_chan *fch)
{
@ -1597,89 +1586,6 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
return 0;
}
struct fuse_dev *fuse_dev_alloc(void)
{
struct fuse_dev *fud;
struct list_head *pq;
fud = kzalloc_obj(struct fuse_dev);
if (!fud)
return NULL;
refcount_set(&fud->ref, 1);
pq = kzalloc_objs(struct list_head, FUSE_PQ_HASH_SIZE);
if (!pq) {
kfree(fud);
return NULL;
}
fud->pq.processing = pq;
fuse_pqueue_init(&fud->pq);
return fud;
}
EXPORT_SYMBOL_GPL(fuse_dev_alloc);
void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc)
{
struct fuse_conn *old_fc;
spin_lock(&fc->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) {
/*
* failed to set fud->fc because
* - it was already set to a different fc
* - it was set to disconneted
*/
fc->connected = 0;
} else {
list_add_tail(&fud->entry, &fc->devices);
fuse_conn_get(fc);
}
spin_unlock(&fc->lock);
}
EXPORT_SYMBOL_GPL(fuse_dev_install);
struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc)
{
struct fuse_dev *fud;
fud = fuse_dev_alloc();
if (!fud)
return NULL;
fuse_dev_install(fud, fc);
return fud;
}
EXPORT_SYMBOL_GPL(fuse_dev_alloc_install);
void fuse_dev_put(struct fuse_dev *fud)
{
struct fuse_conn *fc;
if (!refcount_dec_and_test(&fud->ref))
return;
fc = fuse_dev_fc_get(fud);
if (fc && fc != FUSE_DEV_FC_DISCONNECTED) {
/* This is the virtiofs case (fuse_dev_release() not called) */
spin_lock(&fc->lock);
list_del(&fud->entry);
spin_unlock(&fc->lock);
fuse_conn_put(fc);
}
kfree(fud->pq.processing);
kfree(fud);
}
EXPORT_SYMBOL_GPL(fuse_dev_put);
static void fuse_fill_attr_from_inode(struct fuse_attr *attr,
const struct fuse_inode *fi)
{