Browse Source

add setting of thread pool size

pull/424/head
Antonio SJ Musumeci 7 years ago
parent
commit
75ed37a11a
  1. 1
      README.md
  2. 4
      libfuse/include/fuse.h
  3. 2
      libfuse/include/fuse_lowlevel.h
  4. 2
      libfuse/lib/cuse_lowlevel.c
  5. 7
      libfuse/lib/fuse.c
  6. 23
      libfuse/lib/fuse_loop_mt.c
  7. 6
      libfuse/lib/fuse_mt.c
  8. 12
      man/mergerfs.1
  9. 5
      src/option_parser.cpp

1
README.md

@ -42,6 +42,7 @@ mergerfs -o<options> <srcmounts> <mountpoint>
* **symlinkify_timeout**: time to wait, in seconds, to activate the **symlinkify** behavior. (default: 3600) * **symlinkify_timeout**: time to wait, in seconds, to activate the **symlinkify** behavior. (default: 3600)
* **nullrw**: turns reads and writes into no-ops. The request will succeed but do nothing. Useful for benchmarking mergerfs. (default: false) * **nullrw**: turns reads and writes into no-ops. The request will succeed but do nothing. Useful for benchmarking mergerfs. (default: false)
* **ignorepponrename**: ignore path preserving on rename. Typically rename and link act differently depending on the policy of `create` (read below). Enabling this will cause rename and link to always use the non-path preserving behavior. This means files, when renamed or linked, will stay on the same drive. * **ignorepponrename**: ignore path preserving on rename. Typically rename and link act differently depending on the policy of `create` (read below). Enabling this will cause rename and link to always use the non-path preserving behavior. This means files, when renamed or linked, will stay on the same drive.
* **threads**: number of threads to use in multithreaded mode. When set to zero (the default) it will attempt to discover and use the number of logical cores. If the lookup fails it will fall back to using 4. If the thread count is set negative it will look up the number of cores then divide by the absolute value. ie. threads=-2 on an 8 core machine will result in 8 / 2 = 4 threads. There will always be at least 1 thread. NOTE: higher number of threads increases parallelism but usually decreases throughput.
* **fsname**: sets the name of the filesystem as seen in **mount**, **df**, etc. Defaults to a list of the source paths concatenated together with the longest common prefix removed. * **fsname**: sets the name of the filesystem as seen in **mount**, **df**, etc. Defaults to a list of the source paths concatenated together with the longest common prefix removed.
* **func.<func>=<policy>**: sets the specific FUSE function's policy. See below for the list of value types. Example: **func.getattr=newest** * **func.<func>=<policy>**: sets the specific FUSE function's policy. See below for the list of value types. Example: **func.getattr=newest**
* **category.<category>=<policy>**: Sets policy of all FUSE functions in the provided category. Example: **category.create=mfs** * **category.<category>=<policy>**: Sets policy of all FUSE functions in the provided category. Example: **category.create=mfs**

4
libfuse/include/fuse.h

