Browse Source

checkpoint

bespoke-policies
Antonio SJ Musumeci 2 weeks ago
parent
commit
8ab6bcf554
  1. 2
      src/config.cpp
  2. 2
      src/config.hpp
  3. 19
      src/func_mknod.hpp
  4. 28
      src/func_mknod_base.hpp
  5. 26
      src/func_mknod_factory.cpp
  6. 17
      src/func_mknod_factory.hpp
  7. 94
      src/func_mknod_ff.cpp
  8. 24
      src/func_mknod_ff.hpp
  9. 99
      src/func_mknod_mfs.cpp
  10. 24
      src/func_mknod_mfs.hpp
  11. 31
      src/fuse_mknod.cpp

2
src/config.cpp

@ -235,7 +235,7 @@ Config::Config()
_map["func.link"] = &func.link;
_map["func.listxattr"] = &listxattr;
_map["func.mkdir"] = &func.mkdir;
_map["func.mknod"] = &func.mknod;
_map["func.mknod"] = &mknod;
_map["func.open"] = &func.open;
_map["func.readdir"] = &readdir;
_map["func.readlink"] = &readlink;

2
src/config.hpp

@ -22,6 +22,7 @@
#include "func_getattr.hpp"
#include "func_getxattr.hpp"
#include "func_listxattr.hpp"
#include "func_mknod.hpp"
#include "func_readlink.hpp"
#include "func_removexattr.hpp"
#include "func_rmdir.hpp"
@ -130,6 +131,7 @@ public:
Func2::GetAttr getattr{"cdfo"};
Func2::Getxattr getxattr{"ff"};
Func2::Listxattr listxattr{"ff"};
Func2::Mknod mknod{"ff"};
Func2::Readlink readlink{"ff"};
Func2::Removexattr removexattr{"all"};
Func2::Rmdir rmdir{"all"};

19
src/func_mknod.hpp

@ -0,0 +1,19 @@
#pragma once
#include "func_mknod_base.hpp"
#include "func_mknod_factory.hpp"
#include "func_wrapper.hpp"
namespace Func2
{
using Mknod = FuncWrapper<Func2::MknodBase,
Func2::MknodFactory,
int,
const ugid_t&,
const Branches&,
const fs::path&,
const mode_t&,
const mode_t&,
const dev_t&>;
}

28
src/func_mknod_base.hpp

@ -0,0 +1,28 @@
#pragma once
#include "branches.hpp"
#include "fs_path.hpp"
#include "ugid.hpp"
#include <string_view>
namespace Func2
{
class MknodBase
{
public:
MknodBase() {}
~MknodBase() {}
public:
virtual std::string_view name() const = 0;
public:
virtual int operator()(const ugid_t &ugid,
const Branches &branches,
const fs::path &fusepath,
const mode_t mode,
const mode_t umask,
const dev_t dev) = 0;
};
}

26
src/func_mknod_factory.cpp

@ -0,0 +1,26 @@
#include "func_mknod_factory.hpp"
#include "func_mknod_ff.hpp"
#include "func_mknod_mfs.hpp"
bool
Func2::MknodFactory::valid(const std::string str_)
{
if(str_ == "ff")
return true;
if(str_ == "mfs")
return true;
return false;
}
std::shared_ptr<Func2::MknodBase>
Func2::MknodFactory::make(const std::string_view str_)
{
if(str_ == "ff")
return std::make_shared<Func2::MknodFF>();
if(str_ == "mfs")
return std::make_shared<Func2::MknodMFS>();
return {};
}

17
src/func_mknod_factory.hpp

@ -0,0 +1,17 @@
#pragma once
#include <memory>
#include <string_view>
namespace Func2
{
class MknodBase;
class MknodFactory
{
public:
static bool valid(const std::string str_);
static std::shared_ptr<MknodBase> make(const std::string_view str_);
};
}

94
src/func_mknod_ff.cpp

@ -0,0 +1,94 @@
#include "func_mknod_ff.hpp"
#include "errno.hpp"
#include "error.hpp"
#include "fs_acl.hpp"
#include "fs_clonepath.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_mknod_as.hpp"
#include "fs_path.hpp"
#include "ugid.hpp"
std::string_view
Func2::MknodFF::name() const
{
return "ff";
}
int
Func2::MknodFF::operator()(const ugid_t &ugid_,
const Branches &branches_,
const fs::path &fusepath_,
const mode_t mode_,
const mode_t umask_,
const dev_t dev_)
{
int rv;
fs::path fusedirpath;
mode_t umask;
fusedirpath = fusepath_.parent_path();
umask = 0; // TODO: get actual umask
// Find first branch with the directory
const Branch *existing_branch = nullptr;
for(const auto &branch : branches_)
{
if(fs::exists(branch.path / fusedirpath))
{
existing_branch = &branch;
break;
}
}
if(!existing_branch)
return -ENOENT;
// Find first branch for creation
const Branch *create_branch = nullptr;
for(const auto &branch : branches_)
{
if(branch.ro_or_nc())
continue;
fs::info_t info;
rv = fs::info(branch.path, &info);
if(rv < 0)
continue;
if(info.readonly)
continue;
if(info.spaceavail < branch.minfreespace())
continue;
create_branch = &branch;
break;
}
if(!create_branch)
return -ENOSPC;
// Clone path if needed
if(existing_branch != create_branch)
{
rv = fs::clonepath(existing_branch->path,
create_branch->path,
fusedirpath);
if(rv < 0)
return rv;
}
// Create the node
fs::path fullpath = create_branch->path / fusepath_;
if(!fs::acl::dir_has_defaults(fullpath))
{
mode_t mode = mode_ & ~umask_;
return fs::mknod_as(ugid_, fullpath, mode, dev_);
}
else
{
return fs::mknod_as(ugid_, fullpath, mode_, dev_);
}
}

