mergerfs/src/func_mknod_epall.cpp
Antonio S. Musumeci d8ba75cca3 checkpoint
2026-05-26 21:30:38 -04:00

95 lines
2 KiB
C++

#include "func_mknod_epall.hpp"
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_info_t.hpp"
#include "fs_mknod_as.hpp"
#include "fs_path.hpp"
static
inline
void
_calc_error(int &cur_,
const int err_)
{
switch(cur_)
{
default:
case ENOENT:
cur_ = err_;
break;
case ENOSPC:
if(err_ != ENOENT)
cur_ = err_;
break;
case EROFS:
if((err_ != ENOENT) && (err_ != ENOSPC))
cur_ = err_;
break;
}
}
#define error_and_continue(CUR,ERR) \
do { \
::_calc_error(CUR,ERR); \
continue; \
} while(0)
std::string_view
Func2::MknodEPALL::name() const
{
return "epall";
}
int
Func2::MknodEPALL::operator()(const ugid_t &ugid_,
const Branches &branches_,
const fs::path &fusepath_,
const mode_t mode_,
const dev_t dev_,
const mode_t umask_)
{
int rv;
int error;
bool any;
fs::info_t info;
Branches::Ptr branches;
fs::path fullpath;
branches = branches_;
error = ENOENT;
any = false;
for(auto &branch : *branches)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_.parent_path()))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv < 0)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
fullpath = branch.path / fusepath_;
rv = fs::mknod_as(ugid_,fullpath,mode_,dev_,umask_);
if(rv < 0)
{
::_calc_error(error,-rv);
continue;
}
any = true;
}
if(!any)
return -error;
return 0;
}