Skip to content

Commit 9b17cb5

Browse files
joannekoongMiklos Szeredi
authored andcommitted
fuse: add default_request_timeout and max_request_timeout sysctls
Introduce two new sysctls, "default_request_timeout" and "max_request_timeout". These control how long (in seconds) a server can take to reply to a request. If the server does not reply by the timeout, then the connection will be aborted. The upper bound on these sysctl values is 65535. "default_request_timeout" sets the default timeout if no timeout is specified by the fuse server on mount. 0 (default) indicates no default timeout should be enforced. If the server did specify a timeout, then default_request_timeout will be ignored. "max_request_timeout" sets the max amount of time the server may take to reply to a request. 0 (default) indicates no maximum timeout. If max_request_timeout is set and the fuse server attempts to set a timeout greater than max_request_timeout, the system will use max_request_timeout as the timeout. Similarly, if default_request_timeout is greater than max_request_timeout, the system will use max_request_timeout as the timeout. If the server does not request a timeout and default_request_timeout is set to 0 but max_request_timeout is set, then the timeout will be max_request_timeout. Please note that these timeouts are not 100% precise. The request may take roughly an extra FUSE_TIMEOUT_TIMER_FREQ seconds beyond the set max timeout due to how it's internally implemented. $ sysctl -a | grep fuse.default_request_timeout fs.fuse.default_request_timeout = 0 $ echo 65536 | sudo tee /proc/sys/fs/fuse/default_request_timeout tee: /proc/sys/fs/fuse/default_request_timeout: Invalid argument $ echo 65535 | sudo tee /proc/sys/fs/fuse/default_request_timeout 65535 $ sysctl -a | grep fuse.default_request_timeout fs.fuse.default_request_timeout = 65535 $ echo 0 | sudo tee /proc/sys/fs/fuse/default_request_timeout 0 $ sysctl -a | grep fuse.default_request_timeout fs.fuse.default_request_timeout = 0 [Luis Henriques: Limit the timeout to the range [FUSE_TIMEOUT_TIMER_FREQ, fuse_max_req_timeout]] Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org> Reviewed-by: Luis Henriques <luis@igalia.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent 0f6439f commit 9b17cb5

File tree

5 files changed

+90
-5
lines changed

5 files changed

+90
-5
lines changed

Documentation/admin-guide/sysctl/fs.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,28 @@ filesystems:
347347
``/proc/sys/fs/fuse/max_pages_limit`` is a read/write file for
348348
setting/getting the maximum number of pages that can be used for servicing
349349
requests in FUSE.
350+
351+
``/proc/sys/fs/fuse/default_request_timeout`` is a read/write file for
352+
setting/getting the default timeout (in seconds) for a fuse server to
353+
reply to a kernel-issued request in the event where the server did not
354+
specify a timeout at mount. If the server set a timeout,
355+
then default_request_timeout will be ignored. The default
356+
"default_request_timeout" is set to 0. 0 indicates no default timeout.
357+
The maximum value that can be set is 65535.
358+
359+
``/proc/sys/fs/fuse/max_request_timeout`` is a read/write file for
360+
setting/getting the maximum timeout (in seconds) for a fuse server to
361+
reply to a kernel-issued request. A value greater than 0 automatically opts
362+
the server into a timeout that will be set to at most "max_request_timeout",
363+
even if the server did not specify a timeout and default_request_timeout is
364+
set to 0. If max_request_timeout is greater than 0 and the server set a timeout
365+
greater than max_request_timeout or default_request_timeout is set to a value
366+
greater than max_request_timeout, the system will use max_request_timeout as the
367+
timeout. 0 indicates no max request timeout. The maximum value that can be set
368+
is 65535.
369+
370+
For timeouts, if the server does not respond to the request by the time
371+
the set timeout elapses, then the connection to the fuse server will be aborted.
372+
Please note that the timeouts are not 100% precise (eg you may set 60 seconds but
373+
the timeout may kick in after 70 seconds). The upper margin of error for the
374+
timeout is roughly FUSE_TIMEOUT_TIMER_FREQ seconds.

fs/fuse/dev.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ MODULE_ALIAS("devname:fuse");
3232

3333
static struct kmem_cache *fuse_req_cachep;
3434

35-
/* Frequency (in seconds) of request timeout checks, if opted into */
36-
#define FUSE_TIMEOUT_TIMER_FREQ 15
37-
3835
const unsigned long fuse_timeout_timer_freq =
3936
secs_to_jiffies(FUSE_TIMEOUT_TIMER_FREQ);
4037

fs/fuse/fuse_i.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,24 @@
4444
/** Number of dentries for each connection in the control filesystem */
4545
#define FUSE_CTL_NUM_DENTRIES 5
4646

47+
/* Frequency (in seconds) of request timeout checks, if opted into */
48+
#define FUSE_TIMEOUT_TIMER_FREQ 15
49+
4750
/** Frequency (in jiffies) of request timeout checks, if opted into */
4851
extern const unsigned long fuse_timeout_timer_freq;
4952

5053
/** Maximum of max_pages received in init_out */
5154
extern unsigned int fuse_max_pages_limit;
55+
/*
56+
* Default timeout (in seconds) for the server to reply to a request
57+
* before the connection is aborted, if no timeout was specified on mount.
58+
*/
59+
extern unsigned int fuse_default_req_timeout;
60+
/*
61+
* Max timeout (in seconds) for the server to reply to a request before
62+
* the connection is aborted.
63+
*/
64+
extern unsigned int fuse_max_req_timeout;
5265

5366
/** List of active connections */
5467
extern struct list_head fuse_conn_list;

fs/fuse/inode.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ DEFINE_MUTEX(fuse_mutex);
3737
static int set_global_limit(const char *val, const struct kernel_param *kp);
3838

3939
unsigned int fuse_max_pages_limit = 256;
40+
/* default is no timeout */
41+
unsigned int fuse_default_req_timeout;
42+
unsigned int fuse_max_req_timeout;
4043

4144
unsigned max_user_bgreq;
4245
module_param_call(max_user_bgreq, set_global_limit, param_get_uint,
@@ -1268,6 +1271,26 @@ static void set_request_timeout(struct fuse_conn *fc, unsigned int timeout)
12681271
fuse_timeout_timer_freq);
12691272
}
12701273

1274+
static void init_server_timeout(struct fuse_conn *fc, unsigned int timeout)
1275+
{
1276+
if (!timeout && !fuse_max_req_timeout && !fuse_default_req_timeout)
1277+
return;
1278+
1279+
if (!timeout)
1280+
timeout = fuse_default_req_timeout;
1281+
1282+
if (fuse_max_req_timeout) {
1283+
if (timeout)
1284+
timeout = min(fuse_max_req_timeout, timeout);
1285+
else
1286+
timeout = fuse_max_req_timeout;
1287+
}
1288+
1289+
timeout = max(FUSE_TIMEOUT_TIMER_FREQ, timeout);
1290+
1291+
set_request_timeout(fc, timeout);
1292+
}
1293+
12711294
struct fuse_init_args {
12721295
struct fuse_args args;
12731296
struct fuse_init_in in;
@@ -1286,6 +1309,7 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
12861309
ok = false;
12871310
else {
12881311
unsigned long ra_pages;
1312+
unsigned int timeout = 0;
12891313

12901314
process_init_limits(fc, arg);
12911315

@@ -1404,14 +1428,16 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
14041428
if (flags & FUSE_OVER_IO_URING && fuse_uring_enabled())
14051429
fc->io_uring = 1;
14061430

1407-
if ((flags & FUSE_REQUEST_TIMEOUT) && arg->request_timeout)
1408-
set_request_timeout(fc, arg->request_timeout);
1431+
if (flags & FUSE_REQUEST_TIMEOUT)
1432+
timeout = arg->request_timeout;
14091433
} else {
14101434
ra_pages = fc->max_read / PAGE_SIZE;
14111435
fc->no_lock = 1;
14121436
fc->no_flock = 1;
14131437
}
14141438

1439+
init_server_timeout(fc, timeout);
1440+
14151441
fm->sb->s_bdi->ra_pages =
14161442
min(fm->sb->s_bdi->ra_pages, ra_pages);
14171443
fc->minor = arg->minor;

fs/fuse/sysctl.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ static struct ctl_table_header *fuse_table_header;
1313
/* Bound by fuse_init_out max_pages, which is a u16 */
1414
static unsigned int sysctl_fuse_max_pages_limit = 65535;
1515

16+
/*
17+
* fuse_init_out request timeouts are u16.
18+
* This goes up to ~18 hours, which is plenty for a timeout.
19+
*/
20+
static unsigned int sysctl_fuse_req_timeout_limit = 65535;
21+
1622
static const struct ctl_table fuse_sysctl_table[] = {
1723
{
1824
.procname = "max_pages_limit",
@@ -23,6 +29,24 @@ static const struct ctl_table fuse_sysctl_table[] = {
2329
.extra1 = SYSCTL_ONE,
2430
.extra2 = &sysctl_fuse_max_pages_limit,
2531
},
32+
{
33+
.procname = "default_request_timeout",
34+
.data = &fuse_default_req_timeout,
35+
.maxlen = sizeof(fuse_default_req_timeout),
36+
.mode = 0644,
37+
.proc_handler = proc_douintvec_minmax,
38+
.extra1 = SYSCTL_ZERO,
39+
.extra2 = &sysctl_fuse_req_timeout_limit,
40+
},
41+
{
42+
.procname = "max_request_timeout",
43+
.data = &fuse_max_req_timeout,
44+
.maxlen = sizeof(fuse_max_req_timeout),
45+
.mode = 0644,
46+
.proc_handler = proc_douintvec_minmax,
47+
.extra1 = SYSCTL_ZERO,
48+
.extra2 = &sysctl_fuse_req_timeout_limit,
49+
},
2650
};
2751

2852
int fuse_sysctl_register(void)

0 commit comments

Comments
 (0)