mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-04-26 06:54:06 +08:00
Merge pull request #220 from trapexit/eplfs
add existing path, least free space policy. closes #216
This commit is contained in:
commit
fc100006f9
28
src/link.cpp
28
src/link.cpp
@ -246,21 +246,21 @@ namespace mergerfs
|
|||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
const rwlock::ReadGuard readlock(&config.srcmountslock);
|
const rwlock::ReadGuard readlock(&config.srcmountslock);
|
||||||
|
|
||||||
if(config.create != Policy::epmfs)
|
if(config.create->path_preserving())
|
||||||
return _link_create_path(config.link,
|
return _link_preserve_path(config.getattr,
|
||||||
config.create,
|
config.link,
|
||||||
config.srcmounts,
|
config.create,
|
||||||
config.minfreespace,
|
config.srcmounts,
|
||||||
from,
|
config.minfreespace,
|
||||||
to);
|
from,
|
||||||
|
to);
|
||||||
|
|
||||||
return _link_preserve_path(config.getattr,
|
return _link_create_path(config.link,
|
||||||
config.link,
|
config.create,
|
||||||
config.create,
|
config.srcmounts,
|
||||||
config.srcmounts,
|
config.minfreespace,
|
||||||
config.minfreespace,
|
from,
|
||||||
from,
|
to);
|
||||||
to);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,27 +20,30 @@
|
|||||||
#include "fs.hpp"
|
#include "fs.hpp"
|
||||||
#include "buildvector.hpp"
|
#include "buildvector.hpp"
|
||||||
|
|
||||||
#define POLICY(X) (Policy(Policy::Enum::X,#X,Policy::Func::X))
|
#define POLICY(X,PP) (Policy(Policy::Enum::X,#X,Policy::Func::X,PP))
|
||||||
|
#define PRESERVES_PATH true
|
||||||
|
#define DOESNT_PRESERVE_PATH false
|
||||||
|
|
||||||
namespace mergerfs
|
namespace mergerfs
|
||||||
{
|
{
|
||||||
const std::vector<Policy> Policy::_policies_ =
|
const std::vector<Policy> Policy::_policies_ =
|
||||||
buildvector<Policy,true>
|
buildvector<Policy,true>
|
||||||
(POLICY(invalid))
|
(POLICY(invalid,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(all))
|
(POLICY(all,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(einval))
|
(POLICY(einval,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(enosys))
|
(POLICY(enosys,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(enotsup))
|
(POLICY(enotsup,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(epmfs))
|
(POLICY(eplfs,PRESERVES_PATH))
|
||||||
(POLICY(erofs))
|
(POLICY(epmfs,PRESERVES_PATH))
|
||||||
(POLICY(exdev))
|
(POLICY(erofs,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(ff))
|
(POLICY(exdev,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(ffwp))
|
(POLICY(ff,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(fwfs))
|
(POLICY(ffwp,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(lfs))
|
(POLICY(fwfs,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(mfs))
|
(POLICY(lfs,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(newest))
|
(POLICY(mfs,DOESNT_PRESERVE_PATH))
|
||||||
(POLICY(rand));
|
(POLICY(newest,DOESNT_PRESERVE_PATH))
|
||||||
|
(POLICY(rand,DOESNT_PRESERVE_PATH));
|
||||||
|
|
||||||
const Policy * const Policy::policies = &_policies_[1];
|
const Policy * const Policy::policies = &_policies_[1];
|
||||||
|
|
||||||
@ -51,6 +54,7 @@ namespace mergerfs
|
|||||||
CONST_POLICY(einval);
|
CONST_POLICY(einval);
|
||||||
CONST_POLICY(enosys);
|
CONST_POLICY(enosys);
|
||||||
CONST_POLICY(enotsup);
|
CONST_POLICY(enotsup);
|
||||||
|
CONST_POLICY(eplfs);
|
||||||
CONST_POLICY(epmfs);
|
CONST_POLICY(epmfs);
|
||||||
CONST_POLICY(erofs);
|
CONST_POLICY(erofs);
|
||||||
CONST_POLICY(exdev);
|
CONST_POLICY(exdev);
|
||||||
|
@ -39,6 +39,7 @@ namespace mergerfs
|
|||||||
einval,
|
einval,
|
||||||
enosys,
|
enosys,
|
||||||
enotsup,
|
enotsup,
|
||||||
|
eplfs,
|
||||||
epmfs,
|
epmfs,
|
||||||
erofs,
|
erofs,
|
||||||
exdev,
|
exdev,
|
||||||
@ -95,6 +96,7 @@ namespace mergerfs
|
|||||||
static int einval(CType,cstrvec&,const char*,csize_t,cstrptrvec&);
|
static int einval(CType,cstrvec&,const char*,csize_t,cstrptrvec&);
|
||||||
static int enosys(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
static int enosys(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||||
static int enotsup(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
static int enotsup(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||||
|
static int eplfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||||
static int epmfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
static int epmfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||||
static int erofs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
static int erofs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||||
static int exdev(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
static int exdev(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||||
@ -112,24 +114,34 @@ namespace mergerfs
|
|||||||
Enum::Type _enum;
|
Enum::Type _enum;
|
||||||
std::string _str;
|
std::string _str;
|
||||||
Func::Ptr _func;
|
Func::Ptr _func;
|
||||||
|
bool _path_preserving;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Policy()
|
Policy()
|
||||||
: _enum(invalid),
|
: _enum(invalid),
|
||||||
_str(invalid),
|
_str(invalid),
|
||||||
_func(invalid)
|
_func(invalid),
|
||||||
|
_path_preserving(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Policy(const Enum::Type enum_,
|
Policy(const Enum::Type enum_,
|
||||||
const std::string &str_,
|
const std::string &str_,
|
||||||
const Func::Ptr func_)
|
const Func::Ptr func_,
|
||||||
|
const bool path_preserving_)
|
||||||
: _enum(enum_),
|
: _enum(enum_),
|
||||||
_str(str_),
|
_str(str_),
|
||||||
_func(func_)
|
_func(func_),
|
||||||
|
_path_preserving(path_preserving_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
path_preserving() const
|
||||||
|
{
|
||||||
|
return _path_preserving;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
operator const Enum::Type() const { return _enum; }
|
operator const Enum::Type() const { return _enum; }
|
||||||
operator const std::string&() const { return _str; }
|
operator const std::string&() const { return _str; }
|
||||||
@ -162,6 +174,7 @@ namespace mergerfs
|
|||||||
static const Policy &einval;
|
static const Policy &einval;
|
||||||
static const Policy &enosys;
|
static const Policy &enosys;
|
||||||
static const Policy &enotsup;
|
static const Policy &enotsup;
|
||||||
|
static const Policy &eplfs;
|
||||||
static const Policy &epmfs;
|
static const Policy &epmfs;
|
||||||
static const Policy &erofs;
|
static const Policy &erofs;
|
||||||
static const Policy &exdev;
|
static const Policy &exdev;
|
||||||
|
108
src/policy_eplfs.cpp
Normal file
108
src/policy_eplfs.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
#include "policy.hpp"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
using std::size_t;
|
||||||
|
using mergerfs::Policy;
|
||||||
|
using mergerfs::Category;
|
||||||
|
typedef struct statvfs statvfs_t;
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
_calc_lfs(const statvfs_t &fsstats,
|
||||||
|
const string *basepath,
|
||||||
|
const size_t minfreespace,
|
||||||
|
fsblkcnt_t &lfs,
|
||||||
|
const string *&lfsbasepath)
|
||||||
|
{
|
||||||
|
fsblkcnt_t spaceavail;
|
||||||
|
|
||||||
|
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||||
|
if((spaceavail > minfreespace) && (spaceavail < lfs))
|
||||||
|
{
|
||||||
|
lfs = spaceavail;
|
||||||
|
lfsbasepath = basepath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
_eplfs(const Category::Enum::Type type,
|
||||||
|
const vector<string> &basepaths,
|
||||||
|
const char *fusepath,
|
||||||
|
const size_t minfreespace,
|
||||||
|
vector<const string*> &paths)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
string fullpath;
|
||||||
|
statvfs_t fsstats;
|
||||||
|
fsblkcnt_t eplfs;
|
||||||
|
const string *eplfsbasepath;
|
||||||
|
|
||||||
|
eplfs = -1;
|
||||||
|
eplfsbasepath = NULL;
|
||||||
|
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||||
|
{
|
||||||
|
const string *basepath = &basepaths[i];
|
||||||
|
|
||||||
|
fs::path::make(basepath,fusepath,fullpath);
|
||||||
|
|
||||||
|
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||||
|
if(rv == 0)
|
||||||
|
_calc_lfs(fsstats,basepath,minfreespace,eplfs,eplfsbasepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(eplfsbasepath == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
paths.push_back(eplfsbasepath);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mergerfs
|
||||||
|
{
|
||||||
|
int
|
||||||
|
Policy::Func::eplfs(const Category::Enum::Type type,
|
||||||
|
const vector<string> &basepaths,
|
||||||
|
const char *fusepath,
|
||||||
|
const size_t minfreespace,
|
||||||
|
vector<const string*> &paths)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
const size_t minfs =
|
||||||
|
((type == Category::Enum::create) ? minfreespace : 0);
|
||||||
|
|
||||||
|
rv = _eplfs(type,basepaths,fusepath,minfs,paths);
|
||||||
|
if(rv != 0)
|
||||||
|
rv = Policy::Func::lfs(type,basepaths,fusepath,minfreespace,paths);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
@ -275,21 +275,21 @@ namespace mergerfs
|
|||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
const rwlock::ReadGuard readlock(&config.srcmountslock);
|
const rwlock::ReadGuard readlock(&config.srcmountslock);
|
||||||
|
|
||||||
if(config.create != Policy::epmfs)
|
if(config.create->path_preserving())
|
||||||
return _rename_create_path(config.rename,
|
return _rename_preserve_path(config.getattr,
|
||||||
config.create,
|
config.rename,
|
||||||
config.srcmounts,
|
config.create,
|
||||||
config.minfreespace,
|
config.srcmounts,
|
||||||
oldpath,
|
config.minfreespace,
|
||||||
newpath);
|
oldpath,
|
||||||
|
newpath);
|
||||||
|
|
||||||
return _rename_preserve_path(config.getattr,
|
return _rename_create_path(config.rename,
|
||||||
config.rename,
|
config.create,
|
||||||
config.create,
|
config.srcmounts,
|
||||||
config.srcmounts,
|
config.minfreespace,
|
||||||
config.minfreespace,
|
oldpath,
|
||||||
oldpath,
|
newpath);
|
||||||
newpath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user