mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-01-20 05:52:47 +08:00
add minfreespace check to epmfs create policy
This commit is contained in:
parent
4141181243
commit
bc77b0fd2a
14
README.md
14
README.md
|
@ -21,7 +21,7 @@ Why create **mergerfs** when those exist? **mhddfs** has not been updated in som
|
|||
###options###
|
||||
|
||||
* **defaults** is a shortcut for **auto_cache**. **big_writes**, **atomic_o_trunc**, **splice_read**, **splice_write**, and **splice_move** are in effect also enabled (by asking **FUSE** internally for such features) but if unavailable will be ignored. These options seem to provide the best performance.
|
||||
* **minfreespace** (defaults to **4G**) is the minimum space value used for the **lfs** and **fwfs** policies. Understands 'K', 'M', and 'G' to represent kilobyte, megabyte, and gigabyte respectively.
|
||||
* **minfreespace** (defaults to **4G**) is the minimum space value used for the **lfs**, **fwfs**, and **epmfs** policies. Understands 'K', 'M', and 'G' to represent kilobyte, megabyte, and gigabyte respectively.
|
||||
* All FUSE functions which have a category (see below) are option keys. The syntax being **func.<func>=<policy>**. Example: **func.getattr=newest**.
|
||||
* To set all function policies in a category use **categor.<category>=<policy>**. Example: **category.create=mfs**.
|
||||
* Options are evaluated in the order listed so if the options are **func.rmdir=rand,category.action=ff** the **action** category setting will override the **rmdir** setting.
|
||||
|
@ -64,14 +64,14 @@ Filesystem calls are broken up into 3 categories: **action**, **create**, **sear
|
|||
|
||||
| Policy | Description |
|
||||
|--------------|-------------|
|
||||
| ff (first found) | Given the order of the paths act on the first one found (regardless if stat would return EACCES). |
|
||||
| ffwp (first found w/ permissions) | Given the order of the paths act on the first one found which you have access (stat does not error with EACCES). |
|
||||
| ff (first found) | Given the order of the drives act on the first one found (regardless if stat would return EACCES). |
|
||||
| ffwp (first found w/ permissions) | Given the order of the drives act on the first one found which you have access (stat does not error with EACCES). |
|
||||
| newest (newest file) | If multiple files exist return the one with the most recent mtime. |
|
||||
| mfs (most free space) | Use the drive with the most free space available. |
|
||||
| epmfs (existing path, most free space) | If the path exists in multiple locations use the one with the most free space. Otherwise fall back to **mfs**. |
|
||||
| fwfs (first with free space) | Pick the first path which has at least **minfreespace**. |
|
||||
| lfs (least free space) | Pick the path with least available space but more than **minfreespace**. |
|
||||
| rand (random) | Pick an existing destination at random. |
|
||||
| epmfs (existing path, most free space) | If the path exists on multiple drives use the one with the most free space and is greater than **minfreespace**. If no drive has at least **minfreespace** then fallback to **mfs**. |
|
||||
| fwfs (first with free space) | Pick the first drive which has at least **minfreespace**. |
|
||||
| lfs (least free space) | Pick the drive with least available space but more than **minfreespace**. |
|
||||
| rand (random) | Pick an existing drive at random. |
|
||||
| all | Applies action to all found. For searches it will behave like first found **ff**. |
|
||||
| enosys, einval, enotsup, exdev, erofs | Exclusively return `-1` with `errno` set to the respective value. Useful for debugging other applications' behavior to errors. |
|
||||
|
||||
|
|
|
@ -36,117 +36,57 @@
|
|||
using std::string;
|
||||
using std::vector;
|
||||
using std::size_t;
|
||||
using mergerfs::Policy;
|
||||
using mergerfs::Category;
|
||||
typedef struct statvfs statvfs_t;
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
_calc_epmfs(const struct statvfs &fsstats,
|
||||
const string &basepath,
|
||||
fsblkcnt_t &epmfs,
|
||||
string &epmfsbasepath,
|
||||
fsblkcnt_t &mfs,
|
||||
string &mfsbasepath)
|
||||
_calc_mfs(const statvfs_t &fsstats,
|
||||
const string &basepath,
|
||||
const size_t minfreespace,
|
||||
fsblkcnt_t &mfs,
|
||||
string &mfsbasepath)
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
if(spaceavail > epmfs)
|
||||
{
|
||||
epmfs = spaceavail;
|
||||
epmfsbasepath = basepath;
|
||||
}
|
||||
|
||||
if(spaceavail > mfs)
|
||||
if((spaceavail > minfreespace) && (spaceavail > mfs))
|
||||
{
|
||||
mfs = spaceavail;
|
||||
mfsbasepath = basepath;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
_calc_mfs(const struct statvfs &fsstats,
|
||||
const string &basepath,
|
||||
fsblkcnt_t &mfs,
|
||||
string &mfsbasepath)
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
if(spaceavail > mfs)
|
||||
{
|
||||
mfs = spaceavail;
|
||||
mfsbasepath = basepath;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
int
|
||||
_try_statvfs(const string &basepath,
|
||||
const string &fullpath,
|
||||
fsblkcnt_t &epmfs,
|
||||
string &epmfsbasepath,
|
||||
fsblkcnt_t &mfs,
|
||||
string &mfsbasepath)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(rv == 0)
|
||||
_calc_epmfs(fsstats,basepath,epmfs,epmfsbasepath,mfs,mfsbasepath);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
int
|
||||
_try_statvfs(const string &basepath,
|
||||
fsblkcnt_t &mfs,
|
||||
string &mfsbasepath)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
|
||||
rv = ::statvfs(basepath.c_str(),&fsstats);
|
||||
if(rv == 0)
|
||||
_calc_mfs(fsstats,basepath,mfs,mfsbasepath);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_epmfs_create(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
|
||||
{
|
||||
int rv;
|
||||
fsblkcnt_t epmfs;
|
||||
fsblkcnt_t mfs;
|
||||
string mfsbasepath;
|
||||
string epmfsbasepath;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
|
||||
mfs = 0;
|
||||
epmfs = 0;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
const string &basepath = basepaths[i];
|
||||
|
||||
fullpath = fs::path::make(basepath,fusepath);
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = _try_statvfs(basepath,fullpath,epmfs,epmfsbasepath,mfs,mfsbasepath);
|
||||
if(rv == -1)
|
||||
_try_statvfs(basepath,mfs,mfsbasepath);
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(rv == 0)
|
||||
_calc_mfs(fsstats,basepath,minfreespace,epmfs,epmfsbasepath);
|
||||
}
|
||||
|
||||
if(epmfsbasepath.empty())
|
||||
epmfsbasepath = mfsbasepath;
|
||||
return Policy::Func::mfs(Category::Enum::create,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
paths.push_back(epmfsbasepath);
|
||||
|
||||
|
@ -160,22 +100,22 @@ _epmfs(const vector<string> &basepaths,
|
|||
vector<string> &paths)
|
||||
|
||||
{
|
||||
int rv;
|
||||
fsblkcnt_t epmfs;
|
||||
string epmfsbasepath;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
|
||||
epmfs = 0;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
const string &basepath = basepaths[i];
|
||||
|
||||
fullpath = fs::path::make(basepath,fusepath);
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(rv == 0)
|
||||
_calc_mfs(fsstats,basepath,epmfs,epmfsbasepath);
|
||||
_calc_mfs(fsstats,basepath,0,epmfs,epmfsbasepath);
|
||||
}
|
||||
|
||||
if(epmfsbasepath.empty())
|
||||
|
@ -196,7 +136,7 @@ namespace mergerfs
|
|||
vector<string> &paths)
|
||||
{
|
||||
if(type == Category::Enum::create)
|
||||
return _epmfs_create(basepaths,fusepath,paths);
|
||||
return _epmfs_create(basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
return _epmfs(basepaths,fusepath,paths);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user