]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/epm: Verify available segments on mkfs/mount
authorMatan Breizman <mbreizma@redhat.com>
Mon, 22 Sep 2025 11:51:21 +0000 (11:51 +0000)
committerMatan Breizman <mbreizma@redhat.com>
Mon, 29 Sep 2025 11:18:53 +0000 (11:18 +0000)
First addressed by 3b9632696a5e0b4e02c8ac32ba8ab8b00ee7a005.
However, the mentioned commit should also
consider veryfing available empty segment num when mounting.

When mounting (Both for store mkfs/mount) the (Segmented) AsyncCleaner:
1) Mark all previous OPEN segemnts as closed (See: init_closed)
2) Open/Allocate EMPTY segments to all new writers
3) Run background segments cleaner

Meaning, all previously OPEN segments would be
closed when moutning *before* the cleaner could start running.

Since we don't actually wait/block segments openings
same as we would on runtime IOs -
With limited device sizes, this could result in not enough empty
segments to open.

Fixes: https://tracker.ceph.com/issues/72484
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
src/crimson/os/seastore/extent_placement_manager.cc

index 110ecae411b56f74d437b735413a3a6353c43613..7a11dc7cf2e55df798ce9ab3c2caa4dd3ee1d803 100644 (file)
@@ -450,6 +450,18 @@ ExtentPlacementManager::open_for_write()
   LOG_PREFIX(ExtentPlacementManager::open_for_write);
   DEBUG("started with {} devices", num_devices);
   ceph_assert(primary_device != nullptr);
+  auto total_writers_num =
+    data_writers_by_gen.size() + md_writers_by_gen.size();
+  if (auto segments = background_process.get_segments_info();
+      segments && // Only valid for SegmentCleaner
+      std::cmp_less(segments->get_num_empty(), total_writers_num)) {
+    ERROR("Not enough EMPTY segments! "
+          "Consider increasing the device size (needed {} got {})",
+          total_writers_num, segments->get_num_empty());
+    // TODO: open_ertr should be expanded to enospc
+    co_await open_ertr::future<>(crimson::ct_error::input_output_error::make());
+  }
+
   DEBUG("opening DATA writers", num_devices);
   for (auto& writer : data_writers_by_gen) {
     if (writer) {