diff --git a/src/llfs/page_recycler.cpp b/src/llfs/page_recycler.cpp index 232fb58..f2fd396 100644 --- a/src/llfs/page_recycler.cpp +++ b/src/llfs/page_recycler.cpp @@ -235,7 +235,7 @@ auto PageRecycler::metrics_export() -> MetricsExported& static MetricsExported& metrics_ = [&]() -> MetricsExported& { static MetricsExported metrics_; - LOG(INFO) << "Registering PageRecycler metrics..."; + LLFS_VLOG(1) << "Registering PageRecycler metrics..."; const auto metric_name = [](std::string_view property) { return batt::to_string("PageRecycler_", property); }; @@ -335,7 +335,7 @@ StatusOr PageRecycler::recycle_pages( return this->wal_device_->slot_range(LogReadMode::kDurable).upper_bound; } - // Check to see if we have already seen this or newer request. + // Check to see if we have already seen this or any newer request. // if (this->largest_offset_as_unique_identifier_ >= offset_as_unique_identifier) { this->metrics_export().page_id_deletion_reissue.fetch_add(1); diff --git a/src/llfs/page_recycler.test.cpp b/src/llfs/page_recycler.test.cpp index 36eb5b1..0977bff 100644 --- a/src/llfs/page_recycler.test.cpp +++ b/src/llfs/page_recycler.test.cpp @@ -366,7 +366,9 @@ class FakePageDeleter : public PageDeleter // Recursively recycle any newly dead pages. If we try to recycle the same page multiple // times, that is OK, since PageIds are never reused. // - result = this->test_->recycler_->recycle_pages(as_slice(dead_pages), caller_slot, // + std::lock_guard lock(this->recycle_pages_mutex_); + result = this->test_->recycler_->recycle_pages(as_slice(dead_pages), + this->get_and_incr_unique_offset(), // &recycle_grant, depth + 1); BATT_REQUIRE_OK(result); @@ -412,10 +414,28 @@ class FakePageDeleter : public PageDeleter this->recursive_recycle_events_.push(failure).IgnoreError(); } + slot_offset_type get_and_incr_unique_offset() + { + return this->unique_offset_++; + } + + void lock_mutex() + { + recycle_pages_mutex_.lock(); + } + + void unlock_mutex() + { + recycle_pages_mutex_.unlock(); + } + PageRecyclerTest* test_; std::unordered_map> current_slot_; batt::Queue> recursive_recycle_events_; + + slot_offset_type unique_offset_{1}; + std::mutex recycle_pages_mutex_; }; TEST_F(PageRecyclerTest, CrashRecovery) @@ -435,7 +455,7 @@ TEST_F(PageRecyclerTest, CrashRecovery) void PageRecyclerTest::run_crash_recovery_test() { - const usize fake_page_count = 256; + const usize fake_page_count = 190; const u32 max_branching_factor = 8; const auto options = llfs::PageRecyclerOptions{} // @@ -500,7 +520,9 @@ void PageRecyclerTest::run_crash_recovery_test() const std::array to_recycle = {root_id}; BATT_DEBUG_INFO("Test - recycle_pages"); - StatusOr recycle_status = recycler.recycle_pages(to_recycle, 0); + std::lock_guard lock(fake_deleter.recycle_pages_mutex_); + StatusOr recycle_status = + recycler.recycle_pages(to_recycle, fake_deleter.get_and_incr_unique_offset()); if (!recycle_status.ok()) { failed = true; break;