From 964a4f49e6b475a94e338c6a32a33cc92d6d5b5d Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Wed, 31 Jul 2024 21:15:43 +0200 Subject: [PATCH] refactor(file_stat): turn into proper object with hidden data --- include/dwarfs/file_stat.h | 192 ++++++++++------ include/dwarfs/internal/metadata_v2.h | 1 - src/dwarfs/file_stat.cpp | 303 ++++++++++++++++++++------ src/dwarfs/filesystem_extractor.cpp | 4 +- src/dwarfs/internal/entry.cpp | 96 +++----- src/dwarfs/internal/metadata_v2.cpp | 43 ++-- src/dwarfs/os_access_generic.cpp | 2 +- src/dwarfs_main.cpp | 6 +- src/dwarfsbench_main.cpp | 2 +- src/dwarfsck_main.cpp | 4 +- test/block_cache_test.cpp | 10 +- test/compat_test.cpp | 53 ++--- test/dwarfs_benchmark.cpp | 5 +- test/dwarfs_test.cpp | 164 +++++++------- test/test_helpers.cpp | 25 ++- test/tool_main_test.cpp | 34 +-- test/tools_test.cpp | 4 +- 17 files changed, 559 insertions(+), 389 deletions(-) diff --git a/include/dwarfs/file_stat.h b/include/dwarfs/file_stat.h index 862a922f..160158b1 100644 --- a/include/dwarfs/file_stat.h +++ b/include/dwarfs/file_stat.h @@ -31,7 +31,8 @@ namespace dwarfs { -struct file_stat { +class file_stat { + public: using valid_fields_type = uint32_t; using perms_type = std::underlying_type_t; using mode_type = uint32_t; @@ -45,39 +46,6 @@ struct file_stat { using blkcnt_type = int64_t; using time_type = int64_t; - void ensure_valid(valid_fields_type fields) const; - - std::filesystem::file_status status() const { - ensure_valid(mode_valid); - return file_mode_to_status(mode); - }; - - posix_file_type::value type() const { - ensure_valid(mode_valid); - return static_cast(mode & posix_file_type::mask); - }; - - perms_type permissions() const { - ensure_valid(mode_valid); - return mode & 07777; - }; - - void set_permissions(perms_type perms) { mode = type() | (perms & 07777); } - - bool is_directory() const { return type() == posix_file_type::directory; } - - bool is_regular_file() const { return type() == posix_file_type::regular; } - - bool is_symlink() const { return type() == posix_file_type::symlink; } - - bool is_device() const { - auto t = type(); - return t == posix_file_type::block || t == posix_file_type::character; - } - - static std::string perm_string(mode_type mode); - static std::string mode_string(mode_type mode); - static constexpr valid_fields_type dev_valid = 1 << 0; static constexpr valid_fields_type ino_valid = 1 << 1; static constexpr valid_fields_type nlink_valid = 1 << 2; @@ -93,42 +61,126 @@ struct file_stat { static constexpr valid_fields_type ctime_valid = 1 << 12; static constexpr valid_fields_type all_valid = (1 << 13) - 1; - uint32_t valid_fields{0}; - dev_type dev; - ino_type ino; - nlink_type nlink; - mode_type mode; - uid_type uid; - gid_type gid; - dev_type rdev; - off_type size; - blksize_type blksize; - blkcnt_type blocks; - time_type atime; - time_type mtime; - time_type ctime; - std::exception_ptr exception; + file_stat(); + explicit file_stat(std::filesystem::path const& path); + + void ensure_valid(valid_fields_type fields) const; + + std::filesystem::file_status status() const; + posix_file_type::value type() const; + + perms_type permissions() const; + void set_permissions(perms_type perms); + + dev_type dev() const; + dev_type dev_unchecked() const { return dev_; } + void set_dev(dev_type dev); + + ino_type ino() const; + ino_type ino_unchecked() const { return ino_; } + void set_ino(ino_type ino); + + nlink_type nlink() const; + nlink_type nlink_unchecked() const { return nlink_; } + void set_nlink(nlink_type nlink); + + mode_type mode() const; + mode_type mode_unchecked() const { return mode_; } + void set_mode(mode_type mode); + + uid_type uid() const; + uid_type uid_unchecked() const { return uid_; } + void set_uid(uid_type uid); + + gid_type gid() const; + gid_type gid_unchecked() const { return gid_; } + void set_gid(gid_type gid); + + dev_type rdev() const; + dev_type rdev_unchecked() const { return rdev_; } + void set_rdev(dev_type rdev); + + off_type size() const; + off_type size_unchecked() const { return size_; } + void set_size(off_type size); + + blksize_type blksize() const; + blksize_type blksize_unchecked() const { return blksize_; } + void set_blksize(blksize_type blksize); + + blkcnt_type blocks() const; + blkcnt_type blocks_unchecked() const { return blocks_; } + void set_blocks(blkcnt_type blocks); + + time_type atime() const; + time_type atime_unchecked() const { return atime_; } + void set_atime(time_type atime); + + time_type mtime() const; + time_type mtime_unchecked() const { return mtime_; } + void set_mtime(time_type mtime); + + time_type ctime() const; + time_type ctime_unchecked() const { return ctime_; } + void set_ctime(time_type ctime); + + bool is_directory() const; + bool is_regular_file() const; + bool is_symlink() const; + bool is_device() const; + + static std::string perm_string(mode_type mode); + static std::string mode_string(mode_type mode); + + template + void copy_to(T* out) const { + copy_to_impl(out); + } + + template + void copy_to_without_block_info(T* out) const { + copy_to_impl(out); + } + + private: + template + void copy_to_impl(T* out) const { + constexpr valid_fields_type required_fields{ + with_block_info ? all_valid + : all_valid & ~(blksize_valid | blocks_valid)}; + ensure_valid(required_fields); + out->st_dev = dev_; + out->st_ino = ino_; + out->st_nlink = nlink_; + out->st_mode = mode_; + out->st_uid = uid_; + out->st_gid = gid_; + out->st_rdev = rdev_; + out->st_size = size_; + if constexpr (with_block_info) { + out->st_blksize = blksize_; + out->st_blocks = blocks_; + } + out->st_atime = atime_; + out->st_mtime = mtime_; + out->st_ctime = ctime_; + } + + uint32_t valid_fields_{0}; + dev_type dev_{}; + ino_type ino_{}; + nlink_type nlink_{}; + mode_type mode_{}; + uid_type uid_{}; + gid_type gid_{}; + dev_type rdev_{}; + off_type size_{}; + blksize_type blksize_{}; + blkcnt_type blocks_{}; + time_type atime_{}; + time_type mtime_{}; + time_type ctime_{}; + std::exception_ptr exception_; }; -file_stat make_file_stat(std::filesystem::path const& path); - -template -void copy_file_stat(T* out, file_stat const& in) { - out->st_dev = in.dev; - out->st_ino = in.ino; - out->st_nlink = in.nlink; - out->st_mode = in.mode; - out->st_uid = in.uid; - out->st_gid = in.gid; - out->st_rdev = in.rdev; - out->st_size = in.size; - if constexpr (with_block_info) { - out->st_blksize = in.blksize; - out->st_blocks = in.blocks; - } - out->st_atime = in.atime; - out->st_mtime = in.mtime; - out->st_ctime = in.ctime; -} - } // namespace dwarfs diff --git a/include/dwarfs/internal/metadata_v2.h b/include/dwarfs/internal/metadata_v2.h index 29376aa9..124ed572 100644 --- a/include/dwarfs/internal/metadata_v2.h +++ b/include/dwarfs/internal/metadata_v2.h @@ -45,7 +45,6 @@ class logger; struct getattr_options; struct metadata_options; struct filesystem_info; -struct file_stat; struct vfs_stat; class performance_monitor; diff --git a/src/dwarfs/file_stat.cpp b/src/dwarfs/file_stat.cpp index b88c9cec..75ab8577 100644 --- a/src/dwarfs/file_stat.cpp +++ b/src/dwarfs/file_stat.cpp @@ -98,9 +98,11 @@ void perms_to_stream(std::ostream& os, file_stat::mode_type mode) { } // namespace +file_stat::file_stat() = default; + #ifdef _WIN32 -file_stat make_file_stat(fs::path const& path) { +file_stat::file_stat(fs::path const& path) { std::error_code ec; auto status = fs::symlink_status(path, ec); @@ -108,11 +110,9 @@ file_stat make_file_stat(fs::path const& path) { status = fs::status(path, ec); } - file_stat rv; - if (ec) { - rv.exception = std::make_exception_ptr(std::system_error(ec)); - return rv; + exception_ = std::make_exception_ptr(std::system_error(ec)); + return; } if (status.type() == fs::file_type::not_found || @@ -125,10 +125,10 @@ file_stat make_file_stat(fs::path const& path) { u8string_to_string(path.u8string()))); } - rv.valid_fields = file_stat::mode_valid; - rv.mode = file_status_to_mode(status); - rv.blksize = 0; - rv.blocks = 0; + valid_fields_ = file_stat::mode_valid; + mode_ = file_status_to_mode(status); + blksize_ = 0; + blocks_ = 0; auto wps = path.wstring(); @@ -136,21 +136,21 @@ file_stat make_file_stat(fs::path const& path) { ::WIN32_FILE_ATTRIBUTE_DATA info; if (::GetFileAttributesExW(wps.c_str(), GetFileExInfoStandard, &info) == 0) { - rv.exception = std::make_exception_ptr(std::system_error( + exception_ = std::make_exception_ptr(std::system_error( ::GetLastError(), std::system_category(), "GetFileAttributesExW")); } else { - rv.valid_fields = file_stat::all_valid; - rv.dev = 0; - rv.ino = 0; - rv.nlink = 0; - rv.uid = 0; - rv.gid = 0; - rv.rdev = 0; - rv.size = + valid_fields_ = file_stat::all_valid; + dev_ = 0; + ino_ = 0; + nlink_ = 0; + uid_ = 0; + gid_ = 0; + rdev_ = 0; + size_ = (static_cast(info.nFileSizeHigh) << 32) + info.nFileSizeLow; - rv.atime = time_from_filetime(info.ftLastAccessTime); - rv.mtime = time_from_filetime(info.ftLastWriteTime); - rv.ctime = time_from_filetime(info.ftCreationTime); + atime_ = time_from_filetime(info.ftLastAccessTime); + mtime_ = time_from_filetime(info.ftLastWriteTime); + ctime_ = time_from_filetime(info.ftCreationTime); } } else { struct ::__stat64 st; @@ -165,83 +165,78 @@ file_stat make_file_stat(fs::path const& path) { ::BY_HANDLE_FILE_INFORMATION info; if (::GetFileInformationByHandle(hdl, &info)) { if (::CloseHandle(hdl)) { - rv.valid_fields |= file_stat::ino_valid | file_stat::nlink_valid; - rv.ino = (static_cast(info.nFileIndexHigh) << 32) + - info.nFileIndexLow; - rv.nlink = info.nNumberOfLinks; + valid_fields_ |= file_stat::ino_valid | file_stat::nlink_valid; + ino_ = (static_cast(info.nFileIndexHigh) << 32) + + info.nFileIndexLow; + nlink_ = info.nNumberOfLinks; } else { - rv.exception = std::make_exception_ptr(std::system_error( + exception_ = std::make_exception_ptr(std::system_error( ::GetLastError(), std::system_category(), "CloseHandle")); } } else { - rv.exception = std::make_exception_ptr( + exception_ = std::make_exception_ptr( std::system_error(::GetLastError(), std::system_category(), "GetFileInformationByHandle")); ::CloseHandle(hdl); } } else { - rv.exception = std::make_exception_ptr(std::system_error( + exception_ = std::make_exception_ptr(std::system_error( ::GetLastError(), std::system_category(), "CreateFileW")); } } else { - rv.valid_fields |= file_stat::ino_valid | file_stat::nlink_valid; - rv.ino = st.st_ino; - rv.nlink = st.st_nlink; + valid_fields_ |= file_stat::ino_valid | file_stat::nlink_valid; + ino_ = st.st_ino; + nlink_ = st.st_nlink; } - rv.valid_fields |= file_stat::dev_valid | file_stat::uid_valid | - file_stat::gid_valid | file_stat::rdev_valid | - file_stat::size_valid | file_stat::atime_valid | - file_stat::mtime_valid | file_stat::ctime_valid; - rv.dev = st.st_dev; - rv.uid = st.st_uid; - rv.gid = st.st_gid; - rv.rdev = st.st_rdev; - rv.size = st.st_size; - rv.atime = st.st_atime; - rv.mtime = st.st_mtime; - rv.ctime = st.st_ctime; + valid_fields_ |= file_stat::dev_valid | file_stat::uid_valid | + file_stat::gid_valid | file_stat::rdev_valid | + file_stat::size_valid | file_stat::atime_valid | + file_stat::mtime_valid | file_stat::ctime_valid; + dev_ = st.st_dev; + uid_ = st.st_uid; + gid_ = st.st_gid; + rdev_ = st.st_rdev; + size_ = st.st_size; + atime_ = st.st_atime; + mtime_ = st.st_mtime; + ctime_ = st.st_ctime; } else { - rv.exception = std::make_exception_ptr( + exception_ = std::make_exception_ptr( std::system_error(errno, std::generic_category(), "_stat64")); } } - - return rv; } #else -file_stat make_file_stat(fs::path const& path) { +file_stat::file_stat(fs::path const& path) { struct ::stat st; if (::lstat(path.string().c_str(), &st) != 0) { throw std::system_error(errno, std::generic_category(), "lstat"); } - file_stat rv; - rv.valid_fields = file_stat::all_valid; - rv.dev = st.st_dev; - rv.ino = st.st_ino; - rv.nlink = st.st_nlink; - rv.mode = st.st_mode; - rv.uid = st.st_uid; - rv.gid = st.st_gid; - rv.rdev = st.st_rdev; - rv.size = st.st_size; - rv.blksize = st.st_blksize; - rv.blocks = st.st_blocks; + valid_fields_ = file_stat::all_valid; + dev_ = st.st_dev; + ino_ = st.st_ino; + nlink_ = st.st_nlink; + mode_ = st.st_mode; + uid_ = st.st_uid; + gid_ = st.st_gid; + rdev_ = st.st_rdev; + size_ = st.st_size; + blksize_ = st.st_blksize; + blocks_ = st.st_blocks; #ifdef __APPLE__ - rv.atime = st.st_atimespec.tv_sec; - rv.mtime = st.st_mtimespec.tv_sec; - rv.ctime = st.st_ctimespec.tv_sec; + atime_ = st.st_atimespec.tv_sec; + mtime_ = st.st_mtimespec.tv_sec; + ctime_ = st.st_ctimespec.tv_sec; #else - rv.atime = st.st_atim.tv_sec; - rv.mtime = st.st_mtim.tv_sec; - rv.ctime = st.st_ctim.tv_sec; + atime_ = st.st_atim.tv_sec; + mtime_ = st.st_mtim.tv_sec; + ctime_ = st.st_ctim.tv_sec; #endif - - return rv; } #endif @@ -265,15 +260,181 @@ std::string file_stat::perm_string(mode_type mode) { } void file_stat::ensure_valid(valid_fields_type fields) const { - if ((valid_fields & fields) != fields) { - if (exception) { - std::rethrow_exception(exception); + if ((valid_fields_ & fields) != fields) { + if (exception_) { + std::rethrow_exception(exception_); } else { DWARFS_THROW(runtime_error, fmt::format("missing stat fields: {:#x} (have: {:#x})", - fields, valid_fields)); + fields, valid_fields_)); } } } +std::filesystem::file_status file_stat::status() const { + ensure_valid(mode_valid); + return file_mode_to_status(mode_); +}; + +posix_file_type::value file_stat::type() const { + ensure_valid(mode_valid); + return static_cast(mode_ & posix_file_type::mask); +}; + +file_stat::perms_type file_stat::permissions() const { + ensure_valid(mode_valid); + return mode_ & 07777; +}; + +void file_stat::set_permissions(perms_type perms) { + mode_ = type() | (perms & 07777); +} + +bool file_stat::is_directory() const { + return type() == posix_file_type::directory; +} + +bool file_stat::is_regular_file() const { + return type() == posix_file_type::regular; +} + +bool file_stat::is_symlink() const { + return type() == posix_file_type::symlink; +} + +bool file_stat::is_device() const { + auto t = type(); + return t == posix_file_type::block || t == posix_file_type::character; +} + +file_stat::dev_type file_stat::dev() const { + ensure_valid(dev_valid); + return dev_; +} + +void file_stat::set_dev(dev_type dev) { + valid_fields_ |= dev_valid; + dev_ = dev; +} + +file_stat::ino_type file_stat::ino() const { + ensure_valid(ino_valid); + return ino_; +} + +void file_stat::set_ino(ino_type ino) { + valid_fields_ |= ino_valid; + ino_ = ino; +} + +file_stat::nlink_type file_stat::nlink() const { + ensure_valid(nlink_valid); + return nlink_; +} + +void file_stat::set_nlink(nlink_type nlink) { + valid_fields_ |= nlink_valid; + nlink_ = nlink; +} + +file_stat::mode_type file_stat::mode() const { + ensure_valid(mode_valid); + return mode_; +} + +void file_stat::set_mode(mode_type mode) { + valid_fields_ |= mode_valid; + mode_ = mode; +} + +file_stat::uid_type file_stat::uid() const { + ensure_valid(uid_valid); + return uid_; +} + +void file_stat::set_uid(uid_type uid) { + valid_fields_ |= uid_valid; + uid_ = uid; +} + +file_stat::gid_type file_stat::gid() const { + ensure_valid(gid_valid); + return gid_; +} + +void file_stat::set_gid(gid_type gid) { + valid_fields_ |= gid_valid; + gid_ = gid; +} + +file_stat::dev_type file_stat::rdev() const { + ensure_valid(rdev_valid); + return rdev_; +} + +void file_stat::set_rdev(dev_type rdev) { + valid_fields_ |= rdev_valid; + rdev_ = rdev; +} + +file_stat::off_type file_stat::size() const { + ensure_valid(size_valid); + return size_; +} + +void file_stat::set_size(off_type size) { + valid_fields_ |= size_valid; + size_ = size; +} + +file_stat::blksize_type file_stat::blksize() const { + ensure_valid(blksize_valid); + return blksize_; +} + +void file_stat::set_blksize(blksize_type blksize) { + valid_fields_ |= blksize_valid; + blksize_ = blksize; +} + +file_stat::blkcnt_type file_stat::blocks() const { + ensure_valid(blocks_valid); + return blocks_; +} + +void file_stat::set_blocks(blkcnt_type blocks) { + valid_fields_ |= blocks_valid; + blocks_ = blocks; +} + +file_stat::time_type file_stat::atime() const { + ensure_valid(atime_valid); + return atime_; +} + +void file_stat::set_atime(time_type atime) { + valid_fields_ |= atime_valid; + atime_ = atime; +} + +file_stat::time_type file_stat::mtime() const { + ensure_valid(mtime_valid); + return mtime_; +} + +void file_stat::set_mtime(time_type mtime) { + valid_fields_ |= mtime_valid; + mtime_ = mtime; +} + +file_stat::time_type file_stat::ctime() const { + ensure_valid(ctime_valid); + return ctime_; +} + +void file_stat::set_ctime(time_type ctime) { + valid_fields_ |= ctime_valid; + ctime_ = ctime; +} + } // namespace dwarfs diff --git a/src/dwarfs/filesystem_extractor.cpp b/src/dwarfs/filesystem_extractor.cpp index cfd07983..532dfc7e 100644 --- a/src/dwarfs/filesystem_extractor.cpp +++ b/src/dwarfs/filesystem_extractor.cpp @@ -354,9 +354,9 @@ bool filesystem_extractor_::extract( ::memset(&st, 0, sizeof(st)); #ifdef _WIN32 - copy_file_stat(&st, stbuf); + stbuf.copy_to_without_block_info(&st); #else - copy_file_stat(&st, stbuf); + stbuf.copy_to(&st); #endif #ifdef _WIN32 diff --git a/src/dwarfs/internal/entry.cpp b/src/dwarfs/internal/entry.cpp index dda46c59..1736d136 100644 --- a/src/dwarfs/internal/entry.cpp +++ b/src/dwarfs/internal/entry.cpp @@ -160,12 +160,12 @@ void entry::update(global_entry_data& data) const { stat_.ensure_valid(file_stat::uid_valid | file_stat::gid_valid | file_stat::mode_valid | file_stat::atime_valid | file_stat::mtime_valid | file_stat::ctime_valid); - data.add_uid(stat_.uid); - data.add_gid(stat_.gid); - data.add_mode(stat_.mode); - data.add_atime(stat_.atime); - data.add_mtime(stat_.mtime); - data.add_ctime(stat_.ctime); + data.add_uid(stat_.uid_unchecked()); + data.add_gid(stat_.gid_unchecked()); + data.add_mode(stat_.mode_unchecked()); + data.add_atime(stat_.atime_unchecked()); + data.add_mtime(stat_.mtime_unchecked()); + data.add_ctime(stat_.ctime_unchecked()); } void entry::pack(thrift::metadata::inode_data& entry_v2, @@ -173,33 +173,21 @@ void entry::pack(thrift::metadata::inode_data& entry_v2, stat_.ensure_valid(file_stat::uid_valid | file_stat::gid_valid | file_stat::mode_valid | file_stat::atime_valid | file_stat::mtime_valid | file_stat::ctime_valid); - entry_v2.mode_index() = data.get_mode_index(stat_.mode); - entry_v2.owner_index() = data.get_uid_index(stat_.uid); - entry_v2.group_index() = data.get_gid_index(stat_.gid); - entry_v2.atime_offset() = data.get_atime_offset(stat_.atime); - entry_v2.mtime_offset() = data.get_mtime_offset(stat_.mtime); - entry_v2.ctime_offset() = data.get_ctime_offset(stat_.ctime); + entry_v2.mode_index() = data.get_mode_index(stat_.mode_unchecked()); + entry_v2.owner_index() = data.get_uid_index(stat_.uid_unchecked()); + entry_v2.group_index() = data.get_gid_index(stat_.gid_unchecked()); + entry_v2.atime_offset() = data.get_atime_offset(stat_.atime_unchecked()); + entry_v2.mtime_offset() = data.get_mtime_offset(stat_.mtime_unchecked()); + entry_v2.ctime_offset() = data.get_ctime_offset(stat_.ctime_unchecked()); } -size_t entry::size() const { - stat_.ensure_valid(file_stat::size_valid); - return stat_.size; -} +size_t entry::size() const { return stat_.size(); } -uint64_t entry::raw_inode_num() const { - stat_.ensure_valid(file_stat::ino_valid); - return stat_.ino; -} +uint64_t entry::raw_inode_num() const { return stat_.ino(); } -uint64_t entry::num_hard_links() const { - stat_.ensure_valid(file_stat::nlink_valid); - return stat_.nlink; -} +uint64_t entry::num_hard_links() const { return stat_.nlink(); } -void entry::override_size(size_t size) { - stat_.size = size; - stat_.valid_fields |= file_stat::size_valid; -} +void entry::override_size(size_t size) { stat_.set_size(size); } entry::type_t file::type() const { return E_FILE; } @@ -207,55 +195,25 @@ auto entry::get_permissions() const -> mode_type { return stat_.permissions(); } void entry::set_permissions(mode_type perm) { stat_.set_permissions(perm); } -auto entry::get_uid() const -> uid_type { - stat_.ensure_valid(file_stat::uid_valid); - return stat_.uid; -} +auto entry::get_uid() const -> uid_type { return stat_.uid(); } -void entry::set_uid(uid_type uid) { - stat_.uid = uid; - stat_.valid_fields |= file_stat::uid_valid; -} +void entry::set_uid(uid_type uid) { stat_.set_uid(uid); } -auto entry::get_gid() const -> gid_type { - stat_.ensure_valid(file_stat::gid_valid); - return stat_.gid; -} +auto entry::get_gid() const -> gid_type { return stat_.gid(); } -void entry::set_gid(gid_type gid) { - stat_.gid = gid; - stat_.valid_fields |= file_stat::gid_valid; -} +void entry::set_gid(gid_type gid) { stat_.set_gid(gid); } -uint64_t entry::get_atime() const { - stat_.ensure_valid(file_stat::atime_valid); - return stat_.atime; -} +uint64_t entry::get_atime() const { return stat_.atime(); } -void entry::set_atime(uint64_t atime) { - stat_.atime = atime; - stat_.valid_fields |= file_stat::atime_valid; -} +void entry::set_atime(uint64_t atime) { stat_.set_atime(atime); } -uint64_t entry::get_mtime() const { - stat_.ensure_valid(file_stat::mtime_valid); - return stat_.mtime; -} +uint64_t entry::get_mtime() const { return stat_.mtime(); } -void entry::set_mtime(uint64_t mtime) { - stat_.mtime = mtime; - stat_.valid_fields |= file_stat::mtime_valid; -} +void entry::set_mtime(uint64_t mtime) { stat_.set_mtime(mtime); } -uint64_t entry::get_ctime() const { - stat_.ensure_valid(file_stat::ctime_valid); - return stat_.ctime; -} +uint64_t entry::get_ctime() const { return stat_.ctime(); } -void entry::set_ctime(uint64_t ctime) { - stat_.ctime = ctime; - stat_.valid_fields |= file_stat::ctime_valid; -} +void entry::set_ctime(uint64_t ctime) { stat_.set_ctime(ctime); } std::string_view file::hash() const { auto& h = data_->hash; @@ -506,6 +464,6 @@ void device::accept(entry_visitor& v, bool) { v.visit(this); } void device::scan(os_access const&, progress&) {} -uint64_t device::device_id() const { return status().rdev; } +uint64_t device::device_id() const { return status().rdev(); } } // namespace dwarfs::internal diff --git a/src/dwarfs/internal/metadata_v2.cpp b/src/dwarfs/internal/metadata_v2.cpp index 45901210..21011e17 100644 --- a/src/dwarfs/internal/metadata_v2.cpp +++ b/src/dwarfs/internal/metadata_v2.cpp @@ -1540,9 +1540,7 @@ metadata_::getattr_impl(inode_view iv, getattr_options const& opts) const { file_stat stbuf; - ::memset(&stbuf, 0, sizeof(stbuf)); - - stbuf.valid_fields = file_stat::all_valid; + stbuf.set_dev(0); // TODO: should we make this configurable? auto mode = iv.mode(); auto timebase = meta_.timestamp_base(); @@ -1556,38 +1554,37 @@ metadata_::getattr_impl(inode_view iv, } } - stbuf.mode = mode; - if (options_.readonly) { - stbuf.mode &= READ_ONLY_MASK; + mode &= READ_ONLY_MASK; } + stbuf.set_mode(mode); + if (!opts.no_size) { - stbuf.size = stbuf.is_directory() ? make_directory_view(iv).entry_count() - : file_size(iv, mode); + stbuf.set_size(stbuf.is_directory() ? make_directory_view(iv).entry_count() + : file_size(iv, mode)); + stbuf.set_blocks((stbuf.size_unchecked() + 511) / 512); } - stbuf.ino = inode + inode_offset_; - stbuf.blksize = options_.block_size; - stbuf.blocks = (stbuf.size + 511) / 512; - stbuf.uid = iv.getuid(); - stbuf.gid = iv.getgid(); - stbuf.mtime = resolution * (timebase + iv.raw().mtime_offset()); + stbuf.set_ino(inode + inode_offset_); + stbuf.set_blksize(options_.block_size); + stbuf.set_uid(iv.getuid()); + stbuf.set_gid(iv.getgid()); + stbuf.set_mtime(resolution * (timebase + iv.raw().mtime_offset())); if (mtime_only) { - stbuf.atime = stbuf.ctime = stbuf.mtime; + stbuf.set_atime(stbuf.mtime_unchecked()); + stbuf.set_ctime(stbuf.mtime_unchecked()); } else { - stbuf.atime = resolution * (timebase + iv.raw().atime_offset()); - stbuf.ctime = resolution * (timebase + iv.raw().ctime_offset()); + stbuf.set_atime(resolution * (timebase + iv.raw().atime_offset())); + stbuf.set_ctime(resolution * (timebase + iv.raw().ctime_offset())); } - stbuf.nlink = options_.enable_nlink && stbuf.is_regular_file() - ? DWARFS_NOTHROW(nlinks_.at(inode - file_inode_offset_)) - : 1; + stbuf.set_nlink(options_.enable_nlink && stbuf.is_regular_file() + ? DWARFS_NOTHROW(nlinks_.at(inode - file_inode_offset_)) + : 1); - if (stbuf.is_device()) { - stbuf.rdev = get_device_id(inode); - } + stbuf.set_rdev(stbuf.is_device() ? get_device_id(inode) : 0); return stbuf; } diff --git a/src/dwarfs/os_access_generic.cpp b/src/dwarfs/os_access_generic.cpp index 135ef03e..39c387f6 100644 --- a/src/dwarfs/os_access_generic.cpp +++ b/src/dwarfs/os_access_generic.cpp @@ -92,7 +92,7 @@ os_access_generic::opendir(fs::path const& path) const { } file_stat os_access_generic::symlink_info(fs::path const& path) const { - return make_file_stat(path); + return file_stat(path); } fs::path os_access_generic::read_symlink(fs::path const& path) const { diff --git a/src/dwarfs_main.cpp b/src/dwarfs_main.cpp index 47439d21..0c582dc0 100644 --- a/src/dwarfs_main.cpp +++ b/src/dwarfs_main.cpp @@ -375,7 +375,7 @@ void op_lookup(fuse_req_t req, fuse_ino_t parent, char const* name) { struct ::fuse_entry_param e; ::memset(&e.attr, 0, sizeof(e.attr)); - copy_file_stat(&e.attr, stbuf); + stbuf.copy_to(&e.attr); e.generation = 1; e.ino = e.attr.st_ino; e.attr_timeout = std::numeric_limits::max(); @@ -406,7 +406,7 @@ int op_getattr_common(LogProxy& log_, dwarfs_userdata& userdata, if (!ec) { ::memset(st, 0, sizeof(*st)); - copy_file_stat(st, stbuf); + stbuf.copy_to(st); } return ec.value(); @@ -793,7 +793,7 @@ int op_readdir_common(filesystem_v2& fs, Policy& policy, file_off_t off, return ec.value(); } - copy_file_stat(&st, stbuf); + stbuf.copy_to(&st); if (!policy.add_entry(name, st, off)) { break; diff --git a/src/dwarfsbench_main.cpp b/src/dwarfsbench_main.cpp index aefac4b4..ccbcf367 100644 --- a/src/dwarfsbench_main.cpp +++ b/src/dwarfsbench_main.cpp @@ -110,7 +110,7 @@ int dwarfsbench_main(int argc, sys_char** argv, iolayer const& iol) { pool.add_job([&fs, &iol, inode_data] { try { auto stbuf = fs.getattr(inode_data); - std::vector buf(stbuf.size); + std::vector buf(stbuf.size()); int fh = fs.open(inode_data); fs.read(fh, buf.data(), buf.size()); } catch (std::exception const& e) { diff --git a/src/dwarfsck_main.cpp b/src/dwarfsck_main.cpp index 9395f938..3be1de9c 100644 --- a/src/dwarfsck_main.cpp +++ b/src/dwarfsck_main.cpp @@ -73,7 +73,7 @@ void do_list_files(filesystem_v2& fs, iolayer const& iol, bool verbose) { file_stat::off_type max_inode_size{0}; fs.walk([&](auto const& de) { auto st = fs.getattr(de.inode()); - max_inode_size = std::max(max_inode_size, st.size); + max_inode_size = std::max(max_inode_size, st.size()); }); inode_size_width = fmt::format("{:L}", max_inode_size).size(); } @@ -96,7 +96,7 @@ void do_list_files(filesystem_v2& fs, iolayer const& iol, bool verbose) { iol.out << fmt::format( "{3} {4:{0}}/{5:{1}} {6:{2}L} {7:%Y-%m-%d %H:%M} {8}\n", uid_width, gid_width, inode_size_width, iv.mode_string(), iv.getuid(), - iv.getgid(), st.size, fmt::localtime(st.mtime), name); + iv.getgid(), st.size(), fmt::localtime(st.mtime()), name); } else if (!name.empty()) { iol.out << name << "\n"; } diff --git a/test/block_cache_test.cpp b/test/block_cache_test.cpp index f1ebfe88..d107e3f5 100644 --- a/test/block_cache_test.cpp +++ b/test/block_cache_test.cpp @@ -229,14 +229,14 @@ TEST_P(options_test, cache_stress) { auto iv = inodes[inode_dist(rng)]; auto stat = fs.getattr(iv); if (stat.is_regular_file()) { - auto offset = rng() % stat.size; - auto size = rng() % (stat.size - offset); + auto offset = rng() % stat.size(); + auto size = rng() % (stat.size() - offset); reqs.push_back({iv, offset, size}); while (reqs.size() < num_read_reqs && - offset + size < static_cast(stat.size / 2)) { - offset += rng() % (stat.size - (offset + size)); - size = rng() % (stat.size - offset); + offset + size < static_cast(stat.size() / 2)) { + offset += rng() % (stat.size() - (offset + size)); + size = rng() % (stat.size() - offset); reqs.push_back({iv, offset, size}); } } diff --git a/test/compat_test.cpp b/test/compat_test.cpp index 5b7c36d4..0e6b198a 100644 --- a/test/compat_test.cpp +++ b/test/compat_test.cpp @@ -807,9 +807,8 @@ std::vector headers_v2{ file_stat make_stat(posix_file_type::value type, file_stat::perms_type perms, file_stat::off_type size) { file_stat st; - std::memset(&st, 0, sizeof(st)); - st.mode = type | perms; - st.size = size; + st.set_mode(type | perms); + st.set_size(size); return st; } @@ -839,14 +838,14 @@ void check_compat(logger& lgr, filesystem_v2 const& fs, ASSERT_TRUE(entry); auto st = fs.getattr(*entry); - EXPECT_EQ(94, st.size); - EXPECT_EQ(S_IFREG | 0755, st.mode); - EXPECT_EQ(1000, st.uid); - EXPECT_EQ(100, st.gid); - EXPECT_EQ(1606256045, st.mtime); + EXPECT_EQ(94, st.size()); + EXPECT_EQ(S_IFREG | 0755, st.mode()); + EXPECT_EQ(1000, st.uid()); + EXPECT_EQ(100, st.gid()); + EXPECT_EQ(1606256045, st.mtime()); if (has_ac_time) { - EXPECT_EQ(1616013831, st.atime); - EXPECT_EQ(1616013816, st.ctime); + EXPECT_EQ(1616013831, st.atime()); + EXPECT_EQ(1616013816, st.ctime()); } EXPECT_TRUE(fs.access(*entry, R_OK, 1000, 0)); @@ -855,10 +854,10 @@ void check_compat(logger& lgr, filesystem_v2 const& fs, EXPECT_GE(inode, 0); std::error_code ec; - std::vector buf(st.size); - auto rv = fs.read(inode, &buf[0], st.size, ec); + std::vector buf(st.size()); + auto rv = fs.read(inode, &buf[0], st.size(), ec); EXPECT_FALSE(ec); - EXPECT_EQ(rv, st.size); + EXPECT_EQ(rv, st.size()); EXPECT_EQ(format_sh, std::string(buf.begin(), buf.end())); entry = fs.find("/foo/bad"); @@ -944,8 +943,10 @@ void check_compat(logger& lgr, filesystem_v2 const& fs, for (auto special : {"dev/null", "dev/zero", "foo/pipe"}) { ref_entries.erase(special); } - ref_entries["dev"].size -= 2; - ref_entries["foo"].size -= 1; + auto& dev = ref_entries["dev"]; + auto& foo = ref_entries["foo"]; + dev.set_size(dev.size() - 2); + foo.set_size(foo.size() - 1); } for (auto mp : {&filesystem_v2::walk, &filesystem_v2::walk_data_order}) { @@ -954,7 +955,7 @@ void check_compat(logger& lgr, filesystem_v2 const& fs, (fs.*mp)([&](dir_entry_view e) { auto stbuf = fs.getattr(e.inode()); - inodes.push_back(stbuf.ino); + inodes.push_back(stbuf.ino()); EXPECT_TRUE(entries.emplace(e.unix_path(), stbuf).second); }); @@ -964,15 +965,15 @@ void check_compat(logger& lgr, filesystem_v2 const& fs, auto it = ref_entries.find(p); EXPECT_TRUE(it != ref_entries.end()) << p; if (it != ref_entries.end()) { - EXPECT_EQ(it->second.mode, st.mode) << p; + EXPECT_EQ(it->second.mode(), st.mode()) << p; if (st.type() == posix_file_type::character) { - EXPECT_EQ(0, st.uid) << p; - EXPECT_EQ(0, st.gid) << p; + EXPECT_EQ(0, st.uid()) << p; + EXPECT_EQ(0, st.gid()) << p; } else { - EXPECT_EQ(1000, st.uid) << p; - EXPECT_EQ(100, st.gid) << p; + EXPECT_EQ(1000, st.uid()) << p; + EXPECT_EQ(100, st.gid()) << p; } - EXPECT_EQ(it->second.size, st.size) << p; + EXPECT_EQ(it->second.size(), st.size()) << p; } } } @@ -1015,12 +1016,12 @@ void check_compat(logger& lgr, filesystem_v2 const& fs, if (ri != ref_entries.end()) { auto const& st = ri->second; - EXPECT_EQ(kv["mode"], fmt::format("{0:o}", st.mode & 0777)); + EXPECT_EQ(kv["mode"], fmt::format("{0:o}", st.mode() & 0777)); EXPECT_EQ(std::stoi(kv["uid"]), kv["type"] == "char" ? 0 : 1000); EXPECT_EQ(std::stoi(kv["gid"]), kv["type"] == "char" ? 0 : 100); if (kv["type"] == "file") { - EXPECT_EQ(std::stoi(kv["size"]), st.size); + EXPECT_EQ(std::stoi(kv["size"]), st.size()); } } } @@ -1268,8 +1269,8 @@ TEST_P(set_uidgid_test, read_legacy_image) { EXPECT_EQ(44444, v->getgid()) << path; auto st = fs.getattr(*v); - EXPECT_EQ(33333, st.uid) << path; - EXPECT_EQ(44444, st.gid) << path; + EXPECT_EQ(33333, st.uid()) << path; + EXPECT_EQ(44444, st.gid()) << path; } } diff --git a/test/dwarfs_benchmark.cpp b/test/dwarfs_benchmark.cpp index 958f901d..b9b3ba9b 100644 --- a/test/dwarfs_benchmark.cpp +++ b/test/dwarfs_benchmark.cpp @@ -228,10 +228,11 @@ class filesystem : public ::benchmark::Fixture { auto st = fs->getattr(*iv); auto i = fs->open(*iv); std::string buf; - buf.resize(st.size); + auto size = st.size(); + buf.resize(size); for (auto _ : state) { - auto r = fs->read(i, buf.data(), st.size); + auto r = fs->read(i, buf.data(), size); ::benchmark::DoNotOptimize(r); } } diff --git a/test/dwarfs_test.cpp b/test/dwarfs_test.cpp index 63826df5..6d19b1fc 100644 --- a/test/dwarfs_test.cpp +++ b/test/dwarfs_test.cpp @@ -257,56 +257,56 @@ void basic_end_to_end_test(std::string const& compressor, ASSERT_TRUE(entry); auto st = fs.getattr(*entry); - EXPECT_EQ(st.size, 23456); - EXPECT_EQ(st.uid, set_uid ? 0 : 1337); - EXPECT_EQ(st.gid, 0); - EXPECT_EQ(st.atime, set_time ? 4711 : keep_all_times ? 4001 : 4002); - EXPECT_EQ(st.mtime, set_time ? 4711 : keep_all_times ? 4002 : 4002); - EXPECT_EQ(st.ctime, set_time ? 4711 : keep_all_times ? 4003 : 4002); + EXPECT_EQ(st.size(), 23456); + EXPECT_EQ(st.uid(), set_uid ? 0 : 1337); + EXPECT_EQ(st.gid(), 0); + EXPECT_EQ(st.atime(), set_time ? 4711 : keep_all_times ? 4001 : 4002); + EXPECT_EQ(st.mtime(), set_time ? 4711 : keep_all_times ? 4002 : 4002); + EXPECT_EQ(st.ctime(), set_time ? 4711 : keep_all_times ? 4003 : 4002); { std::error_code ec; auto st2 = fs.getattr(*entry, {.no_size = true}, ec); EXPECT_FALSE(ec); - EXPECT_EQ(st2.size, 0); - EXPECT_EQ(st2.uid, st.uid); - EXPECT_EQ(st2.gid, st.gid); - EXPECT_EQ(st2.atime, st.atime); - EXPECT_EQ(st2.mtime, st.mtime); - EXPECT_EQ(st2.ctime, st.ctime); + EXPECT_THROW(st2.size(), runtime_error); + EXPECT_EQ(st2.uid(), st.uid()); + EXPECT_EQ(st2.gid(), st.gid()); + EXPECT_EQ(st2.atime(), st.atime()); + EXPECT_EQ(st2.mtime(), st.mtime()); + EXPECT_EQ(st2.ctime(), st.ctime()); } { auto st3 = fs.getattr(*entry, {.no_size = true}); - EXPECT_EQ(st3.size, 0); - EXPECT_EQ(st3.uid, st.uid); - EXPECT_EQ(st3.gid, st.gid); - EXPECT_EQ(st3.atime, st.atime); - EXPECT_EQ(st3.mtime, st.mtime); - EXPECT_EQ(st3.ctime, st.ctime); + EXPECT_THROW(st3.size(), runtime_error); + EXPECT_EQ(st3.uid(), st.uid()); + EXPECT_EQ(st3.gid(), st.gid()); + EXPECT_EQ(st3.atime(), st.atime()); + EXPECT_EQ(st3.mtime(), st.mtime()); + EXPECT_EQ(st3.ctime(), st.ctime()); } int inode = fs.open(*entry); EXPECT_GE(inode, 0); std::error_code ec; - std::vector buf(st.size); - auto rv = fs.read(inode, &buf[0], st.size, ec); + std::vector buf(st.size()); + auto rv = fs.read(inode, &buf[0], st.size(), ec); EXPECT_FALSE(ec); - EXPECT_EQ(rv, st.size); - EXPECT_EQ(std::string(buf.begin(), buf.end()), test::loremipsum(st.size)); + EXPECT_EQ(rv, st.size()); + EXPECT_EQ(std::string(buf.begin(), buf.end()), test::loremipsum(st.size())); entry = fs.find("/somelink"); ASSERT_TRUE(entry); st = fs.getattr(*entry); - EXPECT_EQ(st.size, 16); - EXPECT_EQ(st.uid, set_uid ? 0 : 1000); - EXPECT_EQ(st.gid, set_gid ? 0 : 100); - EXPECT_EQ(st.rdev, 0); - EXPECT_EQ(st.atime, set_time ? 4711 : keep_all_times ? 2001 : 2002); - EXPECT_EQ(st.mtime, set_time ? 4711 : keep_all_times ? 2002 : 2002); - EXPECT_EQ(st.ctime, set_time ? 4711 : keep_all_times ? 2003 : 2002); + EXPECT_EQ(st.size(), 16); + EXPECT_EQ(st.uid(), set_uid ? 0 : 1000); + EXPECT_EQ(st.gid(), set_gid ? 0 : 100); + EXPECT_EQ(st.rdev(), 0); + EXPECT_EQ(st.atime(), set_time ? 4711 : keep_all_times ? 2001 : 2002); + EXPECT_EQ(st.mtime(), set_time ? 4711 : keep_all_times ? 2002 : 2002); + EXPECT_EQ(st.ctime(), set_time ? 4711 : keep_all_times ? 2003 : 2002); auto link = fs.readlink(*entry); EXPECT_EQ(link, "somedir/ipsum.py"); @@ -317,7 +317,7 @@ void basic_end_to_end_test(std::string const& compressor, ASSERT_TRUE(entry); st = fs.getattr(*entry); - EXPECT_EQ(st.size, 6); + EXPECT_EQ(st.size(), 6); link = fs.readlink(*entry); EXPECT_EQ(link, "../foo"); @@ -327,14 +327,14 @@ void basic_end_to_end_test(std::string const& compressor, if (with_specials) { ASSERT_TRUE(entry); st = fs.getattr(*entry); - EXPECT_EQ(st.size, 0); - EXPECT_EQ(st.uid, set_uid ? 0 : 1000); - EXPECT_EQ(st.gid, set_gid ? 0 : 100); + EXPECT_EQ(st.size(), 0); + EXPECT_EQ(st.uid(), set_uid ? 0 : 1000); + EXPECT_EQ(st.gid(), set_gid ? 0 : 100); EXPECT_EQ(st.type(), posix_file_type::fifo); - EXPECT_EQ(st.rdev, 0); - EXPECT_EQ(st.atime, set_time ? 4711 : keep_all_times ? 8001 : 8002); - EXPECT_EQ(st.mtime, set_time ? 4711 : keep_all_times ? 8002 : 8002); - EXPECT_EQ(st.ctime, set_time ? 4711 : keep_all_times ? 8003 : 8002); + EXPECT_EQ(st.rdev(), 0); + EXPECT_EQ(st.atime(), set_time ? 4711 : keep_all_times ? 8001 : 8002); + EXPECT_EQ(st.mtime(), set_time ? 4711 : keep_all_times ? 8002 : 8002); + EXPECT_EQ(st.ctime(), set_time ? 4711 : keep_all_times ? 8003 : 8002); } else { EXPECT_FALSE(entry); } @@ -344,11 +344,11 @@ void basic_end_to_end_test(std::string const& compressor, if (with_devices) { ASSERT_TRUE(entry); st = fs.getattr(*entry); - EXPECT_EQ(st.size, 0); - EXPECT_EQ(st.uid, 0); - EXPECT_EQ(st.gid, 0); + EXPECT_EQ(st.size(), 0); + EXPECT_EQ(st.uid(), 0); + EXPECT_EQ(st.gid(), 0); EXPECT_EQ(st.type(), posix_file_type::character); - EXPECT_EQ(st.rdev, 259); + EXPECT_EQ(st.rdev(), 259); } else { EXPECT_FALSE(entry); } @@ -358,20 +358,20 @@ void basic_end_to_end_test(std::string const& compressor, if (with_devices) { ASSERT_TRUE(entry); st = fs.getattr(*entry); - EXPECT_EQ(st.size, 0); - EXPECT_EQ(st.uid, 0); - EXPECT_EQ(st.gid, 0); + EXPECT_EQ(st.size(), 0); + EXPECT_EQ(st.uid(), 0); + EXPECT_EQ(st.gid(), 0); EXPECT_EQ(st.type(), posix_file_type::character); - EXPECT_EQ(st.rdev, 261); - EXPECT_EQ(st.atime, set_time ? 4711 - : keep_all_times ? 4000010001 - : 4000020002); - EXPECT_EQ(st.mtime, set_time ? 4711 - : keep_all_times ? 4000020002 - : 4000020002); - EXPECT_EQ(st.ctime, set_time ? 4711 - : keep_all_times ? 4000030003 - : 4000020002); + EXPECT_EQ(st.rdev(), 261); + EXPECT_EQ(st.atime(), set_time ? 4711 + : keep_all_times ? 4000010001 + : 4000020002); + EXPECT_EQ(st.mtime(), set_time ? 4711 + : keep_all_times ? 4000020002 + : 4000020002); + EXPECT_EQ(st.ctime(), set_time ? 4711 + : keep_all_times ? 4000030003 + : 4000020002); } else { EXPECT_FALSE(entry); } @@ -427,10 +427,10 @@ void basic_end_to_end_test(std::string const& compressor, auto st1 = fs.getattr(*entry); auto st2 = fs.getattr(*e2); - EXPECT_EQ(st1.ino, st2.ino); + EXPECT_EQ(st1.ino(), st2.ino()); if (enable_nlink) { - EXPECT_EQ(2, st1.nlink); - EXPECT_EQ(2, st2.nlink); + EXPECT_EQ(2, st1.nlink()); + EXPECT_EQ(2, st2.nlink()); } entry = fs.find("/"); @@ -443,14 +443,14 @@ void basic_end_to_end_test(std::string const& compressor, ASSERT_TRUE(entry); EXPECT_GT(entry->inode_num(), 0); st1 = fs.getattr(*entry); - EXPECT_EQ(23456, st1.size); + EXPECT_EQ(23456, st1.size()); e2 = fs.find(0, "somedir"); ASSERT_TRUE(e2); st2 = fs.getattr(*e2); - entry = fs.find(st2.ino, "ipsum.py"); + entry = fs.find(st2.ino(), "ipsum.py"); ASSERT_TRUE(entry); st1 = fs.getattr(*entry); - EXPECT_EQ(access_fail ? 0 : 10000, st1.size); + EXPECT_EQ(access_fail ? 0 : 10000, st1.size()); EXPECT_TRUE(fs.access(*entry, R_OK, 1000, 100)); entry = fs.find(0, "baz.pl"); ASSERT_TRUE(entry); @@ -464,7 +464,7 @@ void basic_end_to_end_test(std::string const& compressor, (fs.*mp)([&](dir_entry_view e) { auto stbuf = fs.getattr(e.inode()); - inodes.push_back(stbuf.ino); + inodes.push_back(stbuf.ino()); auto path = e.path(); if (!path.empty()) { path = "/" + path; @@ -477,14 +477,14 @@ void basic_end_to_end_test(std::string const& compressor, for (auto const& [p, st] : entries) { auto ref = input->symlink_info(p); - EXPECT_EQ(ref.mode, st.mode) << p; - EXPECT_EQ(set_uid ? 0 : ref.uid, st.uid) << p; - EXPECT_EQ(set_gid ? 0 : ref.gid, st.gid) << p; + EXPECT_EQ(ref.mode(), st.mode()) << p; + EXPECT_EQ(set_uid ? 0 : ref.uid(), st.uid()) << p; + EXPECT_EQ(set_gid ? 0 : ref.gid(), st.gid()) << p; if (!st.is_directory()) { if (input->access(p, R_OK) == 0) { - EXPECT_EQ(ref.size, st.size) << p; + EXPECT_EQ(ref.size(), st.size()) << p; } else { - EXPECT_EQ(0, st.size) << p; + EXPECT_EQ(0, st.size()) << p; } } } @@ -824,7 +824,7 @@ TEST_P(compression_regression, github45) { ASSERT_TRUE(entry); auto st = fs.getattr(*entry); - EXPECT_EQ(st.size, file_size); + EXPECT_EQ(st.size(), file_size); int inode = fs.open(*entry); EXPECT_GE(inode, 0); @@ -1117,10 +1117,10 @@ TEST(filesystem, uid_gid_32bit) { auto st16 = fs.getattr(*iv16); auto st32 = fs.getattr(*iv32); - EXPECT_EQ(60000, st16.uid); - EXPECT_EQ(65535, st16.gid); - EXPECT_EQ(65536, st32.uid); - EXPECT_EQ(4294967295, st32.gid); + EXPECT_EQ(60000, st16.uid()); + EXPECT_EQ(65535, st16.gid()); + EXPECT_EQ(65536, st32.uid()); + EXPECT_EQ(4294967295, st32.gid()); } TEST(filesystem, uid_gid_count) { @@ -1154,12 +1154,12 @@ TEST(filesystem, uid_gid_count) { auto st50000 = fs.getattr(*iv50000); auto st99999 = fs.getattr(*iv99999); - EXPECT_EQ(50000, st00000.uid); - EXPECT_EQ(250000, st00000.gid); - EXPECT_EQ(100000, st50000.uid); - EXPECT_EQ(300000, st50000.gid); - EXPECT_EQ(149999, st99999.uid); - EXPECT_EQ(349999, st99999.gid); + EXPECT_EQ(50000, st00000.uid()); + EXPECT_EQ(250000, st00000.gid()); + EXPECT_EQ(100000, st50000.uid()); + EXPECT_EQ(300000, st50000.gid()); + EXPECT_EQ(149999, st99999.uid()); + EXPECT_EQ(349999, st99999.gid()); } TEST(section_index_regression, github183) { @@ -1233,8 +1233,8 @@ TEST(section_index_regression, github183) { EXPECT_NO_THROW(inode = fs.open(*entry)); std::error_code ec; - std::vector buf(st.size); - auto rv = fs.read(inode, &buf[0], st.size, ec); + std::vector buf(st.size()); + auto rv = fs.read(inode, &buf[0], st.size(), ec); EXPECT_TRUE(ec); EXPECT_EQ(rv, 0); @@ -1294,9 +1294,9 @@ TEST(file_scanner, file_start_hash) { auto st1 = fs.getattr(*link1); auto st2 = fs.getattr(*link2); - EXPECT_EQ(st1.ino, st2.ino); - EXPECT_EQ(st1.nlink, 2); - EXPECT_EQ(st2.nlink, 2); + EXPECT_EQ(st1.ino(), st2.ino()); + EXPECT_EQ(st1.nlink(), 2); + EXPECT_EQ(st2.nlink(), 2); } TEST(filesystem, root_access_github204) { diff --git a/test/test_helpers.cpp b/test/test_helpers.cpp index 351ef0a0..a43ec796 100644 --- a/test/test_helpers.cpp +++ b/test/test_helpers.cpp @@ -49,18 +49,19 @@ namespace { file_stat make_file_stat(simplestat const& ss) { file_stat rv; - ::memset(&rv, 0, sizeof(rv)); - rv.valid_fields = file_stat::all_valid; - rv.ino = ss.ino; - rv.nlink = ss.nlink; - rv.mode = ss.mode; - rv.uid = ss.uid; - rv.gid = ss.gid; - rv.rdev = ss.rdev; - rv.size = ss.size; - rv.atime = ss.atime; - rv.mtime = ss.mtime; - rv.ctime = ss.ctime; + rv.set_dev(0); + rv.set_ino(ss.ino); + rv.set_nlink(ss.nlink); + rv.set_mode(ss.mode); + rv.set_uid(ss.uid); + rv.set_gid(ss.gid); + rv.set_rdev(ss.rdev); + rv.set_size(ss.size); + rv.set_blocks(0); + rv.set_blksize(0); + rv.set_atime(ss.atime); + rv.set_mtime(ss.mtime); + rv.set_ctime(ss.ctime); return rv; } diff --git a/test/tool_main_test.cpp b/test/tool_main_test.cpp index f62cd2fd..7b7284f4 100644 --- a/test/tool_main_test.cpp +++ b/test/tool_main_test.cpp @@ -375,9 +375,9 @@ std::set get_all_fs_times(filesystem_v2 const& fs) { std::set times; fs.walk([&](auto const& e) { auto st = fs.getattr(e.inode()); - times.insert(st.atime); - times.insert(st.ctime); - times.insert(st.mtime); + times.insert(st.atime()); + times.insert(st.ctime()); + times.insert(st.mtime()); }); return times; } @@ -386,7 +386,7 @@ std::set get_all_fs_uids(filesystem_v2 const& fs) { std::set uids; fs.walk([&](auto const& e) { auto st = fs.getattr(e.inode()); - uids.insert(st.uid); + uids.insert(st.uid()); }); return uids; } @@ -395,7 +395,7 @@ std::set get_all_fs_gids(filesystem_v2 const& fs) { std::set gids; fs.walk([&](auto const& e) { auto st = fs.getattr(e.inode()); - gids.insert(st.gid); + gids.insert(st.gid()); }); return gids; } @@ -877,7 +877,7 @@ TEST(mkdwarfs_test, metadata_path) { fs.walk([&](auto e) { auto stat = fs.getattr(e.inode()); if (stat.is_regular_file()) { - entries.emplace(stat.size, e); + entries.emplace(stat.size(), e); } }); @@ -1008,7 +1008,7 @@ TEST(mkdwarfs_test, metadata_specials) { EXPECT_FALSE(ec); EXPECT_TRUE(stat.is_device()); - EXPECT_EQ(77, stat.rdev); + EXPECT_EQ(77, stat.rdev()); } TEST(mkdwarfs_test, metadata_time_resolution) { @@ -1032,9 +1032,9 @@ TEST(mkdwarfs_test, metadata_time_resolution) { std::error_code ec; auto stat = fs.getattr(*iv, ec); EXPECT_FALSE(ec); - EXPECT_EQ(3300, stat.atime); - EXPECT_EQ(2220, stat.mtime); - EXPECT_EQ(1080, stat.ctime); + EXPECT_EQ(3300, stat.atime()); + EXPECT_EQ(2220, stat.mtime()); + EXPECT_EQ(1080, stat.ctime()); } TEST(mkdwarfs_test, metadata_readdir) { @@ -2561,8 +2561,8 @@ TEST_P(map_file_error_test, delayed) { ASSERT_TRUE(small_link2); EXPECT_EQ(large_link1->inode_num(), large_link2->inode_num()); EXPECT_EQ(small_link1->inode_num(), small_link2->inode_num()); - EXPECT_EQ(0, fs.getattr(*large_link1).size); - EXPECT_EQ(0, fs.getattr(*small_link1).size); + EXPECT_EQ(0, fs.getattr(*large_link1).size()); + EXPECT_EQ(0, fs.getattr(*small_link1).size()); } std::unordered_map actual_files; @@ -2571,7 +2571,7 @@ TEST_P(map_file_error_test, delayed) { if (iv.is_regular_file()) { std::string data; auto stat = fs.getattr(iv); - data.resize(stat.size); + data.resize(stat.size()); ASSERT_EQ(data.size(), fs.read(iv.inode_num(), data.data(), data.size())); ASSERT_TRUE(actual_files.emplace(dev.fs_path(), std::move(data)).second); } @@ -2703,10 +2703,10 @@ TEST(block_cache, sequential_access_detector) { ASSERT_TRUE(iv); ASSERT_TRUE(iv->is_regular_file()); auto st = fs.getattr(*iv); - ASSERT_EQ(data.size(), st.size); + ASSERT_EQ(data.size(), st.size()); std::string buffer; buffer.resize(data.size()); - auto nread = fs.read(iv->inode_num(), buffer.data(), st.size); + auto nread = fs.read(iv->inode_num(), buffer.data(), st.size()); EXPECT_EQ(data.size(), nread); EXPECT_EQ(data, buffer); } @@ -2808,8 +2808,8 @@ TEST(file_scanner, large_file_handling) { ASSERT_TRUE(iv) << i; auto st = fs.getattr(*iv); std::string buffer; - buffer.resize(st.size); - auto nread = fs.read(iv->inode_num(), buffer.data(), st.size); + buffer.resize(st.size()); + auto nread = fs.read(iv->inode_num(), buffer.data(), st.size()); EXPECT_EQ(data[i].size(), nread) << i; EXPECT_EQ(data[i], buffer) << i; } diff --git a/test/tools_test.cpp b/test/tools_test.cpp index 8d2490a2..64745b91 100644 --- a/test/tools_test.cpp +++ b/test/tools_test.cpp @@ -772,8 +772,8 @@ bool check_readonly(fs::path const& p, bool readonly) { size_t num_hardlinks(fs::path const& p) { #ifdef _WIN32 - auto stat = dwarfs::make_file_stat(p); - return stat.nlink; + dwarfs::file_stat stat(p); + return stat.nlink(); #else return fs::hard_link_count(p); #endif