From: Edwin Rodriguez Date: Thu, 18 Jun 2026 14:14:43 +0000 (-0400) Subject: cephfs-tool: Add filesystem statistics reporting before and after benchmark runs X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c8d115ee5d8f780d41764154dcce211e59e401fa;p=ceph.git cephfs-tool: Add filesystem statistics reporting before and after benchmark runs Added filesystem stats reporting to cephfs-tool.cc. Helper functions • fetch_statvfs() — uses ceph_ll_statfs on the root inode when --async-io is set, otherwise ceph_statfs on mount_root • report_fs_stats() — prints and optionally JSON-encodes: • Total / free blocks • File count When it runs • Before the iteration loop (after the bench directory is created) • After all iterations finish (before the final report and optional cleanup) Console output example Filesystem statistics (before iterations): Total blocks: ... Free blocks: ... Files: ... JSON output (when --json is used) adds a filesystem_stats section with before and after objects containing the same fields. Fixes: https://tracker.ceph.com/issues/76183 Signed-off-by: Edwin Rodriguez --- diff --git a/src/tools/cephfs/cephfs-tool.cc b/src/tools/cephfs/cephfs-tool.cc index 8c6af13bb8a4..aa393cb55b34 100644 --- a/src/tools/cephfs/cephfs-tool.cc +++ b/src/tools/cephfs/cephfs-tool.cc @@ -40,6 +40,7 @@ // Standard Public Ceph API #include #include +#include #include // Boost Program Options @@ -1221,6 +1222,54 @@ print_statistics( } } +static void dump_statvfs_json(ceph::Formatter* f, const struct statvfs& st) +{ + f->dump_unsigned("block_size", st.f_bsize); + f->dump_unsigned("total_blocks", st.f_blocks); + f->dump_unsigned("free_blocks", st.f_bfree); + f->dump_unsigned("files", st.f_files); +} + +static int fetch_statvfs(struct ceph_mount_info* cmount, + const BenchConfig& config, + struct statvfs* stbuf) +{ + if (config.async_io) { + Inode* root = nullptr; + int rc = ceph_ll_lookup_root(cmount, &root); + if (rc < 0) { + return rc; + } + return ceph_ll_statfs(cmount, root, stbuf); + } + return ceph_statfs(cmount, config.mount_root.c_str(), stbuf); +} + +static void report_fs_stats(const char* phase, + struct ceph_mount_info* cmount, + const BenchConfig& config, + ceph::Formatter* json_formatter) +{ + struct statvfs stbuf = {}; + int rc = fetch_statvfs(cmount, config, &stbuf); + if (rc < 0) { + cerr << "Failed to get filesystem stats (" << phase << "): " + << strerror(-rc) << std::endl; + return; + } + + cout << "\nFilesystem statistics (" << phase << " iterations):" << std::endl; + cout << " Total blocks: " << stbuf.f_blocks << std::endl; + cout << " Free blocks: " << stbuf.f_bfree << std::endl; + cout << " Files: " << stbuf.f_files << std::endl; + + if (json_formatter) { + json_formatter->open_object_section(phase); + dump_statvfs_json(json_formatter, stbuf); + json_formatter->close_section(); + } +} + // Helper to check for errors and print them bool check_and_report_errors(const std::atomic& stop_signal, const std::vector& outputs) { @@ -1366,6 +1415,11 @@ int do_bench(BenchConfig& config) { int files_per_thread = config.num_files / config.num_threads; int remainder = config.num_files % config.num_threads; + if (json_formatter) { + json_formatter->open_object_section("filesystem_stats"); + } + report_fs_stats("before", shared_cmount, config, json_formatter.get()); + std::vector write_mbps; std::vector write_fps; std::vector read_mbps; @@ -1641,6 +1695,11 @@ int do_bench(BenchConfig& config) { } } + report_fs_stats("after", shared_cmount, config, json_formatter.get()); + if (json_formatter) { + json_formatter->close_section(); // filesystem_stats + } + cout << std::endl << std::endl << "*** Final Report ***" << std::endl; if (json_formatter) {