diff --git a/src/config.cpp b/src/config.cpp index e0c3de3e..282eb13e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -40,6 +40,7 @@ namespace mergerfs minfreespace(MINFREESPACE_DEFAULT), moveonenospc(false), direct_io(false), + dropcacheonclose(false), POLICYINIT(access), POLICYINIT(chmod), POLICYINIT(chown), diff --git a/src/config.hpp b/src/config.hpp index 0ec36d04..fd20f44c 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -48,6 +48,7 @@ namespace mergerfs uint64_t minfreespace; bool moveonenospc; bool direct_io; + bool dropcacheonclose; public: const Policy *policies[FuseFunc::Enum::END]; diff --git a/src/option_parser.cpp b/src/option_parser.cpp index 0ad72880..7189fda3 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -120,13 +120,13 @@ parse_and_process_minfreespace(const std::string &value, static int -parse_and_process_moveonenospc(const std::string &value, - bool &moveonenospc) +parse_and_process_boolean(const std::string &value, + bool &boolean) { if(value == "false") - moveonenospc = false; + boolean = false; else if(value == "true") - moveonenospc = true; + boolean = true; else return 1; @@ -169,7 +169,9 @@ parse_and_process_kv_arg(Config &config, if(key == "minfreespace") rv = parse_and_process_minfreespace(value,config.minfreespace); else if(key == "moveonenospc") - rv = parse_and_process_moveonenospc(value,config.moveonenospc); + rv = parse_and_process_boolean(value,config.moveonenospc); + else if(key == "dropcacheonclose") + rv = parse_and_process_boolean(value,config.dropcacheonclose); } if(rv == -1) @@ -246,20 +248,25 @@ usage(void) "mergerfs options:\n" " ':' delimited list of directories. Supports\n" " shell globbing (must be escaped in shell)\n" - " -o defaults default FUSE options which seem to provide the\n" + " -o defaults Default FUSE options which seem to provide the\n" " best performance: atomic_o_trunc, auto_cache,\n" " big_writes, default_permissions, splice_read,\n" " splice_write, splice_move\n" - " -o direct_io bypass additional caching, increases write\n" - " speeds at the cost of reads\n" - " -o use_ino mergerfs will generate inode values rather than\n" - " autogenerated by libfuse\n" - " -o minfreespace= minimum free space needed for certain policies:\n" - " default 4G\n" + " -o func.=

Set function to policy

\n" + " -o category.=

Set functions in category to

\n" + " -o direct_io Bypass additional caching, increases write\n" + " speeds at the cost of reads. Please read docs\n" + " for more details as there are tradeoffs.\n" + " -o use_ino Have mergerfs generate inode values rather than\n" + " autogenerated by libfuse. Suggested.\n" + " -o minfreespace= minimum free space needed for certain policies.\n" + " default=4G\n" " -o moveonenospc= try to move file to another drive when ENOSPC\n" - " on write: default false\n" - " -o func.=

set function to policy

\n" - " -o category.=

set functions in category to

\n" + " on write. default=false\n" + " -o dropcacheonclose=\n" + " when a file is closed suggest to OS it drop\n" + " the file's cache. This is useful when direct_io\n" + " is disabled. default=false\n" << std::endl; } @@ -267,7 +274,8 @@ static void version(void) { - std::cout << "mergerfs version: " << MERGERFS_VERSION + std::cout << "mergerfs version: " + << MERGERFS_VERSION << std::endl; } diff --git a/src/release.cpp b/src/release.cpp index f38bfd6e..5b045f44 100644 --- a/src/release.cpp +++ b/src/release.cpp @@ -18,14 +18,25 @@ #include +#include "config.hpp" #include "errno.hpp" #include "fileinfo.hpp" #include "fs_base_close.hpp" +#include "fs_fadvise.hpp" static int -_release(FileInfo *fi) +_release(FileInfo *fi, + const bool dropcacheonclose) { + // according to Feh of nocache calling it once doesn't always work + // https://github.com/Feh/nocache + if(dropcacheonclose) + { + fs::fadvise(fi->fd,0,0,POSIX_FADV_DONTNEED); + fs::fadvise(fi->fd,0,0,POSIX_FADV_DONTNEED); + } + fs::close(fi->fd); delete fi; @@ -41,9 +52,11 @@ namespace mergerfs release(const char *fusepath, fuse_file_info *ffi) { - FileInfo *fi = reinterpret_cast(ffi->fh); + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + FileInfo *fi = reinterpret_cast(ffi->fh); - return _release(fi); + return _release(fi,config.dropcacheonclose); } } }