24
src/func_mknod_ff.hpp

@ -0,0 +1,24 @@
#include "func_mknod_base.hpp"
#include <string_view>
namespace Func2
{
class MknodFF : public MknodBase
{
public:
MknodFF() {}
~MknodFF() {}
public:
std::string_view name() const;
public:
int operator()(const ugid_t &ugid,
const Branches &branches,
const fs::path &fusepath,
const mode_t mode,
const mode_t umask,
const dev_t dev);
};
}

99
src/func_mknod_mfs.cpp

@ -0,0 +1,99 @@
#include "func_mknod_mfs.hpp"
#include "errno.hpp"
#include "error.hpp"
#include "fs_acl.hpp"
#include "fs_clonepath.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_mknod_as.hpp"
#include "fs_path.hpp"
#include "ugid.hpp"
std::string_view
Func2::MknodMFS::name() const
{
return "mfs";
}
int
Func2::MknodMFS::operator()(const ugid_t &ugid_,
const Branches &branches_,
const fs::path &fusepath_,
const mode_t mode_,
const mode_t umask_,
const dev_t dev_)
{
int rv;
fs::path fusedirpath;
mode_t umask;
fusedirpath = fusepath_.parent_path();
umask = 0; // TODO: get actual umask
// Find first branch with the directory
const Branch *existing_branch = nullptr;
for(const auto &branch : branches_)
{
if(fs::exists(branch.path / fusedirpath))
{
existing_branch = &branch;
break;
}
}
if(!existing_branch)
return -ENOENT;
// Find branch with most free space for creation
const Branch *create_branch = nullptr;
uint64_t max_space = 0;
for(const auto &branch : branches_)
{
if(branch.ro_or_nc())
continue;
fs::info_t info;
rv = fs::info(branch.path, &info);
if(rv < 0)
continue;
if(info.readonly)
continue;
if(info.spaceavail < branch.minfreespace())
continue;
if(info.spaceavail > max_space)
{
max_space = info.spaceavail;
create_branch = &branch;
}
}
if(!create_branch)
return -ENOSPC;
// Clone path if needed
if(existing_branch != create_branch)
{
rv = fs::clonepath(existing_branch->path,
create_branch->path,
fusedirpath);
if(rv < 0)
return rv;
}
// Create the node
fs::path fullpath = create_branch->path / fusepath_;
if(!fs::acl::dir_has_defaults(fullpath))
{
mode_t mode = mode_ & ~umask_;
return fs::mknod_as(ugid_, fullpath, mode, dev_);
}
else
{
return fs::mknod_as(ugid_, fullpath, mode_, dev_);
}
}

24
src/func_mknod_mfs.hpp

@ -0,0 +1,24 @@
#include "func_mknod_base.hpp"
#include <string_view>
namespace Func2
{
class MknodMFS : public MknodBase
{
public:
MknodMFS() {}
~MknodMFS() {}
public:
std::string_view name() const;
public:
int operator()(const ugid_t &ugid,
const Branches &branches,
const fs::path &fusepath,
const mode_t mode,
const mode_t umask,
const dev_t dev);
};
}

31
src/fuse_mknod.cpp

@ -145,26 +145,23 @@ FUSE::mknod(const fuse_req_ctx_t *ctx_,
{
int rv;
const fs::path fusepath{fusepath_};
rv = ::_mknod(ctx_,
cfg.func.getattr.policy,
cfg.func.mknod.policy,
cfg.branches,
fusepath,
mode_,
ctx_->umask,
rdev_);
const ugid_t ugid(ctx_);
rv = cfg.mknod(ugid,
cfg.branches,
fusepath,
mode_,
ctx_->umask,
rdev_);
if(rv == -EROFS)
{
cfg.branches.find_and_set_mode_ro();
rv = ::_mknod(ctx_,
cfg.func.getattr.policy,
cfg.func.mknod.policy,
cfg.branches,
fusepath,
mode_,
ctx_->umask,
rdev_);
rv = cfg.mknod(ugid,
cfg.branches,
fusepath,
mode_,
ctx_->umask,
rdev_);
}
return rv;

Loading…
Cancel
Save