From 2d9f09dcb686e6dabc27026b0b8571ff72afe1a0 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Wed, 24 Feb 2021 01:32:52 +0300 Subject: [PATCH] Attempt forced trim when stopping an overrun flusher Fixes a rare hang happening in the event of journal space running out without new work to do for flushers except the current sector. The hang could be reproduced more or less consistently with very slow drives. --- blockstore_flush.cpp | 5 ++--- blockstore_journal.cpp | 10 ++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/blockstore_flush.cpp b/blockstore_flush.cpp index e4550e9a..db64fa15 100644 --- a/blockstore_flush.cpp +++ b/blockstore_flush.cpp @@ -223,6 +223,7 @@ bool journal_flusher_co::loop() resume_0: if (!flusher->flush_queue.size() || !flusher->dequeuing) { +stop_flusher: if (flusher->trim_wanted > 0 && flusher->journal_trim_counter > 0) { // Attempt forced trim @@ -327,9 +328,7 @@ resume_0: #ifdef BLOCKSTORE_DEBUG printf("No older flushes, stopping\n"); #endif - flusher->dequeuing = false; - wait_state = 0; - return true; + goto stop_flusher; } } } diff --git a/blockstore_journal.cpp b/blockstore_journal.cpp index 133d4227..2d6054f2 100644 --- a/blockstore_journal.cpp +++ b/blockstore_journal.cpp @@ -81,7 +81,8 @@ int blockstore_journal_check_t::check_available(blockstore_op_t *op, int entries } // In fact, it's even more rare than "ran out of journal space", so print a warning printf( - "Ran out of journal sector buffers: %d/%lu buffers used (%d dirty), next buffer (%ld) is %s and flushed %lu times\n", + "Ran out of journal sector buffers: %d/%lu buffers used (%d dirty), next buffer (%ld)" + " is %s and flushed %lu times. Consider increasing \'journal_sector_buffer_count\'\n", used, bs->journal.sector_count, dirty, next_sector, bs->journal.sector_info[next_sector].dirty ? "dirty" : "not dirty", bs->journal.sector_info[next_sector].flush_count @@ -103,11 +104,8 @@ int blockstore_journal_check_t::check_available(blockstore_op_t *op, int entries { // No space in the journal. Wait until used_start changes. printf( - "Ran out of journal space (free space: %lu bytes, sectors to write: %d)\n", - (bs->journal.next_free >= bs->journal.used_start - ? bs->journal.len-bs->journal.block_size - (bs->journal.next_free-bs->journal.used_start) - : bs->journal.used_start - bs->journal.next_free), - sectors_to_write + "Ran out of journal space (used_start=%08lx, next_free=%08lx, dirty_start=%08lx)\n", + bs->journal.used_start, bs->journal.next_free, bs->journal.dirty_start ); PRIV(op)->wait_for = WAIT_JOURNAL; bs->flusher->request_trim();