A dedicated "timeout" sysfs attribute has been introduced for each fuse connection, empowering users to manage and control the timeout duration for individual connections. This is a preparation for the followup patch. Signed-off-by: Yafang Shao <laoar.shao@xxxxxxxxx> --- fs/fuse/control.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++- fs/fuse/fuse_i.h | 5 ++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 97ac994ff78f..247fbec72cda 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -180,6 +180,44 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file, return ret; } +static ssize_t fuse_conn_timeout_read(struct file *file, + char __user *buf, size_t len, + loff_t *ppos) +{ + struct fuse_conn *fc; + u32 val; + + fc = fuse_ctl_file_conn_get(file); + if (!fc) + return 0; + + val = READ_ONCE(fc->timeout); + fuse_conn_put(fc); + return fuse_conn_limit_read(file, buf, len, ppos, val); +} + +static ssize_t fuse_conn_timeout_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct fuse_conn *fc; + ssize_t ret; + u32 val; + + ret = fuse_conn_limit_write(file, buf, count, ppos, &val, + 3600); + if (ret <= 0) + goto out; + fc = fuse_ctl_file_conn_get(file); + if (!fc) + goto out; + + WRITE_ONCE(fc->timeout, val); + fuse_conn_put(fc); +out: + return ret; +} + static const struct file_operations fuse_ctl_abort_ops = { .open = nonseekable_open, .write = fuse_conn_abort_write, @@ -206,6 +244,13 @@ static const struct file_operations fuse_conn_congestion_threshold_ops = { .llseek = no_llseek, }; +static const struct file_operations fuse_conn_timeout_ops = { + .open = nonseekable_open, + .read = fuse_conn_timeout_read, + .write = fuse_conn_timeout_write, + .llseek = no_llseek, +}; + static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, struct fuse_conn *fc, const char *name, @@ -274,7 +319,10 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) 1, NULL, &fuse_conn_max_background_ops) || !fuse_ctl_add_dentry(parent, fc, "congestion_threshold", S_IFREG | 0600, 1, NULL, - &fuse_conn_congestion_threshold_ops)) + &fuse_conn_congestion_threshold_ops) || + !fuse_ctl_add_dentry(parent, fc, "timeout", + S_IFREG | 0600, 1, NULL, + &fuse_conn_timeout_ops)) goto err; return 0; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index f23919610313..367601bf7285 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -45,7 +45,7 @@ #define FUSE_NAME_MAX 1024 /** Number of dentries for each connection in the control filesystem */ -#define FUSE_CTL_NUM_DENTRIES 5 +#define FUSE_CTL_NUM_DENTRIES 6 /** List of active connections */ extern struct list_head fuse_conn_list; @@ -917,6 +917,9 @@ struct fuse_conn { /** IDR for backing files ids */ struct idr backing_files_map; #endif + + /* fuse request timeout */ + u32 timeout; }; /* -- 2.43.5