@ -115,7 +115,7 @@ struct fuse_operations {
*/ */
int (*mknod) (const char *, mode_t, dev_t); int (*mknod) (const char *, mode_t, dev_t);
/** Create a directory
/** Create a directory
* *
* Note that the mode argument may not have the type specification * Note that the mode argument may not have the type specification
* bits set, i.e. S_ISDIR(mode) can be false. To obtain the * bits set, i.e. S_ISDIR(mode) can be false. To obtain the
@ -696,6 +696,8 @@ int fuse_loop(struct fuse *f);
*/ */
void fuse_exit(struct fuse *f); void fuse_exit(struct fuse *f);
int fuse_config_num_threads(const struct fuse *f);
/** /**
* FUSE event loop with multiple threads * FUSE event loop with multiple threads
* *

2
libfuse/include/fuse_lowlevel.h

@ -1700,7 +1700,7 @@ int fuse_session_loop(struct fuse_session *se);
* @param se the session * @param se the session
* @return 0 on success, -1 on error * @return 0 on success, -1 on error
*/ */
int fuse_session_loop_mt(struct fuse_session *se);
int fuse_session_loop_mt(struct fuse_session *se, const int threads);
/* ----------------------------------------------------------- * /* ----------------------------------------------------------- *
* Channel interface * * Channel interface *

2
libfuse/lib/cuse_lowlevel.c

@ -359,7 +359,7 @@ int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
return 1; return 1;
if (multithreaded) if (multithreaded)
res = fuse_session_loop_mt(se);
res = fuse_session_loop_mt(se, 0);
else else
res = fuse_session_loop(se); res = fuse_session_loop(se);

7
libfuse/lib/fuse.c

@ -77,6 +77,7 @@ struct fuse_config {
int intr_signal; int intr_signal;
int help; int help;
char *modules; char *modules;
int threads;
}; };
struct fuse_fs { struct fuse_fs {
@ -4405,6 +4406,7 @@ static const struct fuse_opt fuse_lib_opts[] = {
FUSE_LIB_OPT("intr", intr, 1), FUSE_LIB_OPT("intr", intr, 1),
FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0), FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0),
FUSE_LIB_OPT("modules=%s", modules, 0), FUSE_LIB_OPT("modules=%s", modules, 0),
FUSE_LIB_OPT("threads=%d", threads, 0),
FUSE_OPT_END FUSE_OPT_END
}; };
@ -4900,3 +4902,8 @@ struct fuse *fuse_new_compat25(int fd, struct fuse_args *args,
} }
FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5"); FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5");
int fuse_config_num_threads(const struct fuse *f)
{
return f->conf.threads;
}

23
libfuse/lib/fuse_loop_mt.c

@ -19,6 +19,7 @@
#include <semaphore.h> #include <semaphore.h>
#include <errno.h> #include <errno.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h>
/* Environment var controlling the thread stack size */ /* Environment var controlling the thread stack size */
#define ENVNAME_THREAD_STACK "FUSE_THREAD_STACK" #define ENVNAME_THREAD_STACK "FUSE_THREAD_STACK"
@ -167,9 +168,21 @@ static void fuse_join_worker(struct fuse_worker *w)
free(w); free(w);
} }
int fuse_session_loop_mt(struct fuse_session *se)
static int number_of_threads(void)
{
#ifdef _SC_NPROCESSORS_ONLN
return sysconf(_SC_NPROCESSORS_ONLN);
#endif
return 4;
}
int fuse_session_loop_mt(struct fuse_session *se,
const int _threads)
{ {
int i;
int err; int err;
int threads;
struct fuse_mt mt; struct fuse_mt mt;
struct fuse_worker *w; struct fuse_worker *w;
@ -181,8 +194,14 @@ int fuse_session_loop_mt(struct fuse_session *se)
mt.main.prev = mt.main.next = &mt.main; mt.main.prev = mt.main.next = &mt.main;
sem_init(&mt.finish, 0, 0); sem_init(&mt.finish, 0, 0);
threads = ((_threads > 0) ? _threads : number_of_threads());
if(_threads < 0)
threads /= -_threads;
if(threads == 0)
threads = 1;
err = 0; err = 0;
for(size_t i = 0; (i < 10) && !err; i++)
for(i = 0; (i < threads) && !err; i++)
err = fuse_loop_start_thread(&mt); err = fuse_loop_start_thread(&mt);
if (!err) { if (!err) {

6
libfuse/lib/fuse_mt.c

@ -100,7 +100,8 @@ int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
return -1; return -1;
} }
fuse_session_add_chan(se, ch); fuse_session_add_chan(se, ch);
res = fuse_session_loop_mt(se);
res = fuse_session_loop_mt(se,
fuse_config_num_threads(f));
fuse_session_destroy(se); fuse_session_destroy(se);
return res; return res;
} }
@ -114,7 +115,8 @@ int fuse_loop_mt(struct fuse *f)
if (res) if (res)
return -1; return -1;
res = fuse_session_loop_mt(fuse_get_session(f));
res = fuse_session_loop_mt(fuse_get_session(f),
fuse_config_num_threads(f));
fuse_stop_cleanup_thread(f); fuse_stop_cleanup_thread(f);
return res; return res;
} }

12
man/mergerfs.1

@ -103,6 +103,18 @@ Enabling this will cause rename and link to always use the non\-path
preserving behavior. preserving behavior.
This means files, when renamed or linked, will stay on the same drive. This means files, when renamed or linked, will stay on the same drive.
.IP \[bu] 2 .IP \[bu] 2
\f[B]threads\f[]: number of threads to use in multithreaded mode.
When set to zero (the default) it will attempt to discover and use the
number of logical cores.
If the lookup fails it will fall back to using 4.
If the thread count is set negative it will look up the number of cores
then divide by the absolute value.
ie.
threads=\-2 on an 8 core machine will result in 8 / 2 = 4 threads.
There will always be at least 1 thread.
NOTE: higher number of threads increases parallelism but usually
decreases throughput.
.IP \[bu] 2
\f[B]fsname\f[]: sets the name of the filesystem as seen in \f[B]fsname\f[]: sets the name of the filesystem as seen in
\f[B]mount\f[], \f[B]df\f[], etc. \f[B]mount\f[], \f[B]df\f[], etc.
Defaults to a list of the source paths concatenated together with the Defaults to a list of the source paths concatenated together with the

5
src/option_parser.cpp

@ -298,7 +298,10 @@ usage(void)
" -o nullrw=<bool> Disables reads and writes. For benchmarking.\n" " -o nullrw=<bool> Disables reads and writes. For benchmarking.\n"
" -o ignorepponrename=<bool>\n" " -o ignorepponrename=<bool>\n"
" Ignore path preserving when performing renames\n" " Ignore path preserving when performing renames\n"
" and links. default = false"
" and links. default = false\n"
" -o threads=<int> number of worker threads. 0 = autodetect.\n"
" Negative values autodetect then divide by\n"
" absolute value. default = 0\n"
<< std::endl; << std::endl;
} }

Loading…
Cancel
Save