mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-08 03:49:44 -04:00
refactor(file_stat): turn into proper object with hidden data
This commit is contained in:
parent
bbd8306a13
commit
964a4f49e6
@ -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<std::filesystem::perms>;
|
||||
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<posix_file_type::value>(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 <typename T>
|
||||
void copy_to(T* out) const {
|
||||
copy_to_impl<true>(out);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void copy_to_without_block_info(T* out) const {
|
||||
copy_to_impl<false>(out);
|
||||
}
|
||||
|
||||
private:
|
||||
template <bool with_block_info = true, typename T>
|
||||
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 <bool with_block_info = true, typename T>
|
||||
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
|
||||
|
@ -45,7 +45,6 @@ class logger;
|
||||
struct getattr_options;
|
||||
struct metadata_options;
|
||||
struct filesystem_info;
|
||||
struct file_stat;
|
||||
struct vfs_stat;
|
||||
|
||||
class performance_monitor;
|
||||
|
@ -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<uint64_t>(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<uint64_t>(info.nFileIndexHigh) << 32) +
|
||||
info.nFileIndexLow;
|
||||
rv.nlink = info.nNumberOfLinks;
|
||||
valid_fields_ |= file_stat::ino_valid | file_stat::nlink_valid;
|
||||
ino_ = (static_cast<uint64_t>(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<posix_file_type::value>(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
|
||||
|
@ -354,9 +354,9 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
||||
|
||||
::memset(&st, 0, sizeof(st));
|
||||
#ifdef _WIN32
|
||||
copy_file_stat<false>(&st, stbuf);
|
||||
stbuf.copy_to_without_block_info(&st);
|
||||
#else
|
||||
copy_file_stat<true>(&st, stbuf);
|
||||
stbuf.copy_to(&st);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -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
|
||||
|
@ -1540,9 +1540,7 @@ metadata_<LoggerPolicy>::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_<LoggerPolicy>::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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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<double>::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;
|
||||
|
@ -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<char> buf(stbuf.size);
|
||||
std::vector<char> buf(stbuf.size());
|
||||
int fh = fs.open(inode_data);
|
||||
fs.read(fh, buf.data(), buf.size());
|
||||
} catch (std::exception const& e) {
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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<size_t>(stat.size / 2)) {
|
||||
offset += rng() % (stat.size - (offset + size));
|
||||
size = rng() % (stat.size - offset);
|
||||
offset + size < static_cast<size_t>(stat.size() / 2)) {
|
||||
offset += rng() % (stat.size() - (offset + size));
|
||||
size = rng() % (stat.size() - offset);
|
||||
reqs.push_back({iv, offset, size});
|
||||
}
|
||||
}
|
||||
|
@ -807,9 +807,8 @@ std::vector<std::string> 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<char> buf(st.size);
|
||||
auto rv = fs.read(inode, &buf[0], st.size, ec);
|
||||
std::vector<char> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<char> buf(st.size);
|
||||
auto rv = fs.read(inode, &buf[0], st.size, ec);
|
||||
std::vector<char> 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<char> buf(st.size);
|
||||
auto rv = fs.read(inode, &buf[0], st.size, ec);
|
||||
std::vector<char> 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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -375,9 +375,9 @@ std::set<uint64_t> get_all_fs_times(filesystem_v2 const& fs) {
|
||||
std::set<uint64_t> 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<uint64_t> get_all_fs_uids(filesystem_v2 const& fs) {
|
||||
std::set<uint64_t> 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<uint64_t> get_all_fs_gids(filesystem_v2 const& fs) {
|
||||
std::set<uint64_t> 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<fs::path, std::string, fs_path_hash> 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user