diff --git a/include/dwarfs/reader/filesystem_v2.h b/include/dwarfs/reader/filesystem_v2.h index cb401985..cd996ea7 100644 --- a/include/dwarfs/reader/filesystem_v2.h +++ b/include/dwarfs/reader/filesystem_v2.h @@ -320,6 +320,10 @@ class filesystem_v2 { return impl_->get_inode_info(entry); } + nlohmann::json get_inode_info(inode_view entry, size_t max_chunks) const { + return impl_->get_inode_info(entry, max_chunks); + } + std::vector get_all_block_categories() const { return impl_->get_all_block_categories(); } @@ -426,6 +430,8 @@ class filesystem_v2 { virtual bool has_symlinks() const = 0; virtual history const& get_history() const = 0; virtual nlohmann::json get_inode_info(inode_view entry) const = 0; + virtual nlohmann::json + get_inode_info(inode_view entry, size_t max_chunks) const = 0; virtual std::vector get_all_block_categories() const = 0; virtual std::vector get_all_uids() const = 0; virtual std::vector get_all_gids() const = 0; diff --git a/include/dwarfs/reader/internal/metadata_v2.h b/include/dwarfs/reader/internal/metadata_v2.h index 9635149e..370d5f2d 100644 --- a/include/dwarfs/reader/internal/metadata_v2.h +++ b/include/dwarfs/reader/internal/metadata_v2.h @@ -151,8 +151,8 @@ class metadata_v2 { bool has_symlinks() const { return impl_->has_symlinks(); } - nlohmann::json get_inode_info(inode_view iv) const { - return impl_->get_inode_info(iv); + nlohmann::json get_inode_info(inode_view iv, size_t max_chunks) const { + return impl_->get_inode_info(iv, max_chunks); } std::optional get_block_category(size_t block_number) const { @@ -229,7 +229,8 @@ class metadata_v2 { virtual bool has_symlinks() const = 0; - virtual nlohmann::json get_inode_info(inode_view iv) const = 0; + virtual nlohmann::json + get_inode_info(inode_view iv, size_t max_chunks) const = 0; virtual std::optional get_block_category(size_t block_number) const = 0; diff --git a/src/reader/filesystem_v2.cpp b/src/reader/filesystem_v2.cpp index ae816b94..e90c62aa 100644 --- a/src/reader/filesystem_v2.cpp +++ b/src/reader/filesystem_v2.cpp @@ -290,7 +290,11 @@ class filesystem_ final : public filesystem_v2::impl { bool has_symlinks() const override { return meta_.has_symlinks(); } history const& get_history() const override { return history_; } nlohmann::json get_inode_info(inode_view entry) const override { - return meta_.get_inode_info(entry); + return meta_.get_inode_info(entry, std::numeric_limits::max()); + } + nlohmann::json + get_inode_info(inode_view entry, size_t max_chunks) const override { + return meta_.get_inode_info(entry, max_chunks); } std::vector get_all_block_categories() const override { return meta_.get_all_block_categories(); diff --git a/src/reader/internal/metadata_v2.cpp b/src/reader/internal/metadata_v2.cpp index ed05bf09..235a8621 100644 --- a/src/reader/internal/metadata_v2.cpp +++ b/src/reader/internal/metadata_v2.cpp @@ -529,7 +529,8 @@ class metadata_ final : public metadata_v2::impl { bool has_symlinks() const override { return !meta_.symlink_table().empty(); } - nlohmann::json get_inode_info(inode_view iv) const override; + nlohmann::json + get_inode_info(inode_view iv, size_t max_chunks) const override; std::optional get_block_category(size_t block_number) const override; @@ -1844,7 +1845,9 @@ metadata_::get_chunks(int inode, std::error_code& ec) const { } template -nlohmann::json metadata_::get_inode_info(inode_view iv) const { +nlohmann::json +metadata_::get_inode_info(inode_view iv, + size_t max_chunks) const { nlohmann::json obj; if (iv.is_regular_file()) { @@ -1854,16 +1857,20 @@ nlohmann::json metadata_::get_inode_info(inode_view iv) const { DWARFS_CHECK(!ec, fmt::format("get_chunk_range({}): {}", iv.inode_num(), ec.message())); - for (auto const& chunk : chunk_range) { - nlohmann::json& chk = obj["chunks"].emplace_back(); + if (chunk_range.size() <= max_chunks) { + for (auto const& chunk : chunk_range) { + nlohmann::json& chk = obj["chunks"].emplace_back(); - chk["block"] = chunk.block(); - chk["offset"] = chunk.offset(); - chk["size"] = chunk.size(); + chk["block"] = chunk.block(); + chk["offset"] = chunk.offset(); + chk["size"] = chunk.size(); - if (auto catname = get_block_category(chunk.block())) { - chk["category"] = catname.value(); + if (auto catname = get_block_category(chunk.block())) { + chk["category"] = catname.value(); + } } + } else { + obj["chunks"] = fmt::format("too many chunks ({})", chunk_range.size()); } } diff --git a/tools/src/dwarfs_main.cpp b/tools/src/dwarfs_main.cpp index 9bc07b50..01ab0c4d 100644 --- a/tools/src/dwarfs_main.cpp +++ b/tools/src/dwarfs_main.cpp @@ -149,6 +149,7 @@ namespace { constexpr size_t const kDefaultBlockSize{static_cast(512) << 10}; constexpr size_t const kDefaultSeqDetectorThreshold{4}; +constexpr size_t const kMaxInodeInfoChunks{8}; struct options { // std::string isn't standard-layout on MSVC @@ -952,7 +953,7 @@ int op_getxattr_common(LogProxy& log_, dwarfs_userdata& userdata, } if (name == inodeinfo_xattr) { - oss << userdata.fs.get_inode_info(*entry) << "\n"; + oss << userdata.fs.get_inode_info(*entry, kMaxInodeInfoChunks) << "\n"; } value = oss.str();