Output more useful file system info with dwarfsck

This commit is contained in:
Marcus Holland-Moritz 2021-10-26 09:30:08 +02:00
parent 263890c6f1
commit 7345578827
4 changed files with 62 additions and 18 deletions

View File

@ -114,6 +114,14 @@ struct section_header_v2 {
void dump(std::ostream& os) const;
};
struct filesystem_info {
uint64_t block_count{0};
uint64_t compressed_block_size{0};
uint64_t uncompressed_block_size{0};
uint64_t compressed_metadata_size{0};
uint64_t uncompressed_metadata_size{0};
};
bool is_valid_compression_type(compression_type type);
bool is_valid_section_type(section_type type);

View File

@ -48,6 +48,8 @@ class logger;
struct metadata_options;
struct filesystem_info;
namespace thrift::metadata {
class metadata;
}
@ -63,9 +65,9 @@ class metadata_v2 {
metadata_v2& operator=(metadata_v2&&) = default;
void
dump(std::ostream& os, int detail_level,
dump(std::ostream& os, int detail_level, filesystem_info const& fsinfo,
std::function<void(const std::string&, uint32_t)> const& icb) const {
impl_->dump(os, detail_level, icb);
impl_->dump(os, detail_level, fsinfo, icb);
}
folly::dynamic as_dynamic() const { return impl_->as_dynamic(); }
@ -141,7 +143,7 @@ class metadata_v2 {
virtual ~impl() = default;
virtual void dump(
std::ostream& os, int detail_level,
std::ostream& os, int detail_level, filesystem_info const& fsinfo,
std::function<void(const std::string&, uint32_t)> const& icb) const = 0;
virtual folly::dynamic as_dynamic() const = 0;

View File

@ -191,6 +191,14 @@ class filesystem_parser {
using section_map = std::unordered_map<section_type, fs_section>;
size_t
get_uncompressed_section_size(std::shared_ptr<mmif> mm, fs_section const& sec) {
std::vector<uint8_t> tmp;
block_decompressor bd(sec.compression(), mm->as<uint8_t>(sec.start()),
sec.length(), tmp);
return bd.uncompressed_size();
}
folly::ByteRange
get_section_data(std::shared_ptr<mmif> mm, fs_section const& section,
std::vector<uint8_t>& buffer, bool force_buffer) {
@ -297,6 +305,7 @@ class filesystem_ final : public filesystem_v2::impl {
inode_reader_v2 ir_;
std::vector<uint8_t> meta_buffer_;
std::optional<folly::ByteRange> header_;
filesystem_info fsinfo_;
};
template <typename LoggerPolicy>
@ -317,6 +326,9 @@ filesystem_<LoggerPolicy>::filesystem_(logger& lgr, std::shared_ptr<mmif> mm,
<< s->length() << " bytes]";
if (s->type() == section_type::BLOCK) {
cache.insert(*s);
++fsinfo_.block_count;
fsinfo_.compressed_block_size += s->length();
fsinfo_.uncompressed_block_size += get_uncompressed_section_size(mm_, *s);
} else {
if (!s->check_fast(*mm_)) {
DWARFS_THROW(runtime_error, "checksum error in section: " + s->name());
@ -325,6 +337,12 @@ filesystem_<LoggerPolicy>::filesystem_(logger& lgr, std::shared_ptr<mmif> mm,
if (!sections.emplace(s->type(), *s).second) {
DWARFS_THROW(runtime_error, "duplicate section: " + s->name());
}
if (s->type() == section_type::METADATA_V2) {
fsinfo_.compressed_metadata_size += s->length();
fsinfo_.uncompressed_metadata_size +=
get_uncompressed_section_size(mm_, *s);
}
}
}
@ -344,9 +362,11 @@ filesystem_<LoggerPolicy>::filesystem_(logger& lgr, std::shared_ptr<mmif> mm,
template <typename LoggerPolicy>
void filesystem_<LoggerPolicy>::dump(std::ostream& os, int detail_level) const {
meta_.dump(os, detail_level, [&](const std::string& indent, uint32_t inode) {
meta_.dump(os, detail_level, fsinfo_,
[&](const std::string& indent, uint32_t inode) {
if (auto chunks = meta_.get_chunks(inode)) {
os << indent << chunks->size() << " chunks in inode " << inode << "\n";
os << indent << chunks->size() << " chunks in inode " << inode
<< "\n";
ir_.dump(os, indent + " ", *chunks);
} else {
LOG_ERROR << "error reading chunks for inode " << inode;
@ -612,14 +632,12 @@ int filesystem_v2::identify(logger& lgr, std::shared_ptr<mmif> mm,
try {
auto s = sf.get();
std::vector<uint8_t> tmp;
block_decompressor bd(s.compression(), mm->as<uint8_t>(s.start()),
s.length(), tmp);
float compression_ratio = float(s.length()) / bd.uncompressed_size();
auto uncompressed_size = get_uncompressed_section_size(mm, s);
float compression_ratio = float(s.length()) / uncompressed_size;
if (detail_level > 2) {
os << "SECTION " << s.description()
<< ", blocksize=" << bd.uncompressed_size()
<< ", blocksize=" << uncompressed_size
<< ", ratio=" << fmt::format("{:.2f}%", 100.0 * compression_ratio)
<< std::endl;
}

View File

@ -48,6 +48,7 @@
#include <fsst.h>
#include "dwarfs/error.h"
#include "dwarfs/fstypes.h"
#include "dwarfs/logger.h"
#include "dwarfs/metadata_v2.h"
#include "dwarfs/options.h"
@ -375,7 +376,7 @@ class metadata_ final : public metadata_v2::impl {
}
}
void dump(std::ostream& os, int detail_level,
void dump(std::ostream& os, int detail_level, filesystem_info const& fsinfo,
std::function<void(const std::string&, uint32_t)> const& icb)
const override;
@ -795,7 +796,7 @@ void metadata_<LoggerPolicy>::dump(
template <typename LoggerPolicy>
void metadata_<LoggerPolicy>::dump(
std::ostream& os, int detail_level,
std::ostream& os, int detail_level, filesystem_info const& fsinfo,
std::function<void(const std::string&, uint32_t)> const& icb) const {
struct ::statvfs stbuf;
statvfs(&stbuf);
@ -814,9 +815,24 @@ void metadata_<LoggerPolicy>::dump(
if (detail_level > 0) {
os << "block size: " << size_with_unit(stbuf.f_bsize) << std::endl;
os << "block count: " << fsinfo.block_count << std::endl;
os << "inode count: " << stbuf.f_files << std::endl;
os << "original filesystem size: " << size_with_unit(stbuf.f_blocks)
<< std::endl;
os << "compressed block size: "
<< size_with_unit(fsinfo.compressed_block_size)
<< fmt::format(" ({0:.2f}%)", (100.0 * fsinfo.compressed_block_size) /
fsinfo.uncompressed_block_size)
<< std::endl;
os << "uncompressed block size: "
<< size_with_unit(fsinfo.uncompressed_block_size) << std::endl;
os << "compressed metadata size: "
<< size_with_unit(fsinfo.compressed_metadata_size)
<< fmt::format(" ({0:.2f}%)", (100.0 * fsinfo.compressed_metadata_size) /
fsinfo.uncompressed_metadata_size)
<< std::endl;
os << "uncompressed metadata size: "
<< size_with_unit(fsinfo.uncompressed_metadata_size) << std::endl;
if (auto opt = meta_.options()) {
std::vector<std::string> options;
auto boolopt = [&](auto const& name, bool value) {