From b7e4d0c9bfade471442bbdf1cb151b5af7707f15 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 9 Jul 2023 01:13:30 +0300 Subject: [PATCH] Fix journal dirty_start position tracking and some debug prints Fixes two bugs found during HDD testing :-) 1) OSD crashed with "BUG: Attempt to overwrite used offset of the journal" during `fio -bs=900k -iodepth=128` test with 16 MB journal 2) OSD stalled during `fio -bs=512k -iodepth=128` test with 64 MB journal --- src/blockstore_flush.cpp | 8 +++++++- src/blockstore_flush.h | 1 + src/blockstore_rollback.cpp | 2 +- src/blockstore_write.cpp | 7 ++++++- tests/run_3osds.sh | 4 +++- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/blockstore_flush.cpp b/src/blockstore_flush.cpp index 7f72542a..2f656962 100644 --- a/src/blockstore_flush.cpp +++ b/src/blockstore_flush.cpp @@ -714,9 +714,15 @@ resume_1: return false; } } + if (new_trim_pos < bs->journal.used_start + ? (bs->journal.dirty_start >= bs->journal.used_start || bs->journal.dirty_start < new_trim_pos) + : (bs->journal.dirty_start >= bs->journal.used_start && bs->journal.dirty_start < new_trim_pos)) + { + bs->journal.dirty_start = new_trim_pos; + } bs->journal.used_start = new_trim_pos; #ifdef BLOCKSTORE_DEBUG - printf("Journal trimmed to %08lx (next_free=%08lx)\n", bs->journal.used_start, bs->journal.next_free); + printf("Journal trimmed to %08lx (next_free=%08lx dirty_start=%08lx)\n", bs->journal.used_start, bs->journal.next_free, bs->journal.dirty_start); #endif if (bs->journal.flush_journal && !flusher->flush_queue.size()) { diff --git a/src/blockstore_flush.h b/src/blockstore_flush.h index 7ff2f871..b1250bcd 100644 --- a/src/blockstore_flush.h +++ b/src/blockstore_flush.h @@ -103,6 +103,7 @@ public: journal_flusher_t(blockstore_impl_t *bs); ~journal_flusher_t(); void loop(); + bool is_trim_wanted() { return trim_wanted; } bool is_active(); void mark_trim_possible(); void request_trim(); diff --git a/src/blockstore_rollback.cpp b/src/blockstore_rollback.cpp index 29eaf4e0..8a2a2bc5 100644 --- a/src/blockstore_rollback.cpp +++ b/src/blockstore_rollback.cpp @@ -218,7 +218,7 @@ void blockstore_impl_t::erase_dirty(blockstore_dirty_db_t::iterator dirty_start, auto used = --journal.used_sectors[dirty_it->second.journal_sector]; #ifdef BLOCKSTORE_DEBUG printf( - "remove usage of journal offset %08lx by %lx:%lx v%lu (%d refs)\n", dirty_it->second.journal_sector, + "remove usage of journal offset %08lx by %lx:%lx v%lu (%lu refs)\n", dirty_it->second.journal_sector, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, used ); #endif diff --git a/src/blockstore_write.cpp b/src/blockstore_write.cpp index 74ada503..3231f245 100644 --- a/src/blockstore_write.cpp +++ b/src/blockstore_write.cpp @@ -661,8 +661,13 @@ void blockstore_impl_t::release_journal_sectors(blockstore_op_t *op) uint64_t s = PRIV(op)->min_flushed_journal_sector; while (1) { - if (s != (1+journal.cur_sector) && journal.sector_info[s-1].flush_count == 0) + if (!journal.sector_info[s-1].dirty && journal.sector_info[s-1].flush_count == 0) { + if (s == (1+journal.cur_sector)) + { + // Forcibly move to the next sector and move dirty position + journal.in_sector_pos = journal.block_size; + } // We know for sure that we won't write into this sector anymore uint64_t new_ds = journal.sector_info[s-1].offset + journal.block_size; if (new_ds >= journal.len) diff --git a/tests/run_3osds.sh b/tests/run_3osds.sh index e9ef2186..499b0ce0 100644 --- a/tests/run_3osds.sh +++ b/tests/run_3osds.sh @@ -82,7 +82,9 @@ wait_up() done } -wait_up 60 +if [[ $OSD_COUNT -gt 0 ]]; then + wait_up 60 +fi try_reweight() {