Skip to content

Commit

Permalink
Merge pull request #636 from trapexit/max_pages
Browse files Browse the repository at this point in the history
allow setting of 'max_pages' (via 'fuse_msg_size')
  • Loading branch information
trapexit authored Jun 4, 2019
2 parents 24af276 + 7cbd88a commit 5d013f4
Show file tree
Hide file tree
Showing 14 changed files with 353 additions and 218 deletions.
115 changes: 60 additions & 55 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions libfuse/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
VERSION = "2.9.7-mergerfs_2.28.0"
OPT = -O2
OPTS = -O2

ifeq ($(DEBUG),1)
DEBUG_FLAGS := -g
Expand Down Expand Up @@ -28,7 +28,7 @@ OBJS = $(SRC:lib/%.c=build/%.o)
DEPS = $(SRC:lib/%.c=build/%.d)

CFLAGS += \
$(OPT) \
$(OPTS) \
$(DEBUG_FLAGS) \
-Wall \
-pipe \
Expand Down
14 changes: 12 additions & 2 deletions libfuse/include/fuse_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#error Please add -D_FILE_OFFSET_BITS=64 to your compile flags!
#endif

#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32
#define FUSE_MAX_MAX_PAGES 256

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -121,6 +124,7 @@ fuse_file_info
#define FUSE_CAP_PARALLEL_DIROPS (1 << 18)
#define FUSE_CAP_POSIX_ACL (1 << 19)
#define FUSE_CAP_CACHE_SYMLINKS (1 << 20)
#define FUSE_CAP_MAX_PAGES (1 << 21)


/**
Expand Down Expand Up @@ -188,10 +192,15 @@ struct fuse_conn_info {
*/
unsigned congestion_threshold;

/**
* Max pages
*/
uint16_t max_pages;

/**
* For future use.
*/
unsigned reserved[23];
unsigned reserved[22];
};

struct fuse_session;
Expand All @@ -208,7 +217,8 @@ struct fuse_pollhandle;
* @param args argument vector
* @return the communication channel on success, NULL on failure
*/
struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args);
struct fuse_chan *fuse_mount(const char *mountpoint,
struct fuse_args *args);

