diff --git a/src/config.cpp b/src/config.cpp index 012194c9..ae9279dc 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -137,8 +137,8 @@ Config::Config() _mountpoint(mountpoint), _never_forget_nodes(), _noforget(), - _remember(fuse_cfg.remember_nodes), - _remember_nodes(fuse_cfg.remember_nodes), + _remember(), + _remember_nodes(), _srcmounts(branches), _threads(fuse_cfg.read_thread_count), _uid(fuse_cfg.uid), diff --git a/src/config.hpp b/src/config.hpp index c20cf102..9c7e685e 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -55,6 +55,7 @@ #include "base_types.h" +#include #include #include #include @@ -176,8 +177,8 @@ private: TFSRef _mountpoint; CfgNoforget _never_forget_nodes; CfgNoforget _noforget; - TFSRef _remember; - TFSRef _remember_nodes; + CfgRememberNodes _remember; + CfgRememberNodes _remember_nodes; SrcMounts _srcmounts; TFSRef _threads; TFSRef _uid; diff --git a/src/config_debug.cpp b/src/config_debug.cpp index ee37ccf8..0ad6e54c 100644 --- a/src/config_debug.cpp +++ b/src/config_debug.cpp @@ -28,13 +28,13 @@ Debug::Debug(const bool v_) { - fuse_cfg.debug = v_; + fuse_cfg.debug.store(v_,std::memory_order_relaxed); } std::string Debug::to_string(void) const { - return str::to(fuse_cfg.debug); + return str::to(fuse_cfg.debug.load(std::memory_order_relaxed)); } int @@ -47,7 +47,7 @@ Debug::from_string(const std::string_view s_) if(rv < 0) return rv; - fuse_cfg.debug = val; + fuse_cfg.debug.store(val,std::memory_order_relaxed); // If debug is being enabled, ensure output file is set if(val) diff --git a/src/config_noforget.hpp b/src/config_noforget.hpp index 70ea021a..a1d5c4d2 100644 --- a/src/config_noforget.hpp +++ b/src/config_noforget.hpp @@ -20,9 +20,40 @@ #include "tofrom_string.hpp" #include "from_string.hpp" +#include "to_string.hpp" #include "fuse_cfg.hpp" +#include + + +class CfgRememberNodes : public ToFromString +{ +public: + int + from_string(const std::string_view s_) + { + int rv; + s64 v; + + rv = str::from(s_,&v); + if(rv < 0) + return rv; + if(v < -1) + return -EINVAL; + + fuse_cfg.remember_nodes.store(v,std::memory_order_relaxed); + + return 0; + } + + std::string + to_string() const + { + return str::to(fuse_cfg.remember_nodes.load(std::memory_order_relaxed)); + } +}; + class CfgNoforget : public ToFromString { @@ -36,14 +67,14 @@ public: rv = str::from(s_,&b); if((b == true) || s_.empty()) { - fuse_cfg.remember_nodes = -1; + fuse_cfg.remember_nodes.store(-1,std::memory_order_relaxed); return 0; } if(rv) return rv; - fuse_cfg.remember_nodes = 0; + fuse_cfg.remember_nodes.store(0,std::memory_order_relaxed); return 0; } @@ -51,7 +82,7 @@ public: std::string to_string() const { - if(fuse_cfg.remember_nodes == -1) + if(fuse_cfg.remember_nodes.load(std::memory_order_relaxed) == -1) return "true"; return "false"; } diff --git a/src/option_parser.cpp b/src/option_parser.cpp index 7d885722..547680d3 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -206,7 +206,7 @@ _option_processor(void *data_, return OPT_DISCARD; case MERGERFS_OPT_DEBUG: - fuse_cfg.debug = true; + fuse_cfg.debug.store(true,std::memory_order_relaxed); return OPT_DISCARD; case MERGERFS_OPT_HELP: diff --git a/src/tofrom_ref.hpp b/src/tofrom_ref.hpp index 68ad082c..0d617df9 100644 --- a/src/tofrom_ref.hpp +++ b/src/tofrom_ref.hpp @@ -22,6 +22,8 @@ #include "from_string.hpp" #include "tofrom_string.hpp" +#include + template class TFSRef : public ToFromString @@ -48,3 +50,38 @@ public: private: T &_data; }; + +template +class TFSRef> : public ToFromString +{ +public: + int + from_string(const std::string_view s_) final + { + T value; + int rv; + + rv = str::from(s_,&value); + if(rv < 0) + return rv; + + _data.store(value,std::memory_order_relaxed); + + return 0; + } + + std::string + to_string(void) const final + { + return str::to(_data.load(std::memory_order_relaxed)); + } + +public: + TFSRef(std::atomic &data_) + : _data(data_) + { + } + +private: + std::atomic &_data; +}; diff --git a/tests/tests.cpp b/tests/tests.cpp index ef7aac61..2696f662 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -2657,6 +2657,39 @@ test_config_get_set_roundtrip() TEST_CHECK(val == "myfs"); } +void +test_config_remember_nodes() +{ + Config cfg; + std::string val; + + TEST_CHECK(cfg.set("remember-nodes","30") == 0); + TEST_CHECK(cfg.get("remember-nodes",&val) == 0); + TEST_CHECK(val == "30"); + + TEST_CHECK(cfg.set("remember","-1") == 0); + TEST_CHECK(cfg.get("remember-nodes",&val) == 0); + TEST_CHECK(val == "-1"); + + TEST_CHECK(cfg.set("remember-nodes","-2") == -EINVAL); + TEST_CHECK(cfg.get("remember-nodes",&val) == 0); + TEST_CHECK(val == "-1"); + + TEST_CHECK(cfg.set("noforget","false") == 0); + TEST_CHECK(cfg.get("noforget",&val) == 0); + TEST_CHECK(val == "false"); + TEST_CHECK(cfg.get("remember-nodes",&val) == 0); + TEST_CHECK(val == "0"); + + TEST_CHECK(cfg.set("noforget","true") == 0); + TEST_CHECK(cfg.get("noforget",&val) == 0); + TEST_CHECK(val == "true"); + TEST_CHECK(cfg.get("remember-nodes",&val) == 0); + TEST_CHECK(val == "-1"); + + TEST_CHECK(cfg.set("remember-nodes","0") == 0); +} + void test_config_get_unknown_key() { @@ -3677,6 +3710,7 @@ TEST_LIST = {"config_keys_listxattr_fill",test_config_keys_listxattr_fill}, {"config_keys_listxattr_erange",test_config_keys_listxattr_erange}, {"config_get_set_roundtrip",test_config_get_set_roundtrip}, + {"config_remember_nodes",test_config_remember_nodes}, {"config_get_unknown_key",test_config_get_unknown_key}, {"config_set_unknown_key",test_config_set_unknown_key}, {"config_set_invalid_value",test_config_set_invalid_value}, diff --git a/vendored/libfuse/include/fuse_cfg.hpp b/vendored/libfuse/include/fuse_cfg.hpp index 1cedb2f5..1cb70595 100644 --- a/vendored/libfuse/include/fuse_cfg.hpp +++ b/vendored/libfuse/include/fuse_cfg.hpp @@ -2,6 +2,7 @@ #include "base_types.h" +#include #include #include #include @@ -25,9 +26,9 @@ struct fuse_cfg_t s64 umask = FUSE_CFG_INVALID_UMASK; bool valid_umask() const; - s64 remember_nodes = 0; + std::atomic remember_nodes = 0; - bool debug = false; + std::atomic debug = false; std::shared_ptr log_file() const; void log_file(std::shared_ptr); std::shared_ptr log_filepath() const;