fuse: +max_pages
Subsystems (3)
PATCH v2 1/1 fuse: +max_pages
Replace FUSE_MAX_PAGES_PER_REQ with the configurable mount parameter max_pages to improve performance.
Old RFC with detailed description of the problem and many fixes by Mitsuo Hayasaka ([email protected]):
- https://lkml.org/lkml/2012/7/5/136
Changes in v2:
- add limitation by pipe_max_size, which was requested in
https://lkml.org/lkml/2012/7/12/32
Changes in v1: https://lkml.org/lkml/2017/8/6/194
- replace FUSE_MAX_PAGES_PER_REQ with
FUSE_DEFAULT_MAX_PAGES_PER_REQ and
fc->max_pages
- add mount option max_pages
Signed-off-by Constantine Shulyupin <[email protected]>
--- Documentation/filesystems/fuse.txt | 5 ++- fs/fuse/dev.c | 4 +-- fs/fuse/file.c | 54 +++++++++++++++--------------- fs/fuse/fuse_i.h | 5 ++- fs/fuse/inode.c | 15 +++++++++ fs/pipe.c | 1 + 6 files changed, 53 insertions(+), 31 deletions(-)
Documentation/filesystems/fuse.txt +4 -1
@@ -108,7 +108,10 @@ Mount options With this option the maximum size of read operations can be set. The default is infinite. Note that the size of read requests is - limited anyway to 32 pages (which is 128kbyte on i386). + limited anyway to max_pages (which by default is 32 or 128KB on x86). + +'max_pages=N' + Maximal number of pages per request. The default is 32 or 128KB on x86. 'blksize=N'
fs/fuse/dev.c +2 -2
@@ -1648,7 +1648,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,unsigned int num;unsigned int offset;size_t total_len =0 ; -int num_pages; +unsigned num_pages; offset = outarg->offset & ~PAGE_MASK ; file_size =i_size_read (inode);
@@ -1660,7 +1660,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, num = file_size - outarg->offset; num_pages = (num + offset +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - num_pages =min (num_pages,FUSE_MAX_PAGES_PER_REQ ); + num_pages =min (num_pages, fc->max_pages); req =fuse_get_req (fc, num_pages);if (IS_ERR (req))
fs/fuse/file.c +27 -27
171 lines not on this page · raw message
fs/fuse/fuse_i.h +4 -1
@@ -29,7 +29,7 @@#include <linux/user_namespace.h> /** Max number of pages that can be used in a single read request */ -#define FUSE_MAX_PAGES_PER_REQ 32 +#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32/** Bias for fi->writectr, meaning new writepages must not be sent */ #define FUSE_NOWRITE INT_MIN
@@ -476,6 +476,9 @@ struct fuse_conn {/** Maximum write size */ unsigned max_write; +/** Maxmum number of pages that can be used in a single request */ +unsigned max_pages; +/** Input queue */ struct fuse_iqueue iq;
fs/fuse/inode.c +15 -0
@@ -22,6 +22,7 @@#include <linux/exportfs.h> #include <linux/posix_acl.h> #include <linux/pid_namespace.h> +#include <linux/pipe_fs_i.h> MODULE_AUTHOR ("Miklos Szeredi <[email protected]>" );MODULE_DESCRIPTION ("Filesystem in Userspace" );
@@ -71,6 +72,7 @@ struct fuse_mount_data { unsigned default_permissions:1; unsigned allow_other:1;unsigned max_read; +unsigned max_pages;unsigned blksize; };
@@ -450,6 +452,7 @@ enum {OPT_DEFAULT_PERMISSIONS ,OPT_ALLOW_OTHER ,OPT_MAX_READ , +OPT_MAX_PAGES ,OPT_BLKSIZE , OPT_ERR };
@@ -462,6 +465,7 @@ static const match_table_t tokens = { {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, {OPT_ALLOW_OTHER, "allow_other"}, {OPT_MAX_READ, "max_read=%u"}, + {OPT_MAX_PAGES, "max_pages=%u"}, {OPT_BLKSIZE, "blksize=%u"}, {OPT_ERR, NULL} };
@@ -543,6 +547,12 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev, d->max_read = value;break ; +case OPT_MAX_PAGES : +if (match_int (&args[0 ], &value)) +return 0 ; + d->max_pages = value; +break ; +case OPT_BLKSIZE :if (!is_bdev ||match_int (&args[0 ], &value))return 0 ;
@@ -574,6 +584,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)seq_puts (m,",allow_other" );if (fc->max_read != ~0 )seq_printf (m,",max_read=%u" , fc->max_read); +if (fc->max_pages !=FUSE_DEFAULT_MAX_PAGES_PER_REQ ) +seq_printf (m,",max_pages=%u" , fc->max_pages);if (sb->s_bdev && sb->s_blocksize !=FUSE_DEFAULT_BLKSIZE )seq_printf (m,",blksize=%lu" , sb->s_blocksize);return 0 ;
@@ -1135,6 +1147,9 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) fc->user_id = d.user_id; fc->group_id = d.group_id; fc->max_read =max_t (unsigned,4096 , d.max_read); + fc->max_pages =min_t (unsigned, pipe_max_size >>PAGE_SHIFT , +max_t (unsigned,FUSE_DEFAULT_MAX_PAGES_PER_REQ , + d.max_pages));/* Used by get_root_inode() */ sb->s_fs_info = fc;
fs/pipe.c +1 -0
@@ -34,6 +34,7 @@* be set by root in /proc/sys/fs/pipe-max-size */ unsigned int pipe_max_size =1048576 ; +EXPORT_SYMBOL (pipe_max_size);/* Maximum allocatable pages per user. Hard limit is unset by default, soft * matches default values.
Signature · 1 line
2.17.1