From a99c0e695d9f1683b4225d8f8e694e9acecef8cd Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 13 Nov 2025 23:14:45 -0600 Subject: [PATCH] checkpoint --- src/func_getattr.hpp | 76 ++++++++++++++++++++++++++++++++++++ src/func_getattr_combine.cpp | 64 ++++++++++++++++++++++++++++++ src/func_getattr_combine.hpp | 21 ++++++++++ src/func_getattr_factory.cpp | 39 ++++++++++++++++++ src/func_getattr_factory.hpp | 13 ++++++ src/func_getattr_newest.cpp | 58 +++++++++++++++++++++++++++ src/func_getattr_newest.hpp | 21 ++++++++++ src/timespec_utils.hpp | 38 ++++++++++++++++++ 8 files changed, 330 insertions(+) create mode 100644 src/func_getattr.hpp create mode 100644 src/func_getattr_combine.cpp create mode 100644 src/func_getattr_combine.hpp create mode 100644 src/func_getattr_factory.cpp create mode 100644 src/func_getattr_factory.hpp create mode 100644 src/func_getattr_newest.cpp create mode 100644 src/func_getattr_newest.hpp create mode 100644 src/timespec_utils.hpp diff --git a/src/func_getattr.hpp b/src/func_getattr.hpp new file mode 100644 index 00000000..d05261f2 --- /dev/null +++ b/src/func_getattr.hpp @@ -0,0 +1,76 @@ +#pragma once + +#include "func_getattr_base.hpp" +#include "func_getattr_factory.hpp" + +#include "tofrom_string.hpp" + +#include "fmt/core.h" + +#include + +#include + +namespace Func2 +{ + class GetAttr : public ToFromString + { + private: + std::shared_ptr _impl; + + public: + GetAttr() + { + } + + GetAttr(const std::string &name_) + { + _impl = Func2::GetAttrFactory::make(name_); + assert(_impl); + } + + public: + int + operator()(const Branches &branches_, + const fs::Path &fusepath_, + struct stat *st_, + const FollowSymlinksEnum follow_symlinks_, + const s64 symlinkify_timeout_) + { + std::shared_ptr p; + + p = std::atomic_load(&_impl); + + return (*p)(branches_, + fusepath_, + st_, + follow_symlinks_, + symlinkify_timeout_); + } + + public: + std::string + to_string() const + { + std::shared_ptr p; + + p = std::atomic_load(&_impl); + + return std::string(p->name()); + } + + int + from_string(const std::string &str_) + { + std::shared_ptr p; + + p = Func2::GetAttrFactory::make(str_); + if(!p) + return -EINVAL; + + _impl = std::atomic_load(&p); + + return 0; + } + }; +} diff --git a/src/func_getattr_combine.cpp b/src/func_getattr_combine.cpp new file mode 100644 index 00000000..a33d76a2 --- /dev/null +++ b/src/func_getattr_combine.cpp @@ -0,0 +1,64 @@ +#include "func_getattr_combine.hpp" + +#include "fs_inode.hpp" +#include "fs_stat.hpp" +#include "symlinkify.hpp" +#include "timespec_utils.hpp" + + +std::string_view +Func2::GetAttrCombine::name() const +{ + return "combine"; +} + +int +Func2::GetAttrCombine::operator()(const Branches &branches_, + const fs::path &fusepath_, + struct stat *st_, + const FollowSymlinksEnum follow_symlinks_, + const s64 symlinkify_timeout_) +{ + int rv; + fs::path fullpath; + const Branch *first_branch; + + first_branch = nullptr; + for(const auto &branch : branches_) + { + struct stat st; + + fullpath = branch.path; + fullpath += fusepath_; + rv = fs::stat(fullpath.c_str(),&st,follow_symlinks_); + if(rv == -1) + continue; + + if(!first_branch) + { + *st_ = st; + first_branch = &branch; + continue; + } + + st_->st_atim = TimeSpec::newest(st_->st_atim,st.st_atim); + st_->st_ctim = TimeSpec::newest(st_->st_ctim,st.st_ctim); + st_->st_mtim = TimeSpec::newest(st_->st_mtim,st.st_mtim); + st_->st_nlink += st.st_nlink; + } + + if(!first_branch) + return -ENOENT; + + if(symlinkify_timeout_ >= 0) + { + fullpath = first_branch->path / fusepath_; + symlinkify::convert_if_can_be_symlink(fullpath, + st_, + symlinkify_timeout_); + } + + fs::inode::calc(first_branch->path,fusepath_.string(),st_); + + return 0; +} diff --git a/src/func_getattr_combine.hpp b/src/func_getattr_combine.hpp new file mode 100644 index 00000000..2a97bdf4 --- /dev/null +++ b/src/func_getattr_combine.hpp @@ -0,0 +1,21 @@ +#include "func_getattr_base.hpp" + +namespace Func2 +{ + class GetAttrCombine : public GetAttrBase + { + public: + GetAttrCombine() {} + ~GetAttrCombine() {} + + public: + std::string_view name() const; + + public: + int operator()(const Branches &branches, + const fs::path &fusepath, + struct stat *st, + const FollowSymlinksEnum follow_symlinks, + const s64 symlinkify_timeout); + }; +} diff --git a/src/func_getattr_factory.cpp b/src/func_getattr_factory.cpp new file mode 100644 index 00000000..51d13afc --- /dev/null +++ b/src/func_getattr_factory.cpp @@ -0,0 +1,39 @@ +#include "func_getattr_factory.hpp" + +#include "func_getattr_combine.hpp" +#include "func_getattr_ff.hpp" +#include "func_getattr_newest.hpp" + +#include "policies.hpp" + +bool +Func2::GetAttrFactory::valid(const std::string str_) +{ + if(str_ == "combined") + return true; + if(str_ == "ff") + return true; + if(str_ == "newest") + return true; + + if(Policies::Search::find(str_)) + return true; + + return false; +} + +std::shared_ptr +Func2::GetAttrFactory::make(const std::string str_) +{ + if(str_ == "combine") + return std::make_shared(); + if(str_ == "ff") + return std::make_shared(); + if(str_ == "newest") + return std::make_shared(); + + if(Policies::Search::find(str_)) + return std::make_shared(); + + return {}; +} diff --git a/src/func_getattr_factory.hpp b/src/func_getattr_factory.hpp new file mode 100644 index 00000000..1b353d8e --- /dev/null +++ b/src/func_getattr_factory.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "func_getattr_base.hpp" + +namespace Func2 +{ + class GetAttrFactory + { + public: + static bool valid(const std::string str); + static std::shared_ptr make(const std::string str); + }; +} diff --git a/src/func_getattr_newest.cpp b/src/func_getattr_newest.cpp new file mode 100644 index 00000000..588b7efa --- /dev/null +++ b/src/func_getattr_newest.cpp @@ -0,0 +1,58 @@ +#include "func_getattr_newest.hpp" + +#include "fs_stat.hpp" +#include "fs_inode.hpp" +#include "timespec_utils.hpp" +#include "symlinkify.hpp" + + +std::string_view +Func2::GetAttrNewest::name() const +{ + return "newest"; +} + +int +Func2::GetAttrNewest::operator()(const Branches &branches_, + const fs::Path &fusepath_, + struct stat *st_, + const FollowSymlinksEnum follow_symlinks_, + const s64 symlinkify_timeout_) +{ + int rv; + fs::Path fullpath; + const Branch *newest_branch; + + newest_branch = nullptr; + for(const auto &branch : branches_) + { + struct stat tmp_st; + + fullpath = branch.path; + fullpath += fusepath_; + rv = fs::stat(fullpath,&tmp_st,follow_symlinks_); + if(rv == -1) + continue; + + if(!TimeSpec::is_newer(tmp_st.st_mtim,st_->st_mtim)) + continue; + + *st_ = tmp_st; + newest_branch = &branch; + } + + if(!newest_branch) + return -ENOENT; + + if(symlinkify_timeout_ >= 0) + { + fullpath = fs::path::make(newest_branch->path,fusepath_); + symlinkify::convert_if_can_be_symlink(fullpath, + st_, + symlinkify_timeout_); + } + + fs::inode::calc(newest_branch->path,fusepath_.string(),st_); + + return 0; +} diff --git a/src/func_getattr_newest.hpp b/src/func_getattr_newest.hpp new file mode 100644 index 00000000..b08d0a67 --- /dev/null +++ b/src/func_getattr_newest.hpp @@ -0,0 +1,21 @@ +#include "func_getattr_base.hpp" + +namespace Func2 +{ + class GetAttrNewest : public GetAttrBase + { + public: + GetAttrNewest() {} + ~GetAttrNewest() {} + + public: + std::string_view name() const; + + public: + int operator()(const Branches &branches, + const fs::path &fusepath, + struct stat *st, + const FollowSymlinksEnum follow_symlinks, + const s64 symlinkify_timeout); + }; +} diff --git a/src/timespec_utils.hpp b/src/timespec_utils.hpp new file mode 100644 index 00000000..292290b4 --- /dev/null +++ b/src/timespec_utils.hpp @@ -0,0 +1,38 @@ +#pragma once + +namespace TimeSpec +{ + static + inline + bool + is_newer(const timespec &t0_, + const timespec &t1_) + { + if(t0_.tv_sec > t1_.tv_sec) + return true; + if(t0_.tv_sec == t1_.tv_sec) + { + if(t0_.tv_nsec > t1_.tv_nsec) + return true; + } + + return false; + } + + static + inline + timespec + newest(const timespec &t0_, + const timespec &t1_) + { + if(t0_.tv_sec > t1_.tv_sec) + return t0_; + if(t0_.tv_sec == t1_.tv_sec) + { + if(t0_.tv_nsec > t1_.tv_nsec) + return t0_; + } + + return t1_; + } +}