From c80e45146632c2d49baa2d68500d38b3d60fd769 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Thu, 7 Nov 2024 15:10:34 +0200 Subject: [PATCH] file: add file_system_space Return space_info for the filesystem identified by the given file name. space_info provides simpler and standard space information about the filesystem, in contrast to the posix statvfs which requires knowledge about the how to convert f_block to bytes by multiplying by f_frsize. Signed-off-by: Benny Halevy --- include/seastar/core/reactor.hh | 1 + include/seastar/core/seastar.hh | 5 +++++ src/core/reactor.cc | 11 +++++++++++ src/util/file.cc | 4 ++++ tests/unit/file_io_test.cc | 16 ++++++++++++++++ 5 files changed, 37 insertions(+) diff --git a/include/seastar/core/reactor.hh b/include/seastar/core/reactor.hh index 4d3d992eaa..8d63b8b3f2 100644 --- a/include/seastar/core/reactor.hh +++ b/include/seastar/core/reactor.hh @@ -487,6 +487,7 @@ public: return file_accessible(pathname, access_flags::exists); } future file_system_at(std::string_view pathname) noexcept; + future file_system_space(std::string_view pathname) noexcept; future statvfs(std::string_view pathname) noexcept; future<> remove_file(std::string_view pathname) noexcept; future<> rename_file(std::string_view old_pathname, std::string_view new_pathname) noexcept; diff --git a/include/seastar/core/seastar.hh b/include/seastar/core/seastar.hh index e5431de841..73d32a8cd3 100644 --- a/include/seastar/core/seastar.hh +++ b/include/seastar/core/seastar.hh @@ -445,6 +445,11 @@ future fs_avail(std::string_view name) noexcept; future fs_free(std::string_view name) noexcept; /// @} +/// Return filesystem-wide space_info where a file is located. +/// +/// \param name name of the file in the filesystem to inspect +future file_system_space(std::string_view name) noexcept; + namespace experimental { /// \defgroup interprocess-module Interprocess Communication /// diff --git a/src/core/reactor.cc b/src/core/reactor.cc index ac33906b6d..d8e189c756 100644 --- a/src/core/reactor.cc +++ b/src/core/reactor.cc @@ -2263,6 +2263,17 @@ reactor::fstatfs(int fd) noexcept { }); } +future +reactor::file_system_space(std::string_view pathname) noexcept { + auto sr = co_await _thread_pool->submit>([path = std::filesystem::path(pathname)] { + std::error_code ec; + auto si = std::filesystem::space(path, ec); + return wrap_syscall(ec.value(), si); + }); + sr.throw_fs_exception_if_error("std::filesystem::space failed", sstring(pathname)); + co_return sr.extra; +} + future reactor::statvfs(std::string_view pathname) noexcept { // Allocating memory for a sstring can throw, hence the futurize_invoke diff --git a/src/util/file.cc b/src/util/file.cc index 58d62428aa..d280860ad7 100644 --- a/src/util/file.cc +++ b/src/util/file.cc @@ -128,6 +128,10 @@ future fs_free(std::string_view name) noexcept { }); } +future file_system_space(std::string_view name) noexcept { + return engine().file_system_space(name); +} + future file_stat(std::string_view name, follow_symlink follow) noexcept { return engine().file_stat(name, follow); } diff --git a/tests/unit/file_io_test.cc b/tests/unit/file_io_test.cc index 29be2a670a..3bce589bf3 100644 --- a/tests/unit/file_io_test.cc +++ b/tests/unit/file_io_test.cc @@ -19,11 +19,14 @@ * Copyright (C) 2014-2015 Cloudius Systems, Ltd. */ +#include + #include #include #include #include +#include #include #include #include @@ -947,3 +950,16 @@ SEASTAR_TEST_CASE(test_oversized_io_works) { BOOST_REQUIRE((size_t)std::count_if(buf.get(), buf.get() + buf_size, [](auto x) { return x == 'a'; }) == buf_size); }); } + +SEASTAR_TEST_CASE(test_file_system_space) { + return tmp_dir::do_with_thread([] (tmp_dir& t) { + const auto& name = t.get_path().native(); + auto st = engine().statvfs(name).get(); + auto si = file_system_space(name).get(); + + BOOST_REQUIRE_EQUAL(st.f_blocks * st.f_frsize, si.capacity); + BOOST_REQUIRE_LT(si.free, si.capacity); + BOOST_REQUIRE_LT(si.available, si.capacity); + BOOST_REQUIRE_LE(si.available, si.free); + }); +}