mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-20 19:29:31 +00:00
Misc changes (#1513)
* Start moving to string_view where possible * Rework readdir object to use atomic load/store
This commit is contained in:
+1
-1
@@ -38,7 +38,7 @@ Branch::Branch(const u64 &default_minfreespace_)
|
||||
}
|
||||
|
||||
int
|
||||
Branch::from_string(const std::string &str_)
|
||||
Branch::from_string(const std::string_view str_)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public:
|
||||
bool ro_or_nc(void) const;
|
||||
|
||||
public:
|
||||
int from_string(const std::string &str) final;
|
||||
int from_string(const std::string_view str) final;
|
||||
std::string to_string(void) const final;
|
||||
|
||||
public:
|
||||
|
||||
+14
-14
@@ -74,9 +74,9 @@ namespace l
|
||||
{
|
||||
static
|
||||
void
|
||||
split(const std::string &s_,
|
||||
std::string *instr_,
|
||||
std::string *values_)
|
||||
split(const std::string_view s_,
|
||||
std::string *instr_,
|
||||
std::string *values_)
|
||||
{
|
||||
u64 offset;
|
||||
|
||||
@@ -222,8 +222,8 @@ namespace l
|
||||
|
||||
static
|
||||
int
|
||||
set(const std::string &str_,
|
||||
Branches::Impl *branches_)
|
||||
set(const std::string_view str_,
|
||||
Branches::Impl *branches_)
|
||||
{
|
||||
int rv;
|
||||
StrVec paths;
|
||||
@@ -244,8 +244,8 @@ namespace l
|
||||
|
||||
static
|
||||
int
|
||||
add_begin(const std::string &str_,
|
||||
Branches::Impl *branches_)
|
||||
add_begin(const std::string_view str_,
|
||||
Branches::Impl *branches_)
|
||||
{
|
||||
int rv;
|
||||
std::vector<std::string> paths;
|
||||
@@ -268,8 +268,8 @@ namespace l
|
||||
|
||||
static
|
||||
int
|
||||
add_end(const std::string &str_,
|
||||
Branches::Impl *branches_)
|
||||
add_end(const std::string_view str_,
|
||||
Branches::Impl *branches_)
|
||||
{
|
||||
int rv;
|
||||
StrVec paths;
|
||||
@@ -310,8 +310,8 @@ namespace l
|
||||
|
||||
static
|
||||
int
|
||||
erase_fnmatch(const std::string &str_,
|
||||
Branches::Impl *branches_)
|
||||
erase_fnmatch(const std::string_view str_,
|
||||
Branches::Impl *branches_)
|
||||
{
|
||||
StrVec patterns;
|
||||
|
||||
@@ -336,7 +336,7 @@ namespace l
|
||||
}
|
||||
|
||||
int
|
||||
Branches::Impl::from_string(const std::string &s_)
|
||||
Branches::Impl::from_string(const std::string_view s_)
|
||||
{
|
||||
std::string instr;
|
||||
std::string values;
|
||||
@@ -403,7 +403,7 @@ Branches::Impl::to_paths() const
|
||||
}
|
||||
|
||||
int
|
||||
Branches::from_string(const std::string &str_)
|
||||
Branches::from_string(const std::string_view str_)
|
||||
{
|
||||
int rv;
|
||||
Branches::Ptr impl;
|
||||
@@ -462,7 +462,7 @@ SrcMounts::SrcMounts(Branches &b_)
|
||||
}
|
||||
|
||||
int
|
||||
SrcMounts::from_string(const std::string &s_)
|
||||
SrcMounts::from_string(const std::string_view s_)
|
||||
{
|
||||
// return _branches.from_string(s_);
|
||||
return 0;
|
||||
|
||||
+10
-3
@@ -46,7 +46,7 @@ public:
|
||||
Impl(const u64 &default_minfreespace);
|
||||
|
||||
public:
|
||||
int from_string(const std::string &str) final;
|
||||
int from_string(const std::string_view str) final;
|
||||
std::string to_string(void) const final;
|
||||
|
||||
public:
|
||||
@@ -73,13 +73,20 @@ public:
|
||||
{}
|
||||
|
||||
public:
|
||||
int from_string(const std::string &str) final;
|
||||
int from_string(const std::string_view str) final;
|
||||
std::string to_string(void) const final;
|
||||
|
||||
public:
|
||||
operator Ptr() const { std::lock_guard<std::mutex> lg(_mutex); return _impl; }
|
||||
Ptr operator->() const { std::lock_guard<std::mutex> lg(_mutex); return _impl; }
|
||||
|
||||
public:
|
||||
Impl::iterator begin() { return _impl->begin(); }
|
||||
Impl::iterator end() { return _impl->end(); }
|
||||
Impl::const_iterator begin() const { return _impl->begin(); }
|
||||
Impl::const_iterator end() const { return _impl->end(); }
|
||||
|
||||
|
||||
public:
|
||||
void find_and_set_mode_ro();
|
||||
};
|
||||
@@ -90,7 +97,7 @@ public:
|
||||
SrcMounts(Branches &b);
|
||||
|
||||
public:
|
||||
int from_string(const std::string &str) final;
|
||||
int from_string(const std::string_view str) final;
|
||||
std::string to_string(void) const final;
|
||||
|
||||
private:
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
#include <string>
|
||||
|
||||
int
|
||||
Category::Base::from_string(const std::string &s_)
|
||||
Category::Base::from_string(const std::string_view s_)
|
||||
{
|
||||
int rv;
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ namespace Category
|
||||
class Base : public ToFromString
|
||||
{
|
||||
public:
|
||||
int from_string(const std::string &s) final;
|
||||
int from_string(const std::string_view s) final;
|
||||
std::string to_string() const final;
|
||||
|
||||
protected:
|
||||
|
||||
+2
-1
@@ -56,6 +56,7 @@
|
||||
|
||||
typedef ToFromWrapper<bool> ConfigBOOL;
|
||||
typedef ToFromWrapper<uint64_t> ConfigUINT64;
|
||||
typedef ToFromWrapper<int64_t> ConfigS64;
|
||||
typedef ToFromWrapper<int> ConfigINT;
|
||||
typedef ToFromWrapper<std::string> ConfigSTR;
|
||||
typedef ToFromWrapper<std::filesystem::path> ConfigPath;
|
||||
@@ -161,7 +162,7 @@ public:
|
||||
StatFS statfs;
|
||||
StatFSIgnore statfs_ignore;
|
||||
ConfigBOOL symlinkify;
|
||||
ConfigUINT64 symlinkify_timeout;
|
||||
ConfigS64 symlinkify_timeout;
|
||||
ConfigINT fuse_read_thread_count;
|
||||
ConfigINT fuse_process_thread_count;
|
||||
ConfigINT fuse_process_thread_queue_depth;
|
||||
|
||||
@@ -45,7 +45,7 @@ CacheFiles::to_string() const
|
||||
|
||||
template<>
|
||||
int
|
||||
CacheFiles::from_string(const std::string &s_)
|
||||
CacheFiles::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "libfuse")
|
||||
_data = CacheFiles::ENUM::LIBFUSE;
|
||||
|
||||
@@ -39,7 +39,7 @@ FlushOnClose::to_string() const
|
||||
|
||||
template<>
|
||||
int
|
||||
FlushOnClose::from_string(const std::string &s_)
|
||||
FlushOnClose::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "never")
|
||||
_data = FlushOnClose::ENUM::NEVER;
|
||||
|
||||
@@ -41,7 +41,7 @@ FollowSymlinks::to_string(void) const
|
||||
|
||||
template<>
|
||||
int
|
||||
FollowSymlinks::from_string(const std::string &s_)
|
||||
FollowSymlinks::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "never")
|
||||
_data = FollowSymlinks::ENUM::NEVER;
|
||||
|
||||
@@ -23,7 +23,7 @@ GIDCacheExpireTimeout::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
GIDCacheExpireTimeout::from_string(const std::string &s_)
|
||||
GIDCacheExpireTimeout::from_string(const std::string_view s_)
|
||||
{
|
||||
int rv;
|
||||
|
||||
@@ -53,7 +53,7 @@ GIDCacheRemoveTimeout::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
GIDCacheRemoveTimeout::from_string(const std::string &s_)
|
||||
GIDCacheRemoveTimeout::from_string(const std::string_view s_)
|
||||
{
|
||||
int rv;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
|
||||
public:
|
||||
std::string to_string(void) const final;
|
||||
int from_string(const std::string &) final;
|
||||
int from_string(const std::string_view) final;
|
||||
};
|
||||
|
||||
class GIDCacheRemoveTimeout : public ToFromString
|
||||
@@ -21,5 +21,5 @@ public:
|
||||
|
||||
public:
|
||||
std::string to_string(void) const final;
|
||||
int from_string(const std::string &) final;
|
||||
int from_string(const std::string_view) final;
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ InodeCalc::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
InodeCalc::from_string(const std::string &s_)
|
||||
InodeCalc::from_string(const std::string_view s_)
|
||||
{
|
||||
return fs::inode::set_algo(s_);
|
||||
}
|
||||
|
||||
@@ -28,5 +28,5 @@ public:
|
||||
|
||||
public:
|
||||
std::string to_string(void) const final;
|
||||
int from_string(const std::string &) final;
|
||||
int from_string(const std::string_view) final;
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ LinkEXDEV::to_string(void) const
|
||||
|
||||
template<>
|
||||
int
|
||||
LinkEXDEV::from_string(const std::string &s_)
|
||||
LinkEXDEV::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "passthrough")
|
||||
_data = LinkEXDEV::ENUM::PASSTHROUGH;
|
||||
|
||||
@@ -38,7 +38,7 @@ LogMetrics::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
LogMetrics::from_string(const std::string &s_)
|
||||
LogMetrics::from_string(const std::string_view s_)
|
||||
{
|
||||
int rv;
|
||||
bool val;
|
||||
|
||||
@@ -27,5 +27,5 @@ public:
|
||||
|
||||
public:
|
||||
std::string to_string(void) const final;
|
||||
int from_string(const std::string &) final;
|
||||
int from_string(const std::string_view) final;
|
||||
};
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
|
||||
int
|
||||
MoveOnENOSPC::from_string(const std::string &s_)
|
||||
MoveOnENOSPC::from_string(const std::string_view s_)
|
||||
{
|
||||
int rv;
|
||||
std::string s;
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
int from_string(const std::string &s) final;
|
||||
int from_string(const std::string_view s) final;
|
||||
std::string to_string() const final;
|
||||
|
||||
public:
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
template<>
|
||||
int
|
||||
NFSOpenHack::from_string(const std::string &s_)
|
||||
NFSOpenHack::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "off")
|
||||
_data = NFSOpenHack::ENUM::OFF;
|
||||
|
||||
@@ -44,7 +44,7 @@ ConfigPageSize::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
ConfigPageSize::from_string(const std::string &s_)
|
||||
ConfigPageSize::from_string(const std::string_view s_)
|
||||
{
|
||||
uint64_t v;
|
||||
uint64_t pagesize;
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
|
||||
public:
|
||||
std::string to_string(void) const final;
|
||||
int from_string(const std::string &) final;
|
||||
int from_string(const std::string_view) final;
|
||||
|
||||
public:
|
||||
ConfigPageSize&
|
||||
|
||||
@@ -41,7 +41,7 @@ Passthrough::to_string() const
|
||||
|
||||
template<>
|
||||
int
|
||||
Passthrough::from_string(const std::string &s_)
|
||||
Passthrough::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "off")
|
||||
_data = Passthrough::ENUM::OFF;
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public:
|
||||
}
|
||||
|
||||
int
|
||||
from_string(const std::string &) final
|
||||
from_string(const std::string_view) final
|
||||
{
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ RenameEXDEV::to_string(void) const
|
||||
|
||||
template<>
|
||||
int
|
||||
RenameEXDEV::from_string(const std::string &s_)
|
||||
RenameEXDEV::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "passthrough")
|
||||
_data = RenameEXDEV::ENUM::PASSTHROUGH;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ ConfigSet::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
ConfigSet::from_string(const std::string &str_)
|
||||
ConfigSet::from_string(const std::string_view str_)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
|
||||
+1
-1
@@ -31,5 +31,5 @@ public:
|
||||
|
||||
public:
|
||||
std::string to_string(void) const final;
|
||||
int from_string(const std::string &) final;
|
||||
int from_string(const std::string_view) final;
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ StatFS::to_string() const
|
||||
|
||||
template<>
|
||||
int
|
||||
StatFS::from_string(const std::string &s_)
|
||||
StatFS::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "base")
|
||||
_data = StatFS::ENUM::BASE;
|
||||
|
||||
@@ -40,7 +40,7 @@ StatFSIgnore::to_string() const
|
||||
|
||||
template<>
|
||||
int
|
||||
StatFSIgnore::from_string(const std::string &s_)
|
||||
StatFSIgnore::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "none")
|
||||
_data = StatFSIgnore::ENUM::NONE;
|
||||
|
||||
@@ -40,7 +40,7 @@ XAttr::to_string() const
|
||||
|
||||
template<>
|
||||
int
|
||||
XAttr::from_string(const std::string &s_)
|
||||
XAttr::from_string(const std::string_view s_)
|
||||
{
|
||||
if(s_ == "passthrough")
|
||||
_data = XAttr::ENUM::PASSTHROUGH;
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
public:
|
||||
std::string to_string() const final;
|
||||
int from_string(const std::string &) final;
|
||||
int from_string(const std::string_view) final;
|
||||
|
||||
public:
|
||||
int to_int() const
|
||||
|
||||
+163
-107
@@ -21,119 +21,175 @@
|
||||
#include "ef.hpp"
|
||||
#include "errno.hpp"
|
||||
|
||||
#include <charconv>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
namespace str
|
||||
int
|
||||
str::from(const std::string_view value_,
|
||||
bool *bool_)
|
||||
{
|
||||
int
|
||||
from(const std::string &value_,
|
||||
bool *bool_)
|
||||
{
|
||||
if((value_ == "true") ||
|
||||
(value_ == "1") ||
|
||||
(value_ == "on") ||
|
||||
(value_ == "yes"))
|
||||
*bool_ = true;
|
||||
ef((value_ == "false") ||
|
||||
(value_ == "0") ||
|
||||
(value_ == "off") ||
|
||||
(value_ == "no"))
|
||||
*bool_ = false;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
from(const std::string &value_,
|
||||
int *int_)
|
||||
{
|
||||
int tmp;
|
||||
char *endptr;
|
||||
|
||||
errno = 0;
|
||||
tmp = ::strtol(value_.c_str(),&endptr,10);
|
||||
if(errno != 0)
|
||||
return -EINVAL;
|
||||
if(endptr == value_.c_str())
|
||||
return -EINVAL;
|
||||
|
||||
*int_ = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
from(const std::string &value_,
|
||||
uint64_t *uint64_)
|
||||
{
|
||||
char *endptr;
|
||||
uint64_t tmp;
|
||||
|
||||
tmp = ::strtoll(value_.c_str(),&endptr,10);
|
||||
switch(*endptr)
|
||||
{
|
||||
case 'b':
|
||||
case 'B':
|
||||
tmp *= 1ULL;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
tmp *= 1024ULL;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
tmp *= (1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
tmp *= (1024ULL * 1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
tmp *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*uint64_ = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
from(const std::string &value_,
|
||||
std::string *str_)
|
||||
{
|
||||
*str_ = value_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
from(const std::string &value_,
|
||||
const std::string *key_)
|
||||
{
|
||||
if((value_ == "true") ||
|
||||
(value_ == "1") ||
|
||||
(value_ == "on") ||
|
||||
(value_ == "yes"))
|
||||
*bool_ = true;
|
||||
ef((value_ == "false") ||
|
||||
(value_ == "0") ||
|
||||
(value_ == "off") ||
|
||||
(value_ == "no"))
|
||||
*bool_ = false;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
from(const std::string &value_,
|
||||
fs::Path *path_)
|
||||
{
|
||||
*path_ = value_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
str::from(const std::string_view val_,
|
||||
int *rv_)
|
||||
{
|
||||
int tmp;
|
||||
const int base = 10;
|
||||
|
||||
auto [ptr,ec] = std::from_chars(val_.begin(),
|
||||
val_.end(),
|
||||
tmp,
|
||||
base);
|
||||
if(ec != std::errc{})
|
||||
return -EINVAL;
|
||||
|
||||
*rv_ = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
str::from(const std::string_view val_,
|
||||
int64_t *rv_)
|
||||
{
|
||||
int64_t tmp;
|
||||
const int base = 10;
|
||||
|
||||
auto [ptr,ec] = std::from_chars(val_.begin(),
|
||||
val_.end(),
|
||||
tmp,
|
||||
base);
|
||||
|
||||
if(ec != std::errc{})
|
||||
return -EINVAL;
|
||||
*rv_ = tmp;
|
||||
if(ptr == val_.end())
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(*ptr)
|
||||
{
|
||||
case 'b':
|
||||
case 'B':
|
||||
*rv_ *= 1ULL;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
*rv_ *= 1024ULL;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
*rv_ *= (1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
*rv_ *= (1024ULL * 1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
*rv_ *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
str::from(const std::string_view val_,
|
||||
uint64_t *rv_)
|
||||
{
|
||||
uint64_t tmp;
|
||||
const int base = 10;
|
||||
|
||||
auto [ptr,ec] = std::from_chars(val_.begin(),
|
||||
val_.end(),
|
||||
tmp,
|
||||
base);
|
||||
|
||||
if(ec != std::errc{})
|
||||
return -EINVAL;
|
||||
*rv_ = tmp;
|
||||
if(ptr == val_.end())
|
||||
return 0;
|
||||
|
||||
switch(*ptr)
|
||||
{
|
||||
case 'b':
|
||||
case 'B':
|
||||
*rv_ *= 1ULL;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
*rv_ *= 1024ULL;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
*rv_ *= (1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
*rv_ *= (1024ULL * 1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
*rv_ *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
str::from(const std::string_view value_,
|
||||
std::string *str_)
|
||||
{
|
||||
*str_ = value_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
str::from(const std::string_view value_,
|
||||
const std::string *key_)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
str::from(const std::string_view value_,
|
||||
std::filesystem::path *path_)
|
||||
{
|
||||
*path_ = value_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+9
-8
@@ -18,18 +18,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fs_path.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
|
||||
namespace str
|
||||
{
|
||||
int from(const std::string &, bool *);
|
||||
int from(const std::string &, int *);
|
||||
int from(const std::string &, uint64_t *);
|
||||
int from(const std::string &, std::string *);
|
||||
int from(const std::string &, const std::string *);
|
||||
int from(const std::string &, fs::Path *);
|
||||
int from(const std::string_view, bool *);
|
||||
int from(const std::string_view, int *);
|
||||
int from(const std::string_view, uint64_t *);
|
||||
int from(const std::string_view, int64_t *);
|
||||
int from(const std::string_view, std::string *);
|
||||
int from(const std::string_view, const std::string *);
|
||||
int from(const std::string_view, std::filesystem::path *);
|
||||
}
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ _hybrid_hash32(const std::string_view branch_path_,
|
||||
}
|
||||
|
||||
int
|
||||
fs::inode::set_algo(const std::string &algo_)
|
||||
fs::inode::set_algo(const std::string_view algo_)
|
||||
{
|
||||
if(algo_ == "passthrough")
|
||||
g_func = ::_passthrough;
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ namespace fs
|
||||
{
|
||||
namespace inode
|
||||
{
|
||||
int set_algo(const std::string &s);
|
||||
int set_algo(const std::string_view s);
|
||||
std::string get_algo(void);
|
||||
|
||||
uint64_t calc(const std::string_view basepath,
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@
|
||||
|
||||
|
||||
int
|
||||
Func::Base::Action::from_string(const std::string &policyname_)
|
||||
Func::Base::Action::from_string(const std::string_view policyname_)
|
||||
{
|
||||
policy = Policies::Action::find(policyname_);
|
||||
if(!policy)
|
||||
@@ -36,7 +36,7 @@ Func::Base::Action::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
Func::Base::Create::from_string(const std::string &policyname_)
|
||||
Func::Base::Create::from_string(const std::string_view policyname_)
|
||||
{
|
||||
policy = Policies::Create::find(policyname_);
|
||||
if(!policy)
|
||||
@@ -52,7 +52,7 @@ Func::Base::Create::to_string(void) const
|
||||
}
|
||||
|
||||
int
|
||||
Func::Base::Search::from_string(const std::string &policyname_)
|
||||
Func::Base::Search::from_string(const std::string_view policyname_)
|
||||
{
|
||||
policy = Policies::Search::find(policyname_);
|
||||
if(!policy)
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ namespace Func
|
||||
{}
|
||||
|
||||
public:
|
||||
int from_string(const std::string &s) final;
|
||||
int from_string(const std::string_view s) final;
|
||||
std::string to_string() const final;
|
||||
|
||||
public:
|
||||
@@ -52,7 +52,7 @@ namespace Func
|
||||
{}
|
||||
|
||||
public:
|
||||
int from_string(const std::string &s) final;
|
||||
int from_string(const std::string_view s) final;
|
||||
std::string to_string() const final;
|
||||
|
||||
public:
|
||||
@@ -67,7 +67,7 @@ namespace Func
|
||||
{}
|
||||
|
||||
public:
|
||||
int from_string(const std::string &s) final;
|
||||
int from_string(const std::string_view s) final;
|
||||
std::string to_string() const final;
|
||||
|
||||
public:
|
||||
|
||||
@@ -192,8 +192,6 @@ FUSE::init(fuse_conn_info *conn_)
|
||||
procfs::init();
|
||||
ugid::init();
|
||||
|
||||
cfg->readdir.initialize();
|
||||
|
||||
::_want_if_capable(conn_,FUSE_CAP_ASYNC_DIO);
|
||||
::_want_if_capable(conn_,FUSE_CAP_ASYNC_READ,&cfg->async_read);
|
||||
::_want_if_capable(conn_,FUSE_CAP_ATOMIC_O_TRUNC);
|
||||
|
||||
+16
-39
@@ -44,56 +44,36 @@ FUSE::readdir(const fuse_file_info_t *ffi_,
|
||||
return cfg->readdir(ffi_,buf_);
|
||||
}
|
||||
|
||||
FUSE::ReadDir::ReadDir(std::string const s_)
|
||||
: _initialized(false)
|
||||
FUSE::ReadDir::ReadDir(const std::string_view s_)
|
||||
: _str(new std::string())
|
||||
{
|
||||
from_string(s_);
|
||||
if(_initialized)
|
||||
assert(_readdir);
|
||||
}
|
||||
|
||||
std::string
|
||||
FUSE::ReadDir::to_string() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
std::shared_ptr<std::string> str;
|
||||
|
||||
return _type;
|
||||
}
|
||||
str = std::atomic_load(&_str);
|
||||
|
||||
void
|
||||
FUSE::ReadDir::initialize()
|
||||
{
|
||||
_initialized = true;
|
||||
from_string(_type);
|
||||
return (*str);
|
||||
}
|
||||
|
||||
int
|
||||
FUSE::ReadDir::from_string(std::string const &str_)
|
||||
FUSE::ReadDir::from_string(const std::string_view str_)
|
||||
{
|
||||
if(_initialized)
|
||||
{
|
||||
std::shared_ptr<FUSE::ReadDirBase> tmp;
|
||||
std::shared_ptr<std::string> tmp_str;
|
||||
std::shared_ptr<FUSE::ReadDirBase> tmp_readdir;
|
||||
|
||||
tmp = FUSE::ReadDirFactory::make(str_);
|
||||
if(!tmp)
|
||||
return -EINVAL;
|
||||
tmp_readdir = FUSE::ReadDirFactory::make(str_);
|
||||
if(!tmp_readdir)
|
||||
return -EINVAL;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
tmp_str = std::make_shared<std::string>(str_);
|
||||
|
||||
_type = str_;
|
||||
std::swap(_readdir,tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
|
||||
if(!FUSE::ReadDirFactory::valid(str_))
|
||||
return -EINVAL;
|
||||
|
||||
_type = str_;
|
||||
}
|
||||
std::atomic_store(&_str,tmp_str);
|
||||
std::atomic_store(&_impl,tmp_readdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -113,7 +93,7 @@ _handle_ENOENT(const fuse_file_info_t *ffi_,
|
||||
|
||||
de.d_ino = 0;
|
||||
de.d_off = 0;
|
||||
de.d_type = DT_REG;
|
||||
de.d_type = DT_UNKNOWN;
|
||||
strcpy(de.d_name,"error: no valid mergerfs branch found, check config");
|
||||
de.d_reclen = sizeof(de);
|
||||
|
||||
@@ -134,10 +114,7 @@ FUSE::ReadDir::operator()(const fuse_file_info_t *ffi_,
|
||||
int rv;
|
||||
std::shared_ptr<FUSE::ReadDirBase> readdir;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
readdir = _readdir;
|
||||
}
|
||||
readdir = std::atomic_load(&_impl);
|
||||
|
||||
rv = (*readdir)(ffi_,buf_);
|
||||
if(rv == -ENOENT)
|
||||
|
||||
+8
-15
@@ -25,37 +25,30 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// The initialization behavior is not pretty but for the moment
|
||||
// needed due to the daemonizing function of the libfuse library when
|
||||
// not using foreground mode. The threads need to be created after the
|
||||
// fork, not before.
|
||||
|
||||
namespace FUSE
|
||||
{
|
||||
int readdir(fuse_file_info_t const *ffi,
|
||||
fuse_dirents_t *buf);
|
||||
}
|
||||
|
||||
namespace FUSE
|
||||
{
|
||||
class ReadDir : public ToFromString
|
||||
{
|
||||
public:
|
||||
ReadDir(std::string const s_);
|
||||
ReadDir(const std::string_view s_);
|
||||
|
||||
public:
|
||||
std::string to_string() const;
|
||||
int from_string(const std::string &);
|
||||
int from_string(const std::string_view);
|
||||
|
||||
public:
|
||||
int operator()(fuse_file_info_t const *ffi,
|
||||
fuse_dirents_t *buf);
|
||||
|
||||
public:
|
||||
void initialize();
|
||||
|
||||
private:
|
||||
mutable std::mutex _mutex;
|
||||
|
||||
private:
|
||||
bool _initialized;
|
||||
std::string _type;
|
||||
std::shared_ptr<FUSE::ReadDirBase> _readdir;
|
||||
std::shared_ptr<std::string> _str;
|
||||
std::shared_ptr<FUSE::ReadDirBase> _impl;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "fuse.h"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
|
||||
namespace FUSE
|
||||
{
|
||||
|
||||
@@ -22,31 +22,46 @@
|
||||
#include "fuse_readdir_cosr.hpp"
|
||||
#include "fuse_readdir_seq.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <set>
|
||||
|
||||
#include <regex>
|
||||
|
||||
// Regex:
|
||||
// ^([a-z]{1,15}) -> required type
|
||||
// (?::(\d+))? -> optional colon + concurrency
|
||||
// (?::(\d+))? -> optional colon + max_queue_depth
|
||||
// $ -> end of string
|
||||
static
|
||||
void
|
||||
_read_cfg(std::string const str_,
|
||||
std::string &type_,
|
||||
unsigned &concurrency_,
|
||||
unsigned &max_queue_depth_)
|
||||
_read_cfg(const std::string_view str_,
|
||||
std::string &type_,
|
||||
int &concurrency_,
|
||||
int &max_queue_depth_)
|
||||
{
|
||||
char type[16];
|
||||
std::string type;
|
||||
int concurrency;
|
||||
int max_queue_depth;
|
||||
bool matched;
|
||||
std::cmatch match;
|
||||
std::regex re(R"(^([a-z]{1,15})(?::(\d+))?(?::(\d+))?$)");
|
||||
|
||||
concurrency = 0;
|
||||
concurrency = 0;
|
||||
max_queue_depth = 0;
|
||||
std::sscanf(str_.c_str(),
|
||||
"%15[a-z]:%d:%d",
|
||||
type,
|
||||
&concurrency,
|
||||
&max_queue_depth);
|
||||
matched = std::regex_match(str_.begin(),
|
||||
str_.end(),
|
||||
match,
|
||||
re);
|
||||
if(matched)
|
||||
{
|
||||
type = match[1];
|
||||
if(match[2].matched)
|
||||
concurrency = std::stoi(match[2]);
|
||||
if(match[3].matched)
|
||||
max_queue_depth = std::stoi(match[3]);
|
||||
}
|
||||
|
||||
if(concurrency == 0)
|
||||
{
|
||||
@@ -73,37 +88,13 @@ _read_cfg(std::string const str_,
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FUSE::ReadDirFactory::valid(const std::string str_)
|
||||
{
|
||||
unsigned concurrency;
|
||||
unsigned max_queue_depth;
|
||||
std::string type;
|
||||
static const std::set<std::string> types =
|
||||
{
|
||||
"seq", "cosr", "cor"
|
||||
};
|
||||
|
||||
::_read_cfg(str_,type,concurrency,max_queue_depth);
|
||||
|
||||
if(types.find(type) == types.end())
|
||||
return false;
|
||||
if(concurrency <= 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<FUSE::ReadDirBase>
|
||||
FUSE::ReadDirFactory::make(std::string const str_)
|
||||
FUSE::ReadDirFactory::make(const std::string_view str_)
|
||||
{
|
||||
unsigned concurrency;
|
||||
unsigned max_queue_depth;
|
||||
int concurrency;
|
||||
int max_queue_depth;
|
||||
std::string type;
|
||||
|
||||
if(!valid(str_))
|
||||
return {};
|
||||
|
||||
::_read_cfg(str_,type,concurrency,max_queue_depth);
|
||||
|
||||
if(type == "seq")
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace FUSE
|
||||
class ReadDirFactory
|
||||
{
|
||||
public:
|
||||
static bool valid(std::string str);
|
||||
static std::shared_ptr<ReadDirBase> make(std::string const str);
|
||||
static std::shared_ptr<ReadDirBase> make(const std::string_view str);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -210,7 +210,11 @@ FUSE::statx(const char *fusepath_,
|
||||
if(Config::is_ctrl_file(fusepath_))
|
||||
return ::_statx_controlfile(st_);
|
||||
|
||||
return ::_statx(fusepath_,flags_|AT_STATX_DONT_SYNC,mask_,st_,timeout_);
|
||||
return ::_statx(fusepath_,
|
||||
flags_|AT_STATX_DONT_SYNC,
|
||||
mask_,
|
||||
st_,
|
||||
timeout_);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -222,5 +226,9 @@ FUSE::statx_fh(const uint64_t fh_,
|
||||
{
|
||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh_);
|
||||
|
||||
return ::_statx(fi->fusepath.c_str(),flags_,mask_,st_,timeout_);
|
||||
return ::_statx(fi->fusepath.c_str(),
|
||||
flags_|AT_STATX_DONT_SYNC,
|
||||
mask_,
|
||||
st_,
|
||||
timeout_);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@ namespace l
|
||||
orig = oom::get_oom_score_adj();
|
||||
rv = oom::set_oom_score_adj(score);
|
||||
|
||||
(void)rv;
|
||||
SysLog::info("set oom_score_adj to {}, originally {}",
|
||||
score,
|
||||
orig);
|
||||
|
||||
@@ -44,7 +44,7 @@ mergerfs::api::allpaths(const std::string &input_path_,
|
||||
if(rv < 0)
|
||||
return rv;
|
||||
|
||||
str::split_on_null(val.data(),val.size(),&output_paths_);
|
||||
str::split_on_null(val,&output_paths_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-80
@@ -24,7 +24,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
#define KB (1024ULL)
|
||||
#define MB (KB * 1024ULL)
|
||||
@@ -33,85 +33,6 @@
|
||||
|
||||
|
||||
namespace num
|
||||
{
|
||||
int
|
||||
to_uint64_t(const std::string &str,
|
||||
uint64_t &value)
|
||||
{
|
||||
char *endptr;
|
||||
uint64_t tmp;
|
||||
|
||||
tmp = strtoll(str.c_str(),&endptr,10);
|
||||
switch(*endptr)
|
||||
{
|
||||
case 'k':
|
||||
case 'K':
|
||||
tmp *= 1024;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
tmp *= (1024 * 1024);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
tmp *= (1024 * 1024 * 1024);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
tmp *= (1024ULL * 1024 * 1024 * 1024);
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
to_double(const std::string &str_,
|
||||
double *d_)
|
||||
{
|
||||
double tmp;
|
||||
char *endptr;
|
||||
|
||||
tmp = strtod(str_.c_str(),&endptr);
|
||||
if(*endptr != '\0')
|
||||
return -1;
|
||||
|
||||
*d_ = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
to_time_t(const std::string &str,
|
||||
time_t &value)
|
||||
{
|
||||
time_t tmp;
|
||||
char *endptr;
|
||||
|
||||
tmp = strtoll(str.c_str(),&endptr,10);
|
||||
if(*endptr != '\0')
|
||||
return -1;
|
||||
if(tmp < 0)
|
||||
return -1;
|
||||
|
||||
value = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace num
|
||||
{
|
||||
std::string
|
||||
humanize(const uint64_t bytes_)
|
||||
|
||||
@@ -19,14 +19,6 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
namespace num
|
||||
{
|
||||
int to_uint64_t(const std::string &str, uint64_t *value);
|
||||
int to_double(const std::string &str, double *value);
|
||||
int to_time_t(const std::string &str, time_t *value);
|
||||
}
|
||||
|
||||
namespace num
|
||||
{
|
||||
|
||||
+48
-11
@@ -204,7 +204,7 @@ _parse_and_process_kv_arg(Config::Write &cfg_,
|
||||
|
||||
static
|
||||
int
|
||||
process_opt(Config::Write &cfg_,
|
||||
_process_opt(Config::Write &cfg_,
|
||||
Config::ErrVec *errs_,
|
||||
const std::string &arg_)
|
||||
{
|
||||
@@ -220,7 +220,7 @@ process_opt(Config::Write &cfg_,
|
||||
|
||||
static
|
||||
int
|
||||
process_branches(Config::Write &cfg_,
|
||||
_process_branches(Config::Write &cfg_,
|
||||
Config::ErrVec *errs_,
|
||||
const char *arg_)
|
||||
{
|
||||
@@ -237,7 +237,7 @@ process_branches(Config::Write &cfg_,
|
||||
|
||||
static
|
||||
int
|
||||
process_mount(Config::Write &cfg_,
|
||||
_process_mount(Config::Write &cfg_,
|
||||
Config::ErrVec *errs_,
|
||||
const char *arg_)
|
||||
{
|
||||
@@ -290,10 +290,10 @@ _usage(void)
|
||||
|
||||
static
|
||||
int
|
||||
option_processor(void *data_,
|
||||
const char *arg_,
|
||||
int key_,
|
||||
fuse_args *outargs_)
|
||||
_option_processor(void *data_,
|
||||
const char *arg_,
|
||||
int key_,
|
||||
fuse_args *outargs_)
|
||||
{
|
||||
Config::Write cfg;
|
||||
Config::ErrVec *errs = (Config::ErrVec*)data_;
|
||||
@@ -301,13 +301,13 @@ option_processor(void *data_,
|
||||
switch(key_)
|
||||
{
|
||||
case FUSE_OPT_KEY_OPT:
|
||||
return process_opt(cfg,errs,arg_);
|
||||
return ::_process_opt(cfg,errs,arg_);
|
||||
|
||||
case FUSE_OPT_KEY_NONOPT:
|
||||
if(cfg->branches->empty())
|
||||
return process_branches(cfg,errs,arg_);
|
||||
return ::_process_branches(cfg,errs,arg_);
|
||||
else
|
||||
return process_mount(cfg,errs,arg_);
|
||||
return ::_process_mount(cfg,errs,arg_);
|
||||
|
||||
case MERGERFS_OPT_HELP:
|
||||
::_usage();
|
||||
@@ -367,6 +367,41 @@ _check_for_mount_loop(Config::Write &cfg_,
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
_print_warnings(Config::Write &cfg_)
|
||||
{
|
||||
if(cfg_->passthrough != Passthrough::ENUM::OFF)
|
||||
{
|
||||
if(cfg_->cache_files == CacheFiles::ENUM::OFF)
|
||||
{
|
||||
SysLog::warning("'cache.files' can not be 'off' when using 'passthrough'."
|
||||
" Setting 'cache.files=auto-full'");
|
||||
cfg_->cache_files = CacheFiles::ENUM::AUTO_FULL;
|
||||
}
|
||||
|
||||
if(cfg_->writeback_cache == true)
|
||||
{
|
||||
SysLog::warning("'cache.writeback' can not be enabled when using 'passthrough'."
|
||||
" Setting 'cache.writeback=false'");
|
||||
cfg_->writeback_cache = false;
|
||||
}
|
||||
|
||||
if(cfg_->moveonenospc.enabled == true)
|
||||
{
|
||||
SysLog::warning("`moveonenospc` will not function when `passthrough` is enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
_cleanup_options(Config::Write &cfg_)
|
||||
{
|
||||
if(!cfg_->symlinkify)
|
||||
cfg_->symlinkify_timeout = -1;
|
||||
}
|
||||
|
||||
namespace options
|
||||
{
|
||||
void
|
||||
@@ -387,7 +422,7 @@ namespace options
|
||||
fuse_opt_parse(args_,
|
||||
errs_,
|
||||
opts,
|
||||
::option_processor);
|
||||
::_option_processor);
|
||||
|
||||
if(cfg->branches->empty())
|
||||
errs_->push_back({0,"branches not set"});
|
||||
@@ -400,6 +435,8 @@ namespace options
|
||||
::_set_fsname(cfg,args_);
|
||||
::_set_subtype(args_);
|
||||
::_set_fuse_threads(cfg);
|
||||
::_print_warnings(cfg);
|
||||
::_cleanup_options(cfg);
|
||||
|
||||
cfg->finish_initializing();
|
||||
}
|
||||
|
||||
+3
-3
@@ -45,7 +45,7 @@
|
||||
FUNC(rand)
|
||||
|
||||
Policy::ActionImpl*
|
||||
Policies::Action::find(const std::string &name_)
|
||||
Policies::Action::find(const std::string_view name_)
|
||||
{
|
||||
IFERT(IFERTA);
|
||||
|
||||
@@ -53,7 +53,7 @@ Policies::Action::find(const std::string &name_)
|
||||
}
|
||||
|
||||
Policy::CreateImpl*
|
||||
Policies::Create::find(const std::string &name_)
|
||||
Policies::Create::find(const std::string_view name_)
|
||||
{
|
||||
IFERT(IFERTC);
|
||||
|
||||
@@ -61,7 +61,7 @@ Policies::Create::find(const std::string &name_)
|
||||
}
|
||||
|
||||
Policy::SearchImpl*
|
||||
Policies::Search::find(const std::string &name_)
|
||||
Policies::Search::find(const std::string_view name_)
|
||||
{
|
||||
IFERT(IFERTS);
|
||||
|
||||
|
||||
+5
-5
@@ -43,8 +43,8 @@ struct Policies
|
||||
{
|
||||
struct Action
|
||||
{
|
||||
static Policy::ActionImpl *find(const std::string &name);
|
||||
|
||||
static Policy::ActionImpl *find(const std::string_view name);
|
||||
|
||||
static Policy::All::Action all;
|
||||
static Policy::EPAll::Action epall;
|
||||
static Policy::EPFF::Action epff;
|
||||
@@ -69,8 +69,8 @@ struct Policies
|
||||
|
||||
struct Create
|
||||
{
|
||||
static Policy::CreateImpl *find(const std::string &name);
|
||||
|
||||
static Policy::CreateImpl *find(const std::string_view name);
|
||||
|
||||
static Policy::All::Create all;
|
||||
static Policy::EPAll::Create epall;
|
||||
static Policy::EPFF::Create epff;
|
||||
@@ -95,7 +95,7 @@ struct Policies
|
||||
|
||||
struct Search
|
||||
{
|
||||
static Policy::SearchImpl *find(const std::string &name);
|
||||
static Policy::SearchImpl *find(const std::string_view name);
|
||||
|
||||
static Policy::All::Search all;
|
||||
static Policy::EPAll::Search epall;
|
||||
|
||||
+88
-57
@@ -14,6 +14,11 @@
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "resources.hpp"
|
||||
|
||||
#include "fs_opendir.hpp"
|
||||
#include "fs_closedir.hpp"
|
||||
#include "fs_readdir.hpp"
|
||||
#include "errno.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
@@ -22,63 +27,89 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
namespace resources
|
||||
|
||||
int
|
||||
resources::reset_umask(void)
|
||||
{
|
||||
int
|
||||
reset_umask(void)
|
||||
{
|
||||
umask(0);
|
||||
umask(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
resources::maxout_rlimit(const int resource)
|
||||
{
|
||||
int rv;
|
||||
struct rlimit rlim;
|
||||
|
||||
rlim.rlim_cur = RLIM_INFINITY;
|
||||
rlim.rlim_max = RLIM_INFINITY;
|
||||
rv = ::setrlimit(resource,&rlim);
|
||||
if(rv == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
maxout_rlimit(const int resource)
|
||||
{
|
||||
int rv;
|
||||
struct rlimit rlim;
|
||||
|
||||
rlim.rlim_cur = RLIM_INFINITY;
|
||||
rlim.rlim_max = RLIM_INFINITY;
|
||||
rv = ::setrlimit(resource,&rlim);
|
||||
if(rv == 0)
|
||||
return 0;
|
||||
|
||||
rv = ::getrlimit(resource,&rlim);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = 0;
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
while(rv == 0)
|
||||
{
|
||||
rv = ::setrlimit(resource,&rlim);
|
||||
rlim.rlim_max *= 2;
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
maxout_rlimit_nofile(void)
|
||||
{
|
||||
return maxout_rlimit(RLIMIT_NOFILE);
|
||||
}
|
||||
|
||||
int
|
||||
maxout_rlimit_fsize(void)
|
||||
{
|
||||
return maxout_rlimit(RLIMIT_FSIZE);
|
||||
}
|
||||
|
||||
int
|
||||
setpriority(const int prio)
|
||||
{
|
||||
int rv;
|
||||
const int SELF = 0;
|
||||
|
||||
rv = ::setpriority(PRIO_PROCESS,SELF,prio);
|
||||
|
||||
return ((rv == -1) ? -errno : rv);
|
||||
}
|
||||
|
||||
rv = ::getrlimit(resource,&rlim);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = 0;
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
while(rv == 0)
|
||||
{
|
||||
rv = ::setrlimit(resource,&rlim);
|
||||
rlim.rlim_max *= 2;
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
resources::maxout_rlimit_nofile(void)
|
||||
{
|
||||
return maxout_rlimit(RLIMIT_NOFILE);
|
||||
}
|
||||
|
||||
int
|
||||
resources::maxout_rlimit_fsize(void)
|
||||
{
|
||||
return maxout_rlimit(RLIMIT_FSIZE);
|
||||
}
|
||||
|
||||
int
|
||||
resources::setpriority(const int prio_)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *e;
|
||||
|
||||
::setpriority(PRIO_PROCESS,0,prio_);
|
||||
|
||||
dir = fs::opendir("/proc/self/task");
|
||||
if(dir == NULL)
|
||||
return -errno;
|
||||
|
||||
while(true)
|
||||
{
|
||||
pid_t tid;
|
||||
|
||||
e = fs::readdir(dir);
|
||||
if(e == NULL)
|
||||
break;
|
||||
if(e->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
tid = std::stoi(e->d_name);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
::setpriority(PRIO_PROCESS,tid,prio_);
|
||||
}
|
||||
|
||||
fs::closedir(dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,66 @@
|
||||
#include "state.hpp"
|
||||
|
||||
#include "fmt/core.h"
|
||||
|
||||
#include "errno.hpp"
|
||||
|
||||
|
||||
State state;
|
||||
|
||||
// static
|
||||
// void
|
||||
// _register_getattr(State *state_)
|
||||
// {
|
||||
// State::GetSet x;
|
||||
|
||||
// x.get = [state_]() -> std::string
|
||||
// {
|
||||
// return state_->getattr.to_string();
|
||||
// };
|
||||
// x.set = [state_](const std::string_view s_) -> int
|
||||
// {
|
||||
// return state_->getattr.from_string(s_);
|
||||
// };
|
||||
|
||||
// state_->set_getset("user.mergerfs.func.getattr",x);
|
||||
// }
|
||||
|
||||
State::State()
|
||||
{
|
||||
// _register_getattr(this);
|
||||
}
|
||||
|
||||
void
|
||||
State::set_getset(const std::string &name_,
|
||||
const State::GetSet &gs_)
|
||||
{
|
||||
_getset[name_] = gs_;
|
||||
}
|
||||
|
||||
int
|
||||
State::get(const std::string &key_,
|
||||
std::string &val_)
|
||||
{
|
||||
std::map<std::string,State::GetSet>::iterator i;
|
||||
|
||||
i = _getset.find(key_);
|
||||
if((i == _getset.end()) || (!i->second.get))
|
||||
return -ENOATTR;
|
||||
|
||||
val_ = i->second.get();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
State::set(const std::string &key_,
|
||||
const std::string_view val_)
|
||||
{
|
||||
std::map<std::string,State::GetSet>::iterator i;
|
||||
|
||||
i = _getset.find(key_);
|
||||
if((i == _getset.end()) || (!i->second.set))
|
||||
return -ENOATTR;
|
||||
|
||||
return i->second.set(val_);
|
||||
}
|
||||
|
||||
@@ -4,11 +4,18 @@
|
||||
|
||||
#include "fileinfo.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
constexpr int INVALID_BACKING_ID = -1;
|
||||
|
||||
class State
|
||||
{
|
||||
public:
|
||||
State();
|
||||
|
||||
public:
|
||||
struct OpenFile
|
||||
{
|
||||
@@ -24,10 +31,27 @@ public:
|
||||
FileInfo *fi;
|
||||
};
|
||||
|
||||
public:
|
||||
struct GetSet
|
||||
{
|
||||
std::function<std::string()> get;
|
||||
std::function<int(const std::string_view)> set;
|
||||
};
|
||||
|
||||
void set_getset(const std::string &name,
|
||||
const State::GetSet &gs);
|
||||
|
||||
int get(const std::string &key,
|
||||
std::string &val);
|
||||
int set(const std::string &key,
|
||||
const std::string_view val);
|
||||
|
||||
public:
|
||||
using OpenFileMap = boost::concurrent_flat_map<u64,OpenFile>;
|
||||
|
||||
private:
|
||||
std::map<std::string,GetSet> _getset;
|
||||
|
||||
public:
|
||||
OpenFileMap open_files;
|
||||
};
|
||||
|
||||
+217
-238
@@ -28,275 +28,254 @@
|
||||
using std::istringstream;
|
||||
using std::set;
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using std::vector;
|
||||
|
||||
namespace str
|
||||
|
||||
void
|
||||
str::split(const string_view str_,
|
||||
const char delimiter_,
|
||||
vector<string> *result_)
|
||||
{
|
||||
void
|
||||
split(const char *str_,
|
||||
const char delimiter_,
|
||||
vector<string> *result_)
|
||||
{
|
||||
string part;
|
||||
istringstream ss(str_);
|
||||
size_t pos;
|
||||
size_t start;
|
||||
|
||||
while(std::getline(ss,part,delimiter_))
|
||||
result_->push_back(part);
|
||||
}
|
||||
start = 0;
|
||||
pos = str_.find(delimiter_,start);
|
||||
while(pos != std::string_view::npos)
|
||||
{
|
||||
result_->push_back(std::string{str_.substr(start,pos)});
|
||||
start = (pos + 1);
|
||||
pos = str_.find(delimiter_,start);
|
||||
}
|
||||
|
||||
void
|
||||
split(const char *str_,
|
||||
const char delimiter_,
|
||||
set<string> *result_)
|
||||
{
|
||||
string part;
|
||||
istringstream ss(str_);
|
||||
result_->push_back(std::string{str_.substr(start)});
|
||||
}
|
||||
|
||||
while(std::getline(ss,part,delimiter_))
|
||||
result_->insert(part);
|
||||
}
|
||||
void
|
||||
str::split(const string_view str_,
|
||||
const char delimiter_,
|
||||
set<string> *result_)
|
||||
{
|
||||
size_t pos;
|
||||
size_t start;
|
||||
|
||||
void
|
||||
split(const string &str_,
|
||||
const char delimiter_,
|
||||
vector<string> *result_)
|
||||
{
|
||||
return str::split(str_.c_str(),delimiter_,result_);
|
||||
}
|
||||
start = 0;
|
||||
pos = str_.find(delimiter_,start);
|
||||
while(pos != std::string_view::npos)
|
||||
{
|
||||
result_->insert(std::string{str_.substr(start,pos)});
|
||||
start = (pos + 1);
|
||||
pos = str_.find(delimiter_,start);
|
||||
}
|
||||
|
||||
void
|
||||
split(const string &str_,
|
||||
const char delimiter_,
|
||||
set<string> *result_)
|
||||
{
|
||||
return str::split(str_.c_str(),delimiter_,result_);
|
||||
}
|
||||
result_->insert(std::string{str_.substr(start)});
|
||||
}
|
||||
|
||||
void
|
||||
split_on_null(const char *str_,
|
||||
const size_t len_,
|
||||
std::vector<std::string> *result_)
|
||||
{
|
||||
const char *start;
|
||||
const char *end;
|
||||
void
|
||||
str::split_on_null(const std::string_view str_,
|
||||
std::vector<std::string> *result_)
|
||||
{
|
||||
const char *start;
|
||||
const char *end;
|
||||
|
||||
start = str_;
|
||||
end = start + len_;
|
||||
while(start < end)
|
||||
{
|
||||
result_->emplace_back(start);
|
||||
start += (result_->back().size() + 1);
|
||||
}
|
||||
}
|
||||
start = str_.begin();
|
||||
end = str_.end();
|
||||
while(start < end)
|
||||
{
|
||||
result_->emplace_back(start);
|
||||
start += (result_->back().size() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rsplit1(const string &str_,
|
||||
const char delimiter_,
|
||||
vector<string> *result_)
|
||||
{
|
||||
std::size_t off;
|
||||
void
|
||||
str::rsplit1(const string_view &str_,
|
||||
const char delimiter_,
|
||||
vector<string> *result_)
|
||||
{
|
||||
std::size_t off;
|
||||
|
||||
off = str_.rfind('=');
|
||||
if(off == std::string::npos)
|
||||
{
|
||||
result_->push_back(str_);
|
||||
}
|
||||
else
|
||||
{
|
||||
result_->push_back(str_.substr(0,off));
|
||||
result_->push_back(str_.substr(off+1));
|
||||
}
|
||||
}
|
||||
off = str_.rfind('=');
|
||||
if(off == std::string::npos)
|
||||
{
|
||||
result_->push_back(std::string{str_});
|
||||
}
|
||||
else
|
||||
{
|
||||
result_->push_back(std::string{str_.substr(0,off)});
|
||||
result_->push_back(std::string{str_.substr(off+1)});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
splitkv(const std::string_view &str_,
|
||||
const char delimiter_,
|
||||
std::string &key_,
|
||||
std::string_view &val_)
|
||||
{
|
||||
size_t pos;
|
||||
void
|
||||
str::splitkv(const std::string_view str_,
|
||||
const char delimiter_,
|
||||
std::string *key_,
|
||||
std::string *val_)
|
||||
{
|
||||
size_t pos;
|
||||
|
||||
pos = str_.find(delimiter_);
|
||||
if(pos != std::string_view::npos)
|
||||
{
|
||||
key_ = str_.substr(0,pos);
|
||||
val_ = str_.substr(pos + 1,
|
||||
str_.size() - pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
key_ = str_;
|
||||
val_ = std::string_view{};
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
splitkv(const string &str_,
|
||||
const char delimiter_,
|
||||
string *key_,
|
||||
string *val_)
|
||||
{
|
||||
istringstream iss;
|
||||
std::string key;
|
||||
std::string val;
|
||||
|
||||
iss.str(str_);
|
||||
std::getline(iss,key,delimiter_);
|
||||
std::getline(iss,val,'\0');
|
||||
|
||||
*key_ = key;
|
||||
*val_ = val;
|
||||
}
|
||||
|
||||
string
|
||||
join(const vector<string> &vec_,
|
||||
const size_t substridx_,
|
||||
const char sep_)
|
||||
{
|
||||
if(vec_.empty())
|
||||
return string();
|
||||
|
||||
string rv = vec_[0].substr(substridx_);
|
||||
for(size_t i = 1; i < vec_.size(); i++)
|
||||
rv += sep_ + vec_[i].substr(substridx_);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
string
|
||||
join(const vector<string> &vec_,
|
||||
const char sep_)
|
||||
{
|
||||
return str::join(vec_,0,sep_);
|
||||
}
|
||||
|
||||
string
|
||||
join(const set<string> &set_,
|
||||
const char sep_)
|
||||
{
|
||||
string rv;
|
||||
|
||||
for(auto const &s : set_)
|
||||
rv += s + sep_;
|
||||
rv.pop_back();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
size_t
|
||||
longest_common_prefix_index(const vector<string> &vec_)
|
||||
{
|
||||
if(vec_.empty())
|
||||
return string::npos;
|
||||
|
||||
for(size_t n = 0; n < vec_[0].size(); n++)
|
||||
{
|
||||
char chr = vec_[0][n];
|
||||
for(size_t i = 1; i < vec_.size(); i++)
|
||||
{
|
||||
if(n >= vec_[i].size())
|
||||
return n;
|
||||
if(vec_[i][n] != chr)
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return string::npos;
|
||||
}
|
||||
|
||||
string
|
||||
longest_common_prefix(const vector<string> &vec_)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
idx = longest_common_prefix_index(vec_);
|
||||
if(idx != string::npos)
|
||||
return vec_[0].substr(0,idx);
|
||||
pos = str_.find(delimiter_);
|
||||
if(pos != std::string_view::npos)
|
||||
{
|
||||
*key_ = str_.substr(0, pos);
|
||||
*val_ = str_.substr(pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*key_ = str_;
|
||||
*val_ = "";
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
str::join(const vector<string> &vec_,
|
||||
const size_t substridx_,
|
||||
const char sep_)
|
||||
{
|
||||
if(vec_.empty())
|
||||
return string();
|
||||
}
|
||||
|
||||
string
|
||||
remove_common_prefix_and_join(const vector<string> &vec_,
|
||||
const char sep_)
|
||||
{
|
||||
size_t idx;
|
||||
string rv = vec_[0].substr(substridx_);
|
||||
for(size_t i = 1; i < vec_.size(); i++)
|
||||
rv += sep_ + vec_[i].substr(substridx_);
|
||||
|
||||
idx = str::longest_common_prefix_index(vec_);
|
||||
if(idx == string::npos)
|
||||
idx = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
return str::join(vec_,idx,sep_);
|
||||
}
|
||||
string
|
||||
str::join(const vector<string> &vec_,
|
||||
const char sep_)
|
||||
{
|
||||
return str::join(vec_,0,sep_);
|
||||
}
|
||||
|
||||
void
|
||||
erase_fnmatches(const vector<string> &patterns_,
|
||||
vector<string> &strs_)
|
||||
{
|
||||
vector<string>::iterator si;
|
||||
vector<string>::const_iterator pi;
|
||||
string
|
||||
str::join(const set<string> &set_,
|
||||
const char sep_)
|
||||
{
|
||||
string rv;
|
||||
|
||||
si = strs_.begin();
|
||||
while(si != strs_.end())
|
||||
{
|
||||
int match = FNM_NOMATCH;
|
||||
for(auto const &s : set_)
|
||||
rv += s + sep_;
|
||||
rv.pop_back();
|
||||
|
||||
for(pi = patterns_.begin();
|
||||
pi != patterns_.end() && match != 0;
|
||||
++pi)
|
||||
{
|
||||
match = fnmatch(pi->c_str(),si->c_str(),0);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
if(match == 0)
|
||||
si = strs_.erase(si);
|
||||
else
|
||||
++si;
|
||||
}
|
||||
}
|
||||
size_t
|
||||
str::longest_common_prefix_index(const vector<string> &vec_)
|
||||
{
|
||||
if(vec_.empty())
|
||||
return string::npos;
|
||||
|
||||
bool
|
||||
isprefix(const string &s0_,
|
||||
const string &s1_)
|
||||
{
|
||||
return ((s0_.size() >= s1_.size()) &&
|
||||
(s0_.compare(0,s1_.size(),s1_) == 0));
|
||||
}
|
||||
for(size_t n = 0; n < vec_[0].size(); n++)
|
||||
{
|
||||
char chr = vec_[0][n];
|
||||
for(size_t i = 1; i < vec_.size(); i++)
|
||||
{
|
||||
if(n >= vec_[i].size())
|
||||
return n;
|
||||
if(vec_[i][n] != chr)
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
startswith(const string &str_,
|
||||
const string &prefix_)
|
||||
{
|
||||
return ((str_.size() >= prefix_.size()) &&
|
||||
(str_.compare(0,prefix_.size(),prefix_) == 0));
|
||||
}
|
||||
return string::npos;
|
||||
}
|
||||
|
||||
bool
|
||||
endswith(const string &str_,
|
||||
const string &suffix_)
|
||||
{
|
||||
if(suffix_.size() > str_.size())
|
||||
return false;
|
||||
string
|
||||
str::longest_common_prefix(const vector<string> &vec_)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
return std::equal(suffix_.rbegin(),
|
||||
suffix_.rend(),
|
||||
str_.rbegin());
|
||||
}
|
||||
idx = longest_common_prefix_index(vec_);
|
||||
if(idx != string::npos)
|
||||
return vec_[0].substr(0,idx);
|
||||
|
||||
std::string
|
||||
trim(const std::string &str_)
|
||||
{
|
||||
std::string rv;
|
||||
return string();
|
||||
}
|
||||
|
||||
rv = str_;
|
||||
string
|
||||
str::remove_common_prefix_and_join(const vector<string> &vec_,
|
||||
const char sep_)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
while(!rv.empty() && (rv[0] == ' '))
|
||||
rv.erase(0);
|
||||
while(!rv.empty() && (rv[rv.size()-1] == ' '))
|
||||
rv.erase(rv.size()-1);
|
||||
idx = str::longest_common_prefix_index(vec_);
|
||||
if(idx == string::npos)
|
||||
idx = 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
return str::join(vec_,idx,sep_);
|
||||
}
|
||||
|
||||
void
|
||||
str::erase_fnmatches(const vector<string> &patterns_,
|
||||
vector<string> &strs_)
|
||||
{
|
||||
vector<string>::iterator si;
|
||||
vector<string>::const_iterator pi;
|
||||
|
||||
si = strs_.begin();
|
||||
while(si != strs_.end())
|
||||
{
|
||||
int match = FNM_NOMATCH;
|
||||
|
||||
for(pi = patterns_.begin();
|
||||
pi != patterns_.end() && match != 0;
|
||||
++pi)
|
||||
{
|
||||
match = fnmatch(pi->c_str(),si->c_str(),0);
|
||||
}
|
||||
|
||||
if(match == 0)
|
||||
si = strs_.erase(si);
|
||||
else
|
||||
++si;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
str::isprefix(const string &s0_,
|
||||
const string &s1_)
|
||||
{
|
||||
return ((s0_.size() >= s1_.size()) &&
|
||||
(s0_.compare(0,s1_.size(),s1_) == 0));
|
||||
}
|
||||
|
||||
bool
|
||||
str::startswith(const string &str_,
|
||||
const string &prefix_)
|
||||
{
|
||||
return ((str_.size() >= prefix_.size()) &&
|
||||
(str_.compare(0,prefix_.size(),prefix_) == 0));
|
||||
}
|
||||
|
||||
bool
|
||||
str::endswith(const string &str_,
|
||||
const string &suffix_)
|
||||
{
|
||||
if(suffix_.size() > str_.size())
|
||||
return false;
|
||||
|
||||
return std::equal(suffix_.rbegin(),
|
||||
suffix_.rend(),
|
||||
str_.rbegin());
|
||||
}
|
||||
|
||||
std::string
|
||||
str::trim(const std::string &str_)
|
||||
{
|
||||
std::string rv;
|
||||
|
||||
rv = str_;
|
||||
|
||||
while(!rv.empty() && (rv[0] == ' '))
|
||||
rv.erase(0);
|
||||
while(!rv.empty() && (rv[rv.size()-1] == ' '))
|
||||
rv.erase(rv.size()-1);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
+9
-24
@@ -23,44 +23,29 @@
|
||||
namespace str
|
||||
{
|
||||
void
|
||||
split(const char *str,
|
||||
const char delimiter,
|
||||
std::vector<std::string> *result);
|
||||
void
|
||||
split(const std::string &str,
|
||||
split(const std::string_view str,
|
||||
const char delimiter,
|
||||
std::vector<std::string> *result);
|
||||
|
||||
void
|
||||
split(const char *str,
|
||||
const char delimiter,
|
||||
std::set<std::string> *result);
|
||||
void
|
||||
split(const std::string &str,
|
||||
const char delimiter,
|
||||
std::set<std::string> *result);
|
||||
split(const std::string_view str,
|
||||
const char delimiter,
|
||||
std::set<std::string> *result);
|
||||
|
||||
void
|
||||
split_on_null(const char *str,
|
||||
const size_t len,
|
||||
split_on_null(const std::string_view str,
|
||||
std::vector<std::string> *result);
|
||||
|
||||
void
|
||||
rsplit1(const std::string &str,
|
||||
rsplit1(const std::string_view &str,
|
||||
const char delimiter,
|
||||
std::vector<std::string> *result);
|
||||
|
||||
void
|
||||
splitkv(const std::string &str,
|
||||
const char delimiter,
|
||||
std::string *key,
|
||||
std::string *value);
|
||||
|
||||
void
|
||||
splitkv(const std::string_view &str,
|
||||
splitkv(const std::string_view str,
|
||||
const char delimiter,
|
||||
std::string &key,
|
||||
std::string_view &val);
|
||||
std::string *key,
|
||||
std::string *value);
|
||||
|
||||
std::string
|
||||
join(const std::vector<std::string> &vec,
|
||||
|
||||
+35
-7
@@ -19,9 +19,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "fuse_kernel.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include "int_types.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -32,13 +30,13 @@ namespace symlinkify
|
||||
inline
|
||||
bool
|
||||
can_be_symlink(const struct stat &st_,
|
||||
const time_t timeout_)
|
||||
const s64 timeout_)
|
||||
{
|
||||
if(S_ISDIR(st_.st_mode) ||
|
||||
(st_.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)))
|
||||
return false;
|
||||
|
||||
const time_t now = ::time(NULL);
|
||||
const s64 now = ::time(NULL);
|
||||
|
||||
return (((now - st_.st_mtime) > timeout_) &&
|
||||
((now - st_.st_ctime) > timeout_));
|
||||
@@ -48,13 +46,13 @@ namespace symlinkify
|
||||
inline
|
||||
bool
|
||||
can_be_symlink(const struct fuse_statx &st_,
|
||||
const time_t timeout_)
|
||||
const s64 timeout_)
|
||||
{
|
||||
if(S_ISDIR(st_.mode) ||
|
||||
(st_.mode & (S_IWUSR|S_IWGRP|S_IWOTH)))
|
||||
return false;
|
||||
|
||||
const time_t now = ::time(NULL);
|
||||
const s64 now = ::time(NULL);
|
||||
|
||||
return (((now - st_.mtime.tv_sec) > timeout_) &&
|
||||
((now - st_.ctime.tv_sec) > timeout_));
|
||||
@@ -81,4 +79,34 @@ namespace symlinkify
|
||||
st_->size = target_.size();
|
||||
st_->blocks = 0;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
convert_if_can_be_symlink(const std::string &target_,
|
||||
struct stat *st_,
|
||||
const s64 timeout_)
|
||||
{
|
||||
if(timeout_ < 0)
|
||||
return;
|
||||
if(!symlinkify::can_be_symlink(*st_,timeout_))
|
||||
return;
|
||||
|
||||
symlinkify::convert(target_,st_);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
convert_if_can_be_symlink(const std::string &target_,
|
||||
fuse_statx *st_,
|
||||
const s64 timeout_)
|
||||
{
|
||||
if(timeout_ < 0)
|
||||
return;
|
||||
if(!symlinkify::can_be_symlink(*st_,timeout_))
|
||||
return;
|
||||
|
||||
symlinkify::convert(target_,st_);
|
||||
}
|
||||
}
|
||||
|
||||
+29
-28
@@ -23,38 +23,39 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace str
|
||||
std::string
|
||||
str::to(const bool bool_)
|
||||
{
|
||||
std::string
|
||||
to(const bool bool_)
|
||||
{
|
||||
return (bool_ ? "true" : "false");
|
||||
}
|
||||
return (bool_ ? "true" : "false");
|
||||
}
|
||||
|
||||
std::string
|
||||
to(const int int_)
|
||||
{
|
||||
return fmt::format("{}",int_);
|
||||
}
|
||||
std::string
|
||||
str::to(const int int_)
|
||||
{
|
||||
return fmt::format("{}",int_);
|
||||
}
|
||||
|
||||
std::string
|
||||
to(const uint64_t uint64_)
|
||||
{
|
||||
return fmt::format("{}",uint64_);
|
||||
}
|
||||
std::string
|
||||
str::to(const uint64_t uint64_)
|
||||
{
|
||||
return fmt::format("{}",uint64_);
|
||||
}
|
||||
|
||||
std::string
|
||||
to(const std::string &s_)
|
||||
{
|
||||
return s_;
|
||||
}
|
||||
std::string
|
||||
str::to(const int64_t int64_)
|
||||
{
|
||||
return fmt::format("{}",int64_);
|
||||
}
|
||||
|
||||
std::string
|
||||
to(const fs::Path &path_)
|
||||
{
|
||||
return path_.string();
|
||||
}
|
||||
std::string
|
||||
str::to(const std::string &s_)
|
||||
{
|
||||
return s_;
|
||||
}
|
||||
|
||||
std::string
|
||||
str::to(const std::filesystem::path &path_)
|
||||
{
|
||||
return path_.string();
|
||||
}
|
||||
|
||||
+3
-3
@@ -18,9 +18,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fs_path.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -29,6 +28,7 @@ namespace str
|
||||
std::string to(const bool);
|
||||
std::string to(const int);
|
||||
std::string to(const uint64_t);
|
||||
std::string to(const int64_t);
|
||||
std::string to(const std::string&);
|
||||
std::string to(const fs::Path&);
|
||||
std::string to(const std::filesystem::path&);
|
||||
}
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class ToFromString
|
||||
{
|
||||
public:
|
||||
virtual std::string to_string() const = 0;
|
||||
virtual int from_string(const std::string &) = 0;
|
||||
virtual int from_string(const std::string_view) = 0;
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ class ToFromWrapper : public ToFromString
|
||||
{
|
||||
public:
|
||||
int
|
||||
from_string(const std::string &s_) final
|
||||
from_string(const std::string_view s_) final
|
||||
{
|
||||
return str::from(s_,&_data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user