Skip to content

Commit 631cbc3

Browse files
fuse: make fuse max-write param tunable
Since kernel 4.20, the FUSE driver introduced the max-pages feature. To enhance write performance, this patch exports a new mount option fuse-max-write to let users specify the maximum write bytes for FUSE. The max-pages parameter for fuse connection will be adjusted accordingly. Updates: #4500 Signed-off-by: chenjinhao <[email protected]>
1 parent a9f3973 commit 631cbc3

File tree

7 files changed

+53
-4
lines changed

7 files changed

+53
-4
lines changed

contrib/fuse-include/fuse_kernel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ struct fuse_file_lock {
285285
#define FUSE_MAX_PAGES (1 << 22)
286286
#define FUSE_CACHE_SYMLINKS (1 << 23)
287287

288+
#define FUSE_MAX_MAX_PAGES 256
289+
288290
/**
289291
* CUSE INIT request/reply flags
290292
*

glusterfsd/src/glusterfsd.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ static struct argp_option gf_options[] = {
271271
{"fuse-handle-copy_file_range", ARGP_FUSE_HANDLE_COPY_FILE_RANGE, "BOOL",
272272
OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
273273
"enable the handler of the FUSE_COPY_FILE_RANGE message"},
274+
{"fuse-max-write", ARGP_FUSE_MAX_WRITE_KEY, "INTEGER", OPTION_ARG_OPTIONAL,
275+
"set fuse max-write bytes"},
274276
{0, 0, 0, 0, "Miscellaneous Options:"},
275277
{
276278
0,
@@ -566,6 +568,11 @@ set_fuse_mount_options(glusterfs_ctx_t *ctx, dict_t *options)
566568
break;
567569
}
568570

571+
if (cmd_args->fuse_max_write) {
572+
DICT_SET_VAL(dict_set_uint32, options, "fuse-max-write",
573+
cmd_args->fuse_max_write, glusterfsd_msg_3);
574+
}
575+
569576
if (cmd_args->fs_display_name) {
570577
DICT_SET_VAL(dict_set_dynstr, options, "fs-display-name",
571578
cmd_args->fs_display_name, glusterfsd_msg_3);
@@ -1463,6 +1470,19 @@ parse_opts(int key, char *arg, struct argp_state *state)
14631470
"unknown fuse handle copy_file_range setting \"%s\"",
14641471
arg);
14651472
break;
1473+
case ARGP_FUSE_MAX_WRITE_KEY:
1474+
if (gf_string2uint32(arg, &cmd_args->fuse_max_write)) {
1475+
argp_failure(state, -1, 0, "unknown fuse max-write option %s",
1476+
arg);
1477+
} else if ((cmd_args->fuse_max_write < 4096) ||
1478+
(cmd_args->fuse_max_write > 1048576)) {
1479+
argp_failure(state, -1, 0,
1480+
"Invalid fuse max-write bytes %s. "
1481+
"Valid range: [\"4096, 1048576\"]",
1482+
arg);
1483+
}
1484+
1485+
break;
14661486
}
14671487
return 0;
14681488
}

glusterfsd/src/glusterfsd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ enum argp_option_keys {
118118
ARGP_FUSE_INODE_TABLESIZE_KEY = 198,
119119
ARGP_FUSE_SETLK_HANDLE_INTERRUPT_KEY = 199,
120120
ARGP_FUSE_HANDLE_COPY_FILE_RANGE = 200,
121+
ARGP_FUSE_MAX_WRITE_KEY = 201,
121122
};
122123

123124
int

libglusterfs/src/glusterfs/glusterfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ struct _cmd_args {
592592
int fuse_auto_inval;
593593

594594
uint32_t fuse_dev_eperm_ratelimit_ns;
595+
uint32_t fuse_max_write;
595596

596597
bool global_threading;
597598
bool brick_mux;

xlators/mount/fuse/src/fuse-bridge.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5154,6 +5154,14 @@ fuse_init(xlator_t *this, fuse_in_header_t *finh, void *msg,
51545154
fino.max_readahead = 1 << 17;
51555155
fino.max_write = 1 << 17;
51565156
fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
5157+
#if FUSE_KERNEL_MINOR_VERSION >= 28
5158+
if (fini->minor >= 28) {
5159+
fino.max_write = priv->fuse_max_write;
5160+
fino.max_pages = priv->fuse_max_write / sysconf(_SC_PAGESIZE);
5161+
if (fino.max_pages == FUSE_MAX_MAX_PAGES)
5162+
fino.flags |= FUSE_MAX_PAGES;
5163+
}
5164+
#endif
51575165
#if FUSE_KERNEL_MINOR_VERSION >= 17
51585166
if (fini->minor >= 17)
51595167
fino.flags |= FUSE_FLOCK_LOCKS;
@@ -6090,14 +6098,12 @@ fuse_thread_proc(void *data)
60906098
struct pollfd pfd[2] = {{
60916099
0,
60926100
}};
6093-
uint32_t psize;
60946101

60956102
this = data;
60966103
priv = this->private;
60976104

60986105
THIS = this;
60996106

6100-
psize = ((struct iobuf_pool *)this->ctx->iobuf_pool)->default_page_size;
61016107
priv->msg0_len_p = &msg0_size;
61026108

61036109
for (;;) {
@@ -6153,7 +6159,7 @@ fuse_thread_proc(void *data)
61536159
size from 'fuse', which is as of today 128KB. If we bring in
61546160
support for higher block sizes support, then we should be
61556161
changing this one too */
6156-
iobuf = iobuf_get(this->ctx->iobuf_pool);
6162+
iobuf = iobuf_get2(this->ctx->iobuf_pool, priv->fuse_max_write);
61576163

61586164
/* Add extra 512 byte to the first iov so that it can
61596165
* accommodate "ordinary" non-write requests. It's not
@@ -6177,7 +6183,7 @@ fuse_thread_proc(void *data)
61776183
iov_in[1].iov_base = iobuf->ptr;
61786184

61796185
iov_in[0].iov_len = msg0_size;
6180-
iov_in[1].iov_len = psize;
6186+
iov_in[1].iov_len = priv->fuse_max_write;
61816187

61826188
res = sys_readv(priv->fd, iov_in, 2);
61836189

@@ -6910,6 +6916,9 @@ init(xlator_t *this_xl)
69106916
GF_OPTION_INIT("fuse-dev-eperm-ratelimit-ns",
69116917
priv->fuse_dev_eperm_ratelimit_ns, uint32, cleanup_exit);
69126918

6919+
GF_OPTION_INIT("fuse-max-write", priv->fuse_max_write, uint32,
6920+
cleanup_exit);
6921+
69136922
/* user has set only background-qlen, not congestion-threshold,
69146923
use the fuse kernel driver formula to set congestion. ie, 75% */
69156924
if (dict_get(this_xl->options, "background-qlen") &&
@@ -7198,6 +7207,14 @@ struct volume_options options[] = {
71987207
.max = 64,
71997208
.description = "Sets fuse reader thread count.",
72007209
},
7210+
{
7211+
.key = {"fuse-max-write"},
7212+
.type = GF_OPTION_TYPE_INT,
7213+
.default_value = "131072",
7214+
.min = 4096,
7215+
.max = 1048576,
7216+
.description = "Sets fuse max-write bytes.",
7217+
},
72017218
{
72027219
.key = {"kernel-writeback-cache"},
72037220
.type = GF_OPTION_TYPE_BOOL,

xlators/mount/fuse/src/fuse-bridge.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ struct fuse_private {
176176
uint32_t inode_table_size;
177177
uint32_t invalidate_limit;
178178
uint32_t fuse_dev_eperm_ratelimit_ns;
179+
uint32_t fuse_max_write;
179180

180181
/* counters for fusdev errnos */
181182
uint8_t fusedev_errno_cnt[FUSEDEV_EMAXPLUS];

xlators/mount/fuse/utils/mount.glusterfs.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ start_glusterfs ()
332332
cmd_line=$(echo "$cmd_line --fuse-handle-copy_file_range=$fuse_handle_copy_file_range");
333333
fi
334334

335+
if [ -n "$fuse_max_write" ]; then
336+
cmd_line=$(echo "$cmd_line --fuse-max-write=$fuse_max_write");
337+
fi
338+
335339
if [ -n "$process_name" ]; then
336340
cmd_line=$(echo "$cmd_line --process-name fuse.$process_name");
337341
else
@@ -641,6 +645,9 @@ with_options()
641645
"fuse-dev-eperm-ratelimit-ns")
642646
fuse_dev_eperm_ratelimit_ns=$value
643647
;;
648+
"fuse-max-write")
649+
fuse_max_write=$value
650+
;;
644651
"context"|"fscontext"|"defcontext"|"rootcontext")
645652
# standard SElinux mount options to pass to the kernel
646653
[ -z "$fuse_mountopts" ] || fuse_mountopts="$fuse_mountopts,"

0 commit comments

Comments
 (0)