Skip to content

Commit

Permalink
file: add file_system_space
Browse files Browse the repository at this point in the history
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 <bhalevy@scylladb.com>
  • Loading branch information
bhalevy authored and avikivity committed Dec 24, 2024
1 parent 84e9889 commit a9bef53
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/seastar/core/reactor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ public:
return file_accessible(pathname, access_flags::exists);
}
future<fs_type> file_system_at(std::string_view pathname) noexcept;
future<std::filesystem::space_info> file_system_space(std::string_view pathname) noexcept;
future<struct statvfs> 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;
Expand Down
5 changes: 5 additions & 0 deletions include/seastar/core/seastar.hh
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ future<uint64_t> fs_avail(std::string_view name) noexcept;
future<uint64_t> 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<std::filesystem::space_info> file_system_space(std::string_view name) noexcept;

namespace experimental {
/// \defgroup interprocess-module Interprocess Communication
///
Expand Down
11 changes: 11 additions & 0 deletions src/core/reactor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2263,6 +2263,17 @@ reactor::fstatfs(int fd) noexcept {
});
}

future<std::filesystem::space_info>
reactor::file_system_space(std::string_view pathname) noexcept {
auto sr = co_await _thread_pool->submit<syscall_result_extra<std::filesystem::space_info>>([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<struct statvfs>
reactor::statvfs(std::string_view pathname) noexcept {
// Allocating memory for a sstring can throw, hence the futurize_invoke
Expand Down
4 changes: 4 additions & 0 deletions src/util/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ future<uint64_t> fs_free(std::string_view name) noexcept {
});
}

future<std::filesystem::space_info> file_system_space(std::string_view name) noexcept {
return engine().file_system_space(name);
}

future<stat_data> file_stat(std::string_view name, follow_symlink follow) noexcept {
return engine().file_stat(name, follow);
}
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/file_io_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
* Copyright (C) 2014-2015 Cloudius Systems, Ltd.
*/

#include <filesystem>

#include <seastar/testing/random.hh>
#include <seastar/testing/test_case.hh>
#include <seastar/testing/thread_test_case.hh>
#include <seastar/testing/test_runner.hh>

#include <seastar/core/reactor.hh>
#include <seastar/core/seastar.hh>
#include <seastar/core/semaphore.hh>
#include <seastar/core/condition-variable.hh>
Expand Down Expand Up @@ -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);
});
}

0 comments on commit a9bef53

Please sign in to comment.