diff --git a/include/dwarfs/filesystem_v2.h b/include/dwarfs/filesystem_v2.h index 8c331fec..88a8668c 100644 --- a/include/dwarfs/filesystem_v2.h +++ b/include/dwarfs/filesystem_v2.h @@ -128,6 +128,11 @@ class filesystem_v2 { return impl_->access(entry, mode, uid, gid); } + void access(inode_view entry, int mode, uid_t uid, gid_t gid, + std::error_code& ec) const { + impl_->access(entry, mode, uid, gid, ec); + } + std::optional opendir(inode_view entry) const { return impl_->opendir(entry); } @@ -249,6 +254,8 @@ class filesystem_v2 { virtual file_stat getattr(inode_view entry) const = 0; virtual int access(inode_view entry, int mode, uid_t uid, gid_t gid) const = 0; + virtual void access(inode_view entry, int mode, uid_t uid, gid_t gid, + std::error_code& ec) const = 0; virtual std::optional opendir(inode_view entry) const = 0; virtual std::optional> readdir(directory_view dir, size_t offset) const = 0; diff --git a/src/dwarfs/filesystem_v2.cpp b/src/dwarfs/filesystem_v2.cpp index a2720637..169f9c68 100644 --- a/src/dwarfs/filesystem_v2.cpp +++ b/src/dwarfs/filesystem_v2.cpp @@ -97,6 +97,16 @@ R call_int_error(Fn&& fn, std::error_code& ec) { return res; } +template +void call_int_error(Fn&& fn, std::error_code& ec) { + auto err = std::forward(fn)(); + if (err < 0) { + ec = std::error_code{-err, std::system_category()}; + } else { + ec.clear(); + } +} + class filesystem_parser { private: static uint64_t constexpr section_offset_mask{(UINT64_C(1) << 48) - 1}; @@ -428,6 +438,8 @@ class filesystem_ final : public filesystem_v2::impl { file_stat getattr(inode_view entry, std::error_code& ec) const override; file_stat getattr(inode_view entry) const override; int access(inode_view entry, int mode, uid_t uid, gid_t gid) const override; + void access(inode_view entry, int mode, uid_t uid, gid_t gid, + std::error_code& ec) const override; std::optional opendir(inode_view entry) const override; std::optional> readdir(directory_view dir, size_t offset) const override; @@ -475,6 +487,7 @@ class filesystem_ final : public filesystem_v2::impl { private: filesystem_info const& get_info() const; void check_section(fs_section const& section) const; + file_stat getattr_ec(inode_view entry, std::error_code& ec) const; std::string readlink_ec(inode_view entry, readlink_mode mode, std::error_code& ec) const; std::vector> @@ -500,6 +513,7 @@ class filesystem_ final : public filesystem_v2::impl { PERFMON_CLS_TIMER_DECL(getattr_ec) PERFMON_CLS_TIMER_DECL(getattr_throw) PERFMON_CLS_TIMER_DECL(access) + PERFMON_CLS_TIMER_DECL(access_ec) PERFMON_CLS_TIMER_DECL(opendir) PERFMON_CLS_TIMER_DECL(readdir) PERFMON_CLS_TIMER_DECL(dirsize) @@ -582,6 +596,7 @@ filesystem_::filesystem_( PERFMON_CLS_TIMER_INIT(getattr_ec) PERFMON_CLS_TIMER_INIT(getattr_throw) PERFMON_CLS_TIMER_INIT(access) + PERFMON_CLS_TIMER_INIT(access_ec) PERFMON_CLS_TIMER_INIT(opendir) PERFMON_CLS_TIMER_INIT(readdir) PERFMON_CLS_TIMER_INIT(dirsize) @@ -1055,18 +1070,25 @@ int filesystem_::getattr(inode_view entry, return meta_.getattr(entry, stbuf); } +template +file_stat filesystem_::getattr_ec(inode_view entry, + std::error_code& ec) const { + return call_int_error( + [&](auto& stbuf) { return meta_.getattr(entry, &stbuf); }, ec); +} + template file_stat filesystem_::getattr(inode_view entry, std::error_code& ec) const { PERFMON_CLS_SCOPED_SECTION(getattr_ec) - return call_int_error( - [&](auto& stbuf) { return getattr(entry, &stbuf); }, ec); + return getattr_ec(entry, ec); } template file_stat filesystem_::getattr(inode_view entry) const { PERFMON_CLS_SCOPED_SECTION(getattr_throw) - return call_ec_throw([&](std::error_code& ec) { return getattr(entry, ec); }); + return call_ec_throw( + [&](std::error_code& ec) { return getattr_ec(entry, ec); }); } template @@ -1076,6 +1098,13 @@ int filesystem_::access(inode_view entry, int mode, uid_t uid, return meta_.access(entry, mode, uid, gid); } +template +void filesystem_::access(inode_view entry, int mode, uid_t uid, + gid_t gid, std::error_code& ec) const { + PERFMON_CLS_SCOPED_SECTION(access_ec) + call_int_error([&] { return meta_.access(entry, mode, uid, gid); }, ec); +} + template std::optional filesystem_::opendir(inode_view entry) const {