mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-01-20 03:52:46 +08:00
ignore drives mounted as readonly from create policies. closes #224
This commit is contained in:
parent
8edb7c1e1c
commit
5813d1e477
83
src/fs.cpp
83
src/fs.cpp
|
@ -31,28 +31,76 @@
|
|||
#include "fs_attr.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_xattr.hpp"
|
||||
#include "statvfs_util.hpp"
|
||||
#include "str.hpp"
|
||||
#include "success_fail.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
namespace fs
|
||||
{
|
||||
bool
|
||||
exists(const string &path,
|
||||
struct stat &st)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = ::lstat(path.c_str(),&st);
|
||||
|
||||
return LSTAT_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
bool
|
||||
exists(const string &path,
|
||||
struct statvfs &st)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = ::statvfs(path.c_str(),&st);
|
||||
|
||||
return STATVFS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
bool
|
||||
exists(const string &path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
return exists(path,st);
|
||||
}
|
||||
|
||||
bool
|
||||
exists_on_rw_fs(const string &path,
|
||||
struct statvfs &st)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = ::statvfs(path.c_str(),&st);
|
||||
|
||||
return (STATVFS_SUCCEEDED(rv) && !StatVFS::readonly(st));
|
||||
}
|
||||
|
||||
bool
|
||||
exists_on_rw_fs(const string &path)
|
||||
{
|
||||
struct statvfs st;
|
||||
|
||||
return exists_on_rw_fs(path,st);
|
||||
}
|
||||
|
||||
void
|
||||
findallfiles(const vector<string> &srcmounts,
|
||||
const char *fusepath,
|
||||
vector<string> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct stat st;
|
||||
|
||||
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::make(&srcmounts[i],fusepath,fullpath);
|
||||
|
||||
rv = ::lstat(fullpath.c_str(),&st);
|
||||
if(rv == 0)
|
||||
if(fs::exists(fullpath))
|
||||
paths.push_back(fullpath);
|
||||
}
|
||||
}
|
||||
|
@ -145,16 +193,14 @@ namespace fs
|
|||
mfsidx = -1;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
struct statvfs st;
|
||||
const string &basepath = basepaths[i];
|
||||
|
||||
rv = ::statvfs(basepath.c_str(),&fsstats);
|
||||
if(rv == 0)
|
||||
if(fs::exists(basepath,st))
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
spaceavail = StatVFS::spaceavail(st);
|
||||
if((spaceavail > mfs) && (spaceavail >= minfreespace))
|
||||
{
|
||||
mfs = spaceavail;
|
||||
|
@ -170,4 +216,23 @@ namespace fs
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
available(const string &path,
|
||||
const bool needswritablefs,
|
||||
struct statvfs &st)
|
||||
{
|
||||
return (needswritablefs ?
|
||||
fs::exists_on_rw_fs(path,st) :
|
||||
fs::exists(path,st));
|
||||
}
|
||||
|
||||
bool
|
||||
available(const string &path,
|
||||
const bool needswritablefs)
|
||||
{
|
||||
return (needswritablefs ?
|
||||
fs::exists_on_rw_fs(path) :
|
||||
fs::exists(path));
|
||||
}
|
||||
};
|
||||
|
|
17
src/fs.hpp
17
src/fs.hpp
|
@ -26,6 +26,16 @@ namespace fs
|
|||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
bool exists(const string &path,
|
||||
struct stat &st);
|
||||
bool exists(const string &path,
|
||||
struct statvfs &st);
|
||||
bool exists(const string &path);
|
||||
|
||||
bool exists_on_rw_fs(const string &path,
|
||||
struct statvfs &st);
|
||||
bool exists_on_rw_fs(const string &path);
|
||||
|
||||
void findallfiles(const vector<string> &srcmounts,
|
||||
const char *fusepath,
|
||||
vector<string> &paths);
|
||||
|
@ -45,6 +55,13 @@ namespace fs
|
|||
int mfs(const vector<string> &srcs,
|
||||
const size_t minfreespace,
|
||||
string &path);
|
||||
|
||||
bool available(const string &path,
|
||||
const bool needswritablefs);
|
||||
|
||||
bool available(const string &path,
|
||||
const bool needswritablefs,
|
||||
struct statvfs &st);
|
||||
};
|
||||
|
||||
#endif // __FS_HPP__
|
||||
|
|
|
@ -14,17 +14,14 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -34,10 +31,9 @@ static
|
|||
int
|
||||
_all(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
string fullpath;
|
||||
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
|
@ -46,9 +42,10 @@ _all(const vector<string> &basepaths,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::lstat(fullpath.c_str(),&st);
|
||||
if(LSTAT_SUCCEEDED(rv))
|
||||
paths.push_back(basepath);
|
||||
if(!fs::available(fullpath,needswritablefs))
|
||||
continue;
|
||||
|
||||
paths.push_back(basepath);
|
||||
}
|
||||
|
||||
if(paths.empty())
|
||||
|
@ -68,7 +65,9 @@ namespace mergerfs
|
|||
{
|
||||
const char *fp =
|
||||
((type == Category::Enum::create) ? "" : fusepath);
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
|
||||
return _all(basepaths,fp,paths);
|
||||
return _all(basepaths,fp,needswritablefs,paths);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,36 +15,33 @@
|
|||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "statvfs_util.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)
|
||||
_calc_lfs(const struct statvfs &st,
|
||||
const string *basepath,
|
||||
const size_t minfreespace,
|
||||
fsblkcnt_t &lfs,
|
||||
const string *&lfsbasepath)
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
spaceavail = StatVFS::spaceavail(st);
|
||||
if((spaceavail > minfreespace) && (spaceavail < lfs))
|
||||
{
|
||||
lfs = spaceavail;
|
||||
|
@ -54,15 +51,14 @@ _calc_lfs(const statvfs_t &fsstats,
|
|||
|
||||
static
|
||||
int
|
||||
_eplfs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<const string*> &paths)
|
||||
_eplfs(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
struct statvfs st;
|
||||
fsblkcnt_t eplfs;
|
||||
const string *eplfsbasepath;
|
||||
|
||||
|
@ -74,9 +70,10 @@ _eplfs(const Category::Enum::Type type,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(STATVFS_SUCCEEDED(rv))
|
||||
_calc_lfs(fsstats,basepath,minfreespace,eplfs,eplfsbasepath);
|
||||
if(!fs::available(fullpath,needswritablefs,st))
|
||||
continue;
|
||||
|
||||
_calc_lfs(st,basepath,minfreespace,eplfs,eplfsbasepath);
|
||||
}
|
||||
|
||||
if(eplfsbasepath == NULL)
|
||||
|
@ -94,13 +91,15 @@ namespace mergerfs
|
|||
const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<const string*> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
const size_t minfs =
|
||||
((type == Category::Enum::create) ? minfreespace : 0);
|
||||
|
||||
rv = _eplfs(type,basepaths,fusepath,minfs,paths);
|
||||
rv = _eplfs(basepaths,fusepath,minfs,needswritablefs,paths);
|
||||
if(POLICY_FAILED(rv))
|
||||
rv = Policy::Func::lfs(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
|
|
|
@ -15,36 +15,33 @@
|
|||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "statvfs_util.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_mfs(const statvfs_t &fsstats,
|
||||
const string *basepath,
|
||||
const size_t minfreespace,
|
||||
fsblkcnt_t &mfs,
|
||||
const string *&mfsbasepath)
|
||||
_calc_mfs(const struct statvfs &st,
|
||||
const string *basepath,
|
||||
const size_t minfreespace,
|
||||
fsblkcnt_t &mfs,
|
||||
const string *&mfsbasepath)
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
spaceavail = StatVFS::spaceavail(st);
|
||||
if((spaceavail > minfreespace) && (spaceavail > mfs))
|
||||
{
|
||||
mfs = spaceavail;
|
||||
|
@ -57,11 +54,11 @@ int
|
|||
_epmfs(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
struct statvfs st;
|
||||
fsblkcnt_t epmfs;
|
||||
const string *epmfsbasepath;
|
||||
|
||||
|
@ -73,9 +70,10 @@ _epmfs(const vector<string> &basepaths,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(STATVFS_SUCCEEDED(rv))
|
||||
_calc_mfs(fsstats,basepath,minfreespace,epmfs,epmfsbasepath);
|
||||
if(!fs::available(fullpath,needswritablefs,st))
|
||||
continue;
|
||||
|
||||
_calc_mfs(st,basepath,minfreespace,epmfs,epmfsbasepath);
|
||||
}
|
||||
|
||||
if(epmfsbasepath == NULL)
|
||||
|
@ -98,8 +96,10 @@ namespace mergerfs
|
|||
int rv;
|
||||
const size_t minfs =
|
||||
((type == Category::Enum::create) ? minfreespace : 0);
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
|
||||
rv = _epmfs(basepaths,fusepath,minfs,paths);
|
||||
rv = _epmfs(basepaths,fusepath,minfs,needswritablefs,paths);
|
||||
if(POLICY_FAILED(rv))
|
||||
rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
|
|
|
@ -14,17 +14,16 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "statvfs_util.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -34,11 +33,12 @@ static
|
|||
int
|
||||
_ff(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct stat st;
|
||||
struct statvfs st;
|
||||
const string *fallback = NULL;
|
||||
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
|
@ -46,15 +46,27 @@ _ff(const vector<string> &basepaths,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::lstat(fullpath.c_str(),&st);
|
||||
if(LSTAT_FAILED(rv))
|
||||
if(!fs::exists(fullpath,st))
|
||||
continue;
|
||||
|
||||
if(needswritablefs && StatVFS::readonly(st))
|
||||
{
|
||||
if(fallback == NULL)
|
||||
fallback = basepath;
|
||||
continue;
|
||||
}
|
||||
|
||||
paths.push_back(basepath);
|
||||
|
||||
return POLICY_SUCCESS;
|
||||
}
|
||||
|
||||
if(fallback != NULL)
|
||||
{
|
||||
paths.push_back(fallback);
|
||||
return POLICY_SUCCESS;
|
||||
}
|
||||
|
||||
return (errno=ENOENT,POLICY_FAIL);
|
||||
}
|
||||
|
||||
|
@ -69,7 +81,9 @@ namespace mergerfs
|
|||
{
|
||||
const char *fp =
|
||||
((type == Category::Enum::create) ? "" : fusepath);
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
|
||||
return _ff(basepaths,fp,paths);
|
||||
return _ff(basepaths,fp,needswritablefs,paths);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,8 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
|
@ -14,15 +14,16 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "statvfs_util.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -35,11 +36,11 @@ int
|
|||
_fwfs(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
struct statvfs st;
|
||||
|
||||
for(size_t i = 0, size = basepaths.size(); i != size; i++)
|
||||
{
|
||||
|
@ -47,19 +48,15 @@ _fwfs(const vector<string> &basepaths,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(STATVFS_SUCCEEDED(rv))
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
if(!fs::available(fullpath,needswritablefs,st))
|
||||
continue;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
if(spaceavail < minfreespace)
|
||||
continue;
|
||||
if(StatVFS::spaceavail(st) < minfreespace)
|
||||
continue;
|
||||
|
||||
paths.push_back(basepath);
|
||||
paths.push_back(basepath);
|
||||
|
||||
return POLICY_SUCCESS;
|
||||
}
|
||||
return POLICY_SUCCESS;
|
||||
}
|
||||
|
||||
return (errno=ENOENT,POLICY_FAIL);
|
||||
|
@ -77,8 +74,10 @@ namespace mergerfs
|
|||
int rv;
|
||||
const char *fp =
|
||||
((type == Category::Enum::create) ? "" : fusepath);
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
|
||||
rv = _fwfs(basepaths,fp,minfreespace,paths);
|
||||
rv = _fwfs(basepaths,fp,minfreespace,needswritablefs,paths);
|
||||
if(POLICY_FAILED(rv))
|
||||
rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
|
|
|
@ -14,18 +14,16 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "statvfs_util.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -35,7 +33,7 @@ using mergerfs::Category;
|
|||
|
||||
static
|
||||
void
|
||||
_calc_lfs(const struct statvfs &fsstats,
|
||||
_calc_lfs(const struct statvfs &st,
|
||||
const string *basepath,
|
||||
const size_t minfreespace,
|
||||
fsblkcnt_t &lfs,
|
||||
|
@ -43,7 +41,7 @@ _calc_lfs(const struct statvfs &fsstats,
|
|||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
spaceavail = StatVFS::spaceavail(st);
|
||||
if((spaceavail > minfreespace) && (spaceavail < lfs))
|
||||
{
|
||||
lfs = spaceavail;
|
||||
|
@ -56,11 +54,11 @@ int
|
|||
_lfs(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
struct statvfs st;
|
||||
fsblkcnt_t lfs;
|
||||
const string *lfsbasepath;
|
||||
|
||||
|
@ -72,9 +70,10 @@ _lfs(const vector<string> &basepaths,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(STATVFS_SUCCEEDED(rv))
|
||||
_calc_lfs(fsstats,basepath,minfreespace,lfs,lfsbasepath);
|
||||
if(!fs::available(fullpath,needswritablefs,st))
|
||||
continue;
|
||||
|
||||
_calc_lfs(st,basepath,minfreespace,lfs,lfsbasepath);
|
||||
}
|
||||
|
||||
if(lfsbasepath == NULL)
|
||||
|
@ -97,8 +96,10 @@ namespace mergerfs
|
|||
int rv;
|
||||
const char *fp =
|
||||
((type == Category::Enum::create) ? "" : fusepath);
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
|
||||
rv = _lfs(basepaths,fp,minfreespace,paths);
|
||||
rv = _lfs(basepaths,fp,minfreespace,needswritablefs,paths);
|
||||
if(POLICY_FAILED(rv))
|
||||
rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
|
|
|
@ -14,15 +14,16 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "statvfs_util.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -30,14 +31,14 @@ using std::size_t;
|
|||
|
||||
static
|
||||
void
|
||||
_calc_mfs(const struct statvfs &fsstats,
|
||||
_calc_mfs(const struct statvfs &st,
|
||||
const string *basepath,
|
||||
fsblkcnt_t &mfs,
|
||||
const string *&mfsbasepath)
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
spaceavail = StatVFS::spaceavail(st);
|
||||
if(spaceavail > mfs)
|
||||
{
|
||||
mfs = spaceavail;
|
||||
|
@ -49,11 +50,11 @@ static
|
|||
int
|
||||
_mfs(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
struct statvfs st;
|
||||
fsblkcnt_t mfs;
|
||||
const string *mfsbasepath;
|
||||
|
||||
|
@ -65,9 +66,10 @@ _mfs(const vector<string> &basepaths,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::statvfs(fullpath.c_str(),&fsstats);
|
||||
if(STATVFS_SUCCEEDED(rv))
|
||||
_calc_mfs(fsstats,basepath,mfs,mfsbasepath);
|
||||
if(!fs::available(fullpath,needswritablefs,st))
|
||||
continue;
|
||||
|
||||
_calc_mfs(st,basepath,mfs,mfsbasepath);
|
||||
}
|
||||
|
||||
if(mfsbasepath == NULL)
|
||||
|
@ -87,9 +89,16 @@ namespace mergerfs
|
|||
const size_t minfreespace,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
const char *fp =
|
||||
((type == Category::Enum::create) ? "" : fusepath);
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
|
||||
return _mfs(basepaths,fp,paths);
|
||||
rv = _mfs(basepaths,fp,needswritablefs,paths);
|
||||
if(POLICY_FAILED(rv))
|
||||
rv = Policy::Func::ff(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,9 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -26,6 +25,7 @@
|
|||
#include "fs_path.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "statvfs_util.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -35,12 +35,12 @@ static
|
|||
int
|
||||
_newest(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const bool needswritablefs,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
string fullpath;
|
||||
time_t newest;
|
||||
string fullpath;
|
||||
struct stat st;
|
||||
const string *newestbasepath;
|
||||
|
||||
newest = std::numeric_limits<time_t>::min();
|
||||
|
@ -51,12 +51,15 @@ _newest(const vector<string> &basepaths,
|
|||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::lstat(fullpath.c_str(),&st);
|
||||
if(LSTAT_SUCCEEDED(rv) && (st.st_mtime >= newest))
|
||||
{
|
||||
newest = st.st_mtime;
|
||||
newestbasepath = basepath;
|
||||
}
|
||||
if(!fs::exists(fullpath,st))
|
||||
continue;
|
||||
if(st.st_mtime < newest)
|
||||
continue;
|
||||
if(needswritablefs && !fs::exists_on_rw_fs(fullpath))
|
||||
continue;
|
||||
|
||||
newest = st.st_mtime;
|
||||
newestbasepath = basepath;
|
||||
}
|
||||
|
||||
if(newestbasepath == NULL)
|
||||
|
@ -76,6 +79,9 @@ namespace mergerfs
|
|||
const size_t minfreespace,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return _newest(basepaths,fusepath,paths);
|
||||
const bool needswritablefs =
|
||||
(type == Category::Enum::create);
|
||||
|
||||
return _newest(basepaths,fusepath,needswritablefs,paths);
|
||||
}
|
||||
}
|
||||
|
|
55
src/statvfs_util.hpp
Normal file
55
src/statvfs_util.hpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 <sys/statvfs.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "success_fail.hpp"
|
||||
|
||||
namespace StatVFS
|
||||
{
|
||||
static
|
||||
inline
|
||||
bool
|
||||
readonly(const struct statvfs &st)
|
||||
{
|
||||
return (st.f_flag & ST_RDONLY);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
bool
|
||||
readonly(const std::string &path)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs st;
|
||||
|
||||
rv = ::statvfs(path.c_str(),&st);
|
||||
if(STATVFS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
return readonly(st);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
fsblkcnt_t
|
||||
spaceavail(const struct statvfs &st)
|
||||
{
|
||||
return (st.f_frsize * st.f_bavail);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user