/**
* Umount a FUSE mountpoint
Expand Down
9 changes: 6 additions & 3 deletions libfuse/lib/fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -4775,9 +4775,11 @@ void fuse_destroy(struct fuse *f)
fuse_delete_context_key();
}

static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, int compat)
static
struct fuse *
fuse_new_common_compat25(int fd, struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, int compat)
{
struct fuse *f = NULL;
struct fuse_chan *ch = fuse_kern_chan_new(fd);
Expand Down Expand Up @@ -4805,6 +4807,7 @@ static struct fuse *fuse_new_common_compat(int fd, const char *opts,
fuse_opt_free_args(&args);
return NULL;
}

f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
fuse_opt_free_args(&args);

Expand Down
27 changes: 16 additions & 11 deletions libfuse/lib/fuse_kern_chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,21 @@ static void fuse_kern_chan_destroy(struct fuse_chan *ch)
close(fd);
}

#define MIN_BUFSIZE 0x21000

struct fuse_chan *fuse_kern_chan_new(int fd)
struct fuse_chan *
fuse_kern_chan_new(int fd_)
{
struct fuse_chan_ops op = {
.receive = fuse_kern_chan_receive,
.send = fuse_kern_chan_send,
.destroy = fuse_kern_chan_destroy,
};
size_t bufsize = getpagesize() + 0x1000;
bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
return fuse_chan_new(&op, fd, bufsize, NULL);
long pagesize;
size_t bufsize;
struct fuse_chan_ops op =
{
.receive = fuse_kern_chan_receive,
.send = fuse_kern_chan_send,
.destroy = fuse_kern_chan_destroy,
};

pagesize = sysconf(_SC_PAGESIZE);

bufsize = ((FUSE_MAX_MAX_PAGES * pagesize) + 0x1000);

return fuse_chan_new(&op, fd_, bufsize, NULL);
}
26 changes: 13 additions & 13 deletions libfuse/lib/fuse_lowlevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1749,8 +1749,10 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
f->conn.want = 0;

memset(&outarg, 0, sizeof(outarg));
outarg.major = FUSE_KERNEL_VERSION;
outarg.minor = FUSE_KERNEL_MINOR_VERSION;

outarg.major = FUSE_KERNEL_VERSION;
outarg.minor = FUSE_KERNEL_MINOR_VERSION;
outarg.max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;

if (arg->major < 7) {
fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n",
Expand Down Expand Up @@ -1790,6 +1792,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
f->conn.capable |= FUSE_CAP_ASYNC_DIO;
if (arg->flags & FUSE_PARALLEL_DIROPS)
f->conn.capable |= FUSE_CAP_PARALLEL_DIROPS;
if (arg->flags & FUSE_MAX_PAGES)
f->conn.capable |= FUSE_CAP_MAX_PAGES;
} else {
f->conn.want &= ~FUSE_CAP_ASYNC_READ;
f->conn.max_readahead = 0;
Expand All @@ -1812,14 +1816,10 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
if (req->f->conn.proto_minor >= 18)
f->conn.capable |= FUSE_CAP_IOCTL_DIR;

if (f->atomic_o_trunc)
f->conn.want |= FUSE_CAP_ATOMIC_O_TRUNC;
if (f->op.getlk && f->op.setlk && !f->no_remote_posix_lock)
f->conn.want |= FUSE_CAP_POSIX_LOCKS;
if (f->op.flock && !f->no_remote_flock)
f->conn.want |= FUSE_CAP_FLOCK_LOCKS;
if (f->big_writes)
f->conn.want |= FUSE_CAP_BIG_WRITES;

if (bufsize < FUSE_MIN_READ_BUFFER) {
fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
Expand All @@ -1842,6 +1842,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
if (f->no_splice_move)
f->conn.want &= ~FUSE_CAP_SPLICE_MOVE;

if ((arg->flags & FUSE_MAX_PAGES) && (f->conn.want & FUSE_CAP_MAX_PAGES))
{
outarg.flags |= FUSE_MAX_PAGES;
outarg.max_pages = f->conn.max_pages;
}

if (f->conn.want & FUSE_CAP_ASYNC_READ)
outarg.flags |= FUSE_ASYNC_READ;
if (f->conn.want & FUSE_CAP_POSIX_LOCKS)
Expand Down Expand Up @@ -1890,6 +1896,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
outarg.max_background);
fprintf(stderr, " congestion_threshold=%i\n",
outarg.congestion_threshold);
fprintf(stderr, " max_pages=%d\n",outarg.max_pages);
}

size_t outargsize;
Expand Down Expand Up @@ -2520,17 +2527,14 @@ static const struct fuse_opt fuse_ll_opts[] = {
{ "debug", offsetof(struct fuse_ll, debug), 1 },
{ "-d", offsetof(struct fuse_ll, debug), 1 },
{ "allow_root", offsetof(struct fuse_ll, allow_root), 1 },
{ "max_write=%u", offsetof(struct fuse_ll, conn.max_write), 0 },
{ "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 },
{ "max_background=%u", offsetof(struct fuse_ll, conn.max_background), 0 },
{ "congestion_threshold=%u",
offsetof(struct fuse_ll, conn.congestion_threshold), 0 },
{ "atomic_o_trunc", offsetof(struct fuse_ll, atomic_o_trunc), 1},
{ "no_remote_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1},
{ "no_remote_lock", offsetof(struct fuse_ll, no_remote_flock), 1},
{ "no_remote_flock", offsetof(struct fuse_ll, no_remote_flock), 1},
{ "no_remote_posix_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1},
{ "big_writes", offsetof(struct fuse_ll, big_writes), 1},
{ "splice_write", offsetof(struct fuse_ll, splice_write), 1},
{ "no_splice_write", offsetof(struct fuse_ll, no_splice_write), 1},
{ "splice_move", offsetof(struct fuse_ll, splice_move), 1},
Expand All @@ -2554,12 +2558,9 @@ static void fuse_ll_version(void)
static void fuse_ll_help(void)
{
fprintf(stderr,
" -o max_write=N set maximum size of write requests\n"
" -o max_readahead=N set maximum readahead\n"
" -o max_background=N set number of maximum background requests\n"
" -o congestion_threshold=N set kernel's congestion threshold\n"
" -o atomic_o_trunc enable atomic open+truncate support\n"
" -o big_writes enable larger than 4kB writes\n"
" -o no_remote_lock disable remote file locking\n"
" -o no_remote_flock disable remote file locking (BSD)\n"
" -o no_remote_posix_lock disable remove file locking (POSIX)\n"
Expand Down Expand Up @@ -2764,7 +2765,6 @@ struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,

f->conn.max_write = UINT_MAX;
f->conn.max_readahead = UINT_MAX;
f->atomic_o_trunc = 0;
list_init_req(&f->list);
list_init_req(&f->interrupts);
list_init_nreq(&f->notify_list);
Expand Down
143 changes: 80 additions & 63 deletions libfuse/lib/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,26 @@ enum {
KEY_VERSION,
};

struct helper_opts {
int singlethread;
int foreground;
int nodefault_subtype;
char *mountpoint;
struct helper_opts
{
int singlethread;
int foreground;
int nodefault_subtype;
char *mountpoint;
};

#define FUSE_HELPER_OPT(t, p) { t, offsetof(struct helper_opts, p), 1 }

static const struct fuse_opt fuse_helper_opts[] = {
static
const
struct fuse_opt fuse_helper_opts[] =
{
FUSE_HELPER_OPT("-d", foreground),
FUSE_HELPER_OPT("debug", foreground),
FUSE_HELPER_OPT("-f", foreground),
FUSE_HELPER_OPT("-s", singlethread),
FUSE_HELPER_OPT("fsname=", nodefault_subtype),
FUSE_HELPER_OPT("subtype=", nodefault_subtype),

FUSE_OPT_KEY("-h", KEY_HELP),
FUSE_OPT_KEY("--help", KEY_HELP),
FUSE_OPT_KEY("-ho", KEY_HELP_NOHEADER),
Expand Down Expand Up @@ -144,37 +147,46 @@ static int add_default_subtype(const char *progname, struct fuse_args *args)
return res;
}

int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
int *multithreaded, int *foreground)
int
fuse_parse_cmdline(struct fuse_args *args_,
char **mountpoint_,
int *multithreaded_,
int *foreground_)
{
int res;
struct helper_opts hopts;

memset(&hopts, 0, sizeof(hopts));
res = fuse_opt_parse(args, &hopts, fuse_helper_opts,
fuse_helper_opt_proc);
if (res == -1)
return -1;

if (!hopts.nodefault_subtype) {
res = add_default_subtype(args->argv[0], args);
if (res == -1)
goto err;
}
if (mountpoint)
*mountpoint = hopts.mountpoint;
else
free(hopts.mountpoint);

if (multithreaded)
*multithreaded = !hopts.singlethread;
if (foreground)
*foreground = hopts.foreground;
return 0;

err:
free(hopts.mountpoint);
return -1;
int res;
struct helper_opts hopts;

memset(&hopts, 0, sizeof(hopts));

res = fuse_opt_parse(args_,
&hopts,
fuse_helper_opts,
fuse_helper_opt_proc);
if(res == -1)
return -1;

if(!hopts.nodefault_subtype)
{
res = add_default_subtype(args_->argv[0], args_);
if(res == -1)
goto err;
}

if(mountpoint_)
*mountpoint_ = hopts.mountpoint;
else
free(hopts.mountpoint);

if(multithreaded_)
*multithreaded_ = !hopts.singlethread;
if(foreground_)
*foreground_ = hopts.foreground;

return 0;

err:
free(hopts.mountpoint);
return -1;
}

int fuse_daemonize(int foreground)
Expand Down Expand Up @@ -229,36 +241,41 @@ int fuse_daemonize(int foreground)
return 0;
}

static struct fuse_chan *fuse_mount_common(const char *mountpoint,
struct fuse_args *args)
static
struct fuse_chan *
fuse_mount_common(const char *mountpoint_,
struct fuse_args *args_)
{
struct fuse_chan *ch;
int fd;

/*
* Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
* would ensue.
*/
do {
fd = open("/dev/null", O_RDWR);
if (fd > 2)
close(fd);
} while (fd >= 0 && fd <= 2);

fd = fuse_mount_compat25(mountpoint, args);
if (fd == -1)
return NULL;

ch = fuse_kern_chan_new(fd);
if (!ch)
fuse_kern_unmount(mountpoint, fd);

return ch;
struct fuse_chan *ch;
int fd;

/*
* Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
* would ensue.
*/
do
{
fd = open("/dev/null", O_RDWR);
if(fd > 2)
close(fd);
} while(fd >= 0 && fd <= 2);

fd = fuse_mount_compat25(mountpoint_, args_);
if(fd == -1)
return NULL;

ch = fuse_kern_chan_new(fd);
if(!ch)
fuse_kern_unmount(mountpoint_, fd);

return ch;
}

struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
struct fuse_chan *
fuse_mount(const char *mountpoint_,
struct fuse_args *args_)
{
return fuse_mount_common(mountpoint, args);
return fuse_mount_common(mountpoint_,args_);
}

static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch)
Expand Down
Loading

0 comments on commit 5d013f4

Please sign in to comment.