mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
fuse: don't access transport layer structs directly from the fs layer
Add helpers (get and set functions mainly) that cleanly separate the layers. Remove #include "fuse_dev_i.h" from: - inode.c - file.c - control.c Remove #include "dev_uring_i.h" from inode.c. [Li Wang: drop redundant initializer in process_init_limits()] Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
c1265fe499
commit
b6d83d4e3e
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
#include "fuse_i.h"
|
||||
#include "fuse_dev_i.h"
|
||||
#include "dev.h"
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
|
|
@ -58,7 +58,7 @@ static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf,
|
|||
if (!fc)
|
||||
return 0;
|
||||
|
||||
value = atomic_read(&fc->chan->num_waiting);
|
||||
value = fuse_chan_num_waiting(fc->chan);
|
||||
file->private_data = (void *)value;
|
||||
fuse_conn_put(fc);
|
||||
}
|
||||
|
|
@ -112,7 +112,7 @@ static ssize_t fuse_conn_max_background_read(struct file *file,
|
|||
if (!fc)
|
||||
return 0;
|
||||
|
||||
val = READ_ONCE(fc->chan->max_background);
|
||||
val = fuse_chan_max_background(fc->chan);
|
||||
fuse_conn_put(fc);
|
||||
|
||||
return fuse_conn_limit_read(file, buf, len, ppos, val);
|
||||
|
|
@ -130,12 +130,7 @@ static ssize_t fuse_conn_max_background_write(struct file *file,
|
|||
if (ret > 0) {
|
||||
struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
|
||||
if (fc) {
|
||||
spin_lock(&fc->chan->bg_lock);
|
||||
fc->chan->max_background = val;
|
||||
fc->chan->blocked = fc->chan->num_background >= fc->chan->max_background;
|
||||
if (!fc->chan->blocked)
|
||||
wake_up(&fc->chan->blocked_waitq);
|
||||
spin_unlock(&fc->chan->bg_lock);
|
||||
fuse_chan_max_background_set(fc->chan, val);
|
||||
fuse_conn_put(fc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,11 +70,12 @@ static void __fuse_put_request(struct fuse_req *req)
|
|||
refcount_dec(&req->count);
|
||||
}
|
||||
|
||||
void fuse_set_initialized(struct fuse_conn *fc)
|
||||
void fuse_chan_set_initialized(struct fuse_chan *fch)
|
||||
{
|
||||
/* Make sure stores before this are seen on another CPU */
|
||||
smp_wmb();
|
||||
fc->chan->initialized = 1;
|
||||
fch->initialized = 1;
|
||||
wake_up_all(&fch->blocked_waitq);
|
||||
}
|
||||
|
||||
static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
|
||||
|
|
@ -119,7 +120,7 @@ static struct fuse_req *fuse_get_req(struct mnt_idmap *idmap,
|
|||
(TASK_KILLABLE | TASK_FREEZABLE)))
|
||||
goto out;
|
||||
}
|
||||
/* Matches smp_wmb() in fuse_set_initialized() */
|
||||
/* Matches smp_wmb() in fuse_chan_set_initialized() */
|
||||
smp_rmb();
|
||||
|
||||
err = -ENOTCONN;
|
||||
|
|
@ -339,6 +340,9 @@ void fuse_chan_release(struct fuse_chan *fch)
|
|||
|
||||
if (fiq->ops->release)
|
||||
fiq->ops->release(fiq);
|
||||
|
||||
if (fch->timeout.req_timeout)
|
||||
cancel_delayed_work_sync(&fch->timeout.work);
|
||||
}
|
||||
|
||||
void fuse_chan_free(struct fuse_chan *fch)
|
||||
|
|
@ -382,6 +386,41 @@ struct fuse_chan *fuse_dev_chan_new(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(fuse_dev_chan_new);
|
||||
|
||||
unsigned int fuse_chan_num_background(struct fuse_chan *fch)
|
||||
{
|
||||
return fch->num_background;
|
||||
}
|
||||
|
||||
unsigned int fuse_chan_max_background(struct fuse_chan *fch)
|
||||
{
|
||||
return READ_ONCE(fch->max_background);
|
||||
}
|
||||
|
||||
void fuse_chan_max_background_set(struct fuse_chan *fch, unsigned int val)
|
||||
{
|
||||
spin_lock(&fch->bg_lock);
|
||||
fch->max_background = val;
|
||||
fch->blocked = fch->num_background >= fch->max_background;
|
||||
if (!fch->blocked)
|
||||
wake_up(&fch->blocked_waitq);
|
||||
spin_unlock(&fch->bg_lock);
|
||||
}
|
||||
|
||||
unsigned int fuse_chan_num_waiting(struct fuse_chan *fch)
|
||||
{
|
||||
return atomic_read(&fch->num_waiting);
|
||||
}
|
||||
|
||||
void fuse_chan_set_fc(struct fuse_chan *fch, struct fuse_conn *fc)
|
||||
{
|
||||
fch->conn = fc;
|
||||
}
|
||||
|
||||
void fuse_chan_io_uring_enable(struct fuse_chan *fch)
|
||||
{
|
||||
fch->io_uring = 1;
|
||||
}
|
||||
|
||||
void fuse_pqueue_init(struct fuse_pqueue *fpq)
|
||||
{
|
||||
unsigned int i;
|
||||
|
|
@ -476,6 +515,34 @@ void fuse_dev_put(struct fuse_dev *fud)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(fuse_dev_put);
|
||||
|
||||
bool fuse_dev_is_installed(struct fuse_dev *fud)
|
||||
{
|
||||
struct fuse_conn *fc = fuse_dev_fc_get(fud);
|
||||
|
||||
return fc != NULL && fc != FUSE_DEV_FC_DISCONNECTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if @fc matches the one installed in @fud
|
||||
*/
|
||||
bool fuse_dev_verify(struct fuse_dev *fud, struct fuse_conn *fc)
|
||||
{
|
||||
return fuse_dev_fc_get(fud) == fc;
|
||||
}
|
||||
|
||||
bool fuse_dev_is_sync_init(struct fuse_dev *fud)
|
||||
{
|
||||
return fud->sync_init;
|
||||
}
|
||||
|
||||
struct fuse_dev *fuse_dev_grab(struct file *file)
|
||||
{
|
||||
struct fuse_dev *fud = fuse_file_to_fud(file);
|
||||
|
||||
refcount_inc(&fud->ref);
|
||||
return fud;
|
||||
}
|
||||
|
||||
static void fuse_send_one(struct fuse_iqueue *fiq, struct fuse_req *req)
|
||||
{
|
||||
req->in.h.len = sizeof(struct fuse_in_header) +
|
||||
|
|
@ -2550,7 +2617,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
|
|||
fc->chan->connected = 0;
|
||||
spin_unlock(&fc->chan->bg_lock);
|
||||
|
||||
fuse_set_initialized(fc);
|
||||
fuse_chan_set_initialized(fc->chan);
|
||||
list_for_each_entry(fud, &fc->chan->devices, entry) {
|
||||
struct fuse_pqueue *fpq = &fud->pq;
|
||||
|
||||
|
|
@ -2609,7 +2676,7 @@ void fuse_wait_aborted(struct fuse_conn *fc)
|
|||
{
|
||||
/* matches implicit memory barrier in fuse_drop_waiting() */
|
||||
smp_mb();
|
||||
wait_event(fc->chan->blocked_waitq, atomic_read(&fc->chan->num_waiting) == 0);
|
||||
wait_event(fc->chan->blocked_waitq, fuse_chan_num_waiting(fc->chan) == 0);
|
||||
|
||||
fuse_uring_wait_stopped_queues(fc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,16 +11,43 @@
|
|||
struct fuse_conn;
|
||||
struct fuse_chan;
|
||||
struct fuse_dev;
|
||||
struct file;
|
||||
|
||||
struct fuse_chan *fuse_chan_new(void);
|
||||
struct fuse_chan *fuse_dev_chan_new(void);
|
||||
void fuse_chan_release(struct fuse_chan *fch);
|
||||
void fuse_chan_free(struct fuse_chan *fch);
|
||||
unsigned int fuse_chan_num_background(struct fuse_chan *fch);
|
||||
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_io_uring_enable(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);
|
||||
bool fuse_dev_verify(struct fuse_dev *fud, struct fuse_conn *fc);
|
||||
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);
|
||||
struct fuse_dev *fuse_dev_grab(struct file *file);
|
||||
|
||||
void fuse_init_server_timeout(struct fuse_chan *fch, unsigned int timeout);
|
||||
|
||||
#ifdef CONFIG_FUSE_IO_URING
|
||||
bool fuse_uring_enabled(void);
|
||||
void fuse_uring_destruct(struct fuse_chan *fch);
|
||||
#else /* CONFIG_FUSE_IO_URING */
|
||||
static inline bool fuse_uring_enabled(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void fuse_uring_destruct(struct fuse_chan *fch)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_FUSE_IO_URING */
|
||||
|
||||
#endif /* _FS_FUSE_DEV_H */
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright (c) 2023-2024 DataDirect Networks.
|
||||
*/
|
||||
|
||||
#include "dev.h"
|
||||
#include "fuse_i.h"
|
||||
#include "dev_uring_i.h"
|
||||
#include "fuse_dev_i.h"
|
||||
|
|
@ -185,9 +186,9 @@ bool fuse_uring_request_expired(struct fuse_chan *fch)
|
|||
return false;
|
||||
}
|
||||
|
||||
void fuse_uring_destruct(struct fuse_conn *fc)
|
||||
void fuse_uring_destruct(struct fuse_chan *fch)
|
||||
{
|
||||
struct fuse_ring *ring = fc->chan->ring;
|
||||
struct fuse_ring *ring = fch->ring;
|
||||
int qid;
|
||||
|
||||
if (!ring)
|
||||
|
|
@ -218,7 +219,7 @@ void fuse_uring_destruct(struct fuse_conn *fc)
|
|||
|
||||
kfree(ring->queues);
|
||||
kfree(ring);
|
||||
fc->chan->ring = NULL;
|
||||
fch->ring = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -136,8 +136,6 @@ struct fuse_ring {
|
|||
bool ready;
|
||||
};
|
||||
|
||||
bool fuse_uring_enabled(void);
|
||||
void fuse_uring_destruct(struct fuse_conn *fc);
|
||||
void fuse_uring_stop_queues(struct fuse_ring *ring);
|
||||
void fuse_uring_abort_end_requests(struct fuse_ring *ring);
|
||||
int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags);
|
||||
|
|
@ -177,15 +175,6 @@ static inline bool fuse_uring_ready(struct fuse_conn *fc)
|
|||
|
||||
#else /* CONFIG_FUSE_IO_URING */
|
||||
|
||||
static inline void fuse_uring_destruct(struct fuse_conn *fc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool fuse_uring_enabled(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void fuse_uring_abort(struct fuse_conn *fc)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
#include "fuse_i.h"
|
||||
#include "fuse_dev_i.h"
|
||||
#include "dev.h"
|
||||
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -909,7 +909,7 @@ static int fuse_handle_readahead(struct folio *folio,
|
|||
ia = NULL;
|
||||
}
|
||||
if (!ia) {
|
||||
if (fc->chan->num_background >= fc->congestion_threshold &&
|
||||
if (fuse_chan_num_background(fc->chan) >= fc->congestion_threshold &&
|
||||
rac->ra->async_size >= readahead_count(rac))
|
||||
/*
|
||||
* Congested and only async pages left, so skip the
|
||||
|
|
@ -2301,7 +2301,7 @@ static int fuse_writepages(struct address_space *mapping,
|
|||
return -EIO;
|
||||
|
||||
if (wbc->sync_mode == WB_SYNC_NONE &&
|
||||
fc->chan->num_background >= fc->congestion_threshold)
|
||||
fuse_chan_num_background(fc->chan) >= fc->congestion_threshold)
|
||||
return 0;
|
||||
|
||||
return iomap_writepages(&wpc);
|
||||
|
|
|
|||
|
|
@ -1184,8 +1184,6 @@ int fuse_write_inode(struct inode *inode, struct writeback_control *wbc);
|
|||
int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr, struct file *file);
|
||||
|
||||
void fuse_set_initialized(struct fuse_conn *fc);
|
||||
|
||||
void fuse_unlock_inode(struct inode *inode, bool locked);
|
||||
bool fuse_lock_inode(struct inode *inode);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
#include "dev.h"
|
||||
#include "fuse_i.h"
|
||||
#include "fuse_dev_i.h"
|
||||
#include "dev_uring_i.h"
|
||||
|
||||
#include <linux/dax.h>
|
||||
#include <linux/pagemap.h>
|
||||
|
|
@ -812,8 +810,7 @@ static int fuse_opt_fd(struct fs_context *fsc, struct file *file)
|
|||
if (file->f_cred->user_ns != fsc->user_ns)
|
||||
return invalfc(fsc, "wrong user namespace for fuse device");
|
||||
|
||||
ctx->fud = file->private_data;
|
||||
refcount_inc(&ctx->fud->ref);
|
||||
ctx->fud = fuse_dev_grab(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -994,7 +991,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
|
|||
INIT_LIST_HEAD(&fc->mounts);
|
||||
list_add(&fm->fc_entry, &fc->mounts);
|
||||
fm->fc = fc;
|
||||
fch->conn = fc;
|
||||
fuse_chan_set_fc(fch, fc);
|
||||
fc->chan = fch;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fuse_conn_init);
|
||||
|
|
@ -1003,7 +1000,7 @@ static void delayed_release(struct rcu_head *p)
|
|||
{
|
||||
struct fuse_conn *fc = container_of(p, struct fuse_conn, rcu);
|
||||
|
||||
fuse_uring_destruct(fc);
|
||||
fuse_uring_destruct(fc->chan);
|
||||
fuse_chan_free(fc->chan);
|
||||
|
||||
put_user_ns(fc->user_ns);
|
||||
|
|
@ -1019,8 +1016,6 @@ void fuse_conn_put(struct fuse_conn *fc)
|
|||
|
||||
if (IS_ENABLED(CONFIG_FUSE_DAX))
|
||||
fuse_dax_conn_free(fc);
|
||||
if (fc->chan->timeout.req_timeout)
|
||||
cancel_delayed_work_sync(&fc->chan->timeout.work);
|
||||
cancel_work_sync(&fc->epoch_work);
|
||||
fuse_chan_release(fc->chan);
|
||||
put_pid_ns(fc->pid_ns);
|
||||
|
|
@ -1253,12 +1248,13 @@ static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)
|
|||
sanitize_global_limit(&max_user_bgreq);
|
||||
sanitize_global_limit(&max_user_congthresh);
|
||||
|
||||
spin_lock(&fc->chan->bg_lock);
|
||||
if (arg->max_background) {
|
||||
fc->chan->max_background = arg->max_background;
|
||||
unsigned int max_background = arg->max_background;
|
||||
|
||||
if (!cap_sys_admin && fc->chan->max_background > max_user_bgreq)
|
||||
fc->chan->max_background = max_user_bgreq;
|
||||
if (!cap_sys_admin && max_background > max_user_bgreq)
|
||||
max_background = max_user_bgreq;
|
||||
|
||||
fuse_chan_max_background_set(fc->chan, max_background);
|
||||
}
|
||||
if (arg->congestion_threshold) {
|
||||
fc->congestion_threshold = arg->congestion_threshold;
|
||||
|
|
@ -1267,7 +1263,6 @@ static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)
|
|||
fc->congestion_threshold > max_user_congthresh)
|
||||
fc->congestion_threshold = max_user_congthresh;
|
||||
}
|
||||
spin_unlock(&fc->chan->bg_lock);
|
||||
}
|
||||
|
||||
struct fuse_init_args {
|
||||
|
|
@ -1412,7 +1407,7 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
|
|||
ok = false;
|
||||
}
|
||||
if (flags & FUSE_OVER_IO_URING && fuse_uring_enabled())
|
||||
fc->chan->io_uring = 1;
|
||||
fuse_chan_io_uring_enable(fc->chan);
|
||||
|
||||
if (flags & FUSE_REQUEST_TIMEOUT)
|
||||
timeout = arg->request_timeout;
|
||||
|
|
@ -1438,8 +1433,7 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
|
|||
fc->conn_error = 1;
|
||||
}
|
||||
|
||||
fuse_set_initialized(fc);
|
||||
wake_up_all(&fc->chan->blocked_waitq);
|
||||
fuse_chan_set_initialized(fc->chan);
|
||||
}
|
||||
|
||||
static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm)
|
||||
|
|
@ -1788,9 +1782,9 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
|
|||
mutex_lock(&fuse_mutex);
|
||||
err = -EINVAL;
|
||||
if (fud) {
|
||||
if (fuse_dev_fc_get(fud))
|
||||
if (fuse_dev_is_installed(fud))
|
||||
goto err_unlock;
|
||||
if (fud->sync_init)
|
||||
if (fuse_dev_is_sync_init(fud))
|
||||
fc->sync_init = 1;
|
||||
}
|
||||
|
||||
|
|
@ -1848,9 +1842,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)
|
||||
{
|
||||
struct fuse_dev *fud = fsc->sget_key;
|
||||
|
||||
return fuse_dev_fc_get(fud) == get_fuse_conn_super(sb);
|
||||
return fuse_dev_verify(fsc->sget_key, get_fuse_conn_super(sb));
|
||||
}
|
||||
|
||||
static int fuse_get_tree(struct fs_context *fsc)
|
||||
|
|
@ -1896,7 +1888,7 @@ static int fuse_get_tree(struct fs_context *fsc)
|
|||
* Allow creating a fuse mount with an already initialized fuse
|
||||
* connection
|
||||
*/
|
||||
if (fuse_dev_fc_get(ctx->fud)) {
|
||||
if (fuse_dev_is_installed(ctx->fud)) {
|
||||
fsc->sget_key = ctx->fud;
|
||||
sb = sget_fc(fsc, fuse_test_super, fuse_set_no_super);
|
||||
err = PTR_ERR_OR_ZERO(sb);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user