Skip to contentSkip to conversation

fuse: add configurable max_pages parameter

PATCH New Constantine Shulyupin 1 participant 1 message Aug 6, 2017

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fuse: add configurable max_pages parameter

Replace define FUSE_MAX_PAGES_PER_REQ with the configurable mount parameter max_pages to improve performance. To utilize the max_pages parameter you must also increase the value of bufsize in the user mode library.

---
 Documentation/filesystems/fuse.txt |  5 +++-
 fs/fuse/dev.c                      |  2 +-
 fs/fuse/file.c                     | 54 +++++++++++++++++++++-----------------
 fs/fuse/fuse_i.h                   |  5 +++-
 fs/fuse/inode.c                    | 12 +++++++++
 5 files changed, 51 insertions(+), 27 deletions(-)
Documentation/filesystems/fuse.txt +4 -1
index 13af4a4..d4e832f 100644
@@ -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 +1 -1
index ebb5e37..f750f30 100644
@@ -1707,7 +1707,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 +30 -24

172 lines not on this page · raw message

fs/fuse/fuse_i.h +4 -1
index 5c4adc4..e3f9599 100644
@@ -25,7 +25,7 @@
 #include <linux/kref.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
@@ -478,6 +478,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 +12 -0
index 9904a1b..0798063 100644
@@ -68,6 +68,7 @@ struct fuse_mount_data {
 	unsigned group_id_present:1;
 	unsigned flags;
 	unsigned max_read;
+	unsigned max_pages;
 	unsigned blksize;
 };
 
@@ -444,6 +445,7 @@ enum {
 	OPT_ALLOW_OTHER,
 	OPT_USE_RDEV,
 	OPT_MAX_READ,
+	OPT_MAX_PAGES,
 	OPT_BLKSIZE,
 	OPT_ERR
 };
@@ -457,6 +459,7 @@ static const match_table_t tokens = {
 	{OPT_ALLOW_OTHER,		"allow_other"},
 	{OPT_USE_RDEV,			"use_rdev"},
 	{OPT_MAX_READ,			"max_read=%u"},
+	{OPT_MAX_PAGES,                 "max_pages=%u"},
 	{OPT_BLKSIZE,			"blksize=%u"},
 	{OPT_ERR,			NULL}
 };
@@ -541,6 +544,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 +583,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
 		seq_puts(m, ",use_rdev");
 	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;
@@ -1112,6 +1123,7 @@ 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 = d.max_pages ?: FUSE_DEFAULT_MAX_PAGES_PER_REQ;
 
 	/* Used by get_root_inode() */
 	sb->s_fs_info = fc;
Signature · 1 line
2.7.4