From 5cadb170b9a0cc65bc4f95153907d0f62ceb4a78 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Mon, 11 Sep 2023 01:42:38 +0300 Subject: [PATCH] Fix possible OSD crash during sync due to missing min_flushed_journal_sector reset --- src/blockstore_impl.cpp | 1 + src/blockstore_impl.h | 2 +- src/blockstore_journal.cpp | 1 + src/blockstore_write.cpp | 27 +++++++-------------------- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/blockstore_impl.cpp b/src/blockstore_impl.cpp index 578b5f2d..2e9f3086 100644 --- a/src/blockstore_impl.cpp +++ b/src/blockstore_impl.cpp @@ -393,6 +393,7 @@ void blockstore_impl_t::init_op(blockstore_op_t *op) { // Call constructor without allocating memory. We'll call destructor before returning op back new ((void*)op->private_data) blockstore_op_private_t; + PRIV(op)->min_flushed_journal_sector = PRIV(op)->max_flushed_journal_sector = 0; PRIV(op)->wait_for = 0; PRIV(op)->op_state = 0; PRIV(op)->pending_ops = 0; diff --git a/src/blockstore_impl.h b/src/blockstore_impl.h index eb5965f9..d2d5e493 100644 --- a/src/blockstore_impl.h +++ b/src/blockstore_impl.h @@ -210,7 +210,7 @@ struct blockstore_op_private_t std::vector read_vec; // Sync, write - int min_flushed_journal_sector, max_flushed_journal_sector; + uint64_t min_flushed_journal_sector, max_flushed_journal_sector; // Write struct iovec iov_zerofill[3]; diff --git a/src/blockstore_journal.cpp b/src/blockstore_journal.cpp index 1f3ff7d4..b1a661a7 100644 --- a/src/blockstore_journal.cpp +++ b/src/blockstore_journal.cpp @@ -198,6 +198,7 @@ void blockstore_impl_t::prepare_journal_sector_write(int cur_sector, blockstore_ priv->pending_ops++; if (!priv->min_flushed_journal_sector) priv->min_flushed_journal_sector = 1+cur_sector; + assert(priv->min_flushed_journal_sector <= journal.sector_count); priv->max_flushed_journal_sector = 1+cur_sector; } diff --git a/src/blockstore_write.cpp b/src/blockstore_write.cpp index 8df2ed6a..88972377 100644 --- a/src/blockstore_write.cpp +++ b/src/blockstore_write.cpp @@ -378,7 +378,6 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op) sqe, dsk.data_fd, PRIV(op)->iov_zerofill, vcnt, dsk.data_offset + (loc << dsk.block_order) + op->offset - stripe_offset ); PRIV(op)->pending_ops = 1; - PRIV(op)->min_flushed_journal_sector = PRIV(op)->max_flushed_journal_sector = 0; if (immediate_commit != IMMEDIATE_ALL) { // Increase the counter, but don't save into unsynced_writes yet (can't sync until the write is finished) @@ -415,16 +414,10 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op) write_iodepth++; // Got SQEs. Prepare previous journal sector write if required auto cb = [this, op](ring_data_t *data) { handle_write_event(data, op); }; - if (immediate_commit == IMMEDIATE_NONE) + if (immediate_commit == IMMEDIATE_NONE && + !journal.entry_fits(sizeof(journal_entry_small_write) + dyn_size)) { - if (!journal.entry_fits(sizeof(journal_entry_small_write) + dyn_size)) - { - prepare_journal_sector_write(journal.cur_sector, op); - } - else - { - PRIV(op)->min_flushed_journal_sector = PRIV(op)->max_flushed_journal_sector = 0; - } + prepare_journal_sector_write(journal.cur_sector, op); } // Then pre-fill journal entry journal_entry_small_write *je = (journal_entry_small_write*)prefill_single_journal_entry( @@ -750,17 +743,11 @@ int blockstore_impl_t::dequeue_del(blockstore_op_t *op) } write_iodepth++; // Prepare journal sector write - if (immediate_commit == IMMEDIATE_NONE) + if (immediate_commit == IMMEDIATE_NONE && + (dsk.journal_block_size - journal.in_sector_pos) < sizeof(journal_entry_del) && + journal.sector_info[journal.cur_sector].dirty) { - if ((dsk.journal_block_size - journal.in_sector_pos) < sizeof(journal_entry_del) && - journal.sector_info[journal.cur_sector].dirty) - { - prepare_journal_sector_write(journal.cur_sector, op); - } - else - { - PRIV(op)->min_flushed_journal_sector = PRIV(op)->max_flushed_journal_sector = 0; - } + prepare_journal_sector_write(journal.cur_sector, op); } // Pre-fill journal entry journal_entry_del *je = (journal_entry_del*)prefill_single_journal_entry(