From a00fc1bc24d5654c1b6cedea711027d639185789 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 12 Jul 2025 01:35:16 +0300 Subject: [PATCH] Fsync after stabilizing --- src/blockstore/blockstore_impl.h | 1 + src/blockstore/blockstore_stable.cpp | 26 +++++++++----------------- src/blockstore/blockstore_sync.cpp | 22 ++++++++++++++++------ 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/blockstore/blockstore_impl.h b/src/blockstore/blockstore_impl.h index f54a6aa4..8356f683 100644 --- a/src/blockstore/blockstore_impl.h +++ b/src/blockstore/blockstore_impl.h @@ -173,6 +173,7 @@ class blockstore_impl_t: public blockstore_i // Sync int continue_sync(blockstore_op_t *op); + int do_sync(blockstore_op_t *op, int base_state); // Stabilize int dequeue_stable(blockstore_op_t *op); diff --git a/src/blockstore/blockstore_stable.cpp b/src/blockstore/blockstore_stable.cpp index 901e8bcb..797ea8e0 100644 --- a/src/blockstore/blockstore_stable.cpp +++ b/src/blockstore/blockstore_stable.cpp @@ -66,28 +66,20 @@ resume_1: priv->op_state = 1; return 0; } -resume_2: - if (!dsk.disable_meta_fsync) - { - BS_SUBMIT_GET_SQE(sqe, data); - io_uring_prep_fsync(sqe, dsk.meta_fd, IORING_FSYNC_DATASYNC); - data->iov = { 0 }; - data->callback = [this, op](ring_data_t *data) { handle_write_event(data, op); }; - priv->pending_ops++; - } -resume_3: - if (priv->pending_ops > 0) - { - priv->op_state = 3; - return 0; - } -resume_4: // Mark writes as completed to allow compaction - // FIXME: Also mark as fsynced for (uint64_t lsn = priv->lsn; lsn <= priv->to_lsn; lsn++) { heap->mark_lsn_completed(lsn); } + // Fsync, just because our semantics imply that commit (stabilize) is immediately fsynced +resume_2: +resume_3: +resume_4: + int res = do_sync(op, 2); + if (res != 2) + { + return res; + } // Done. Don't touch op->retval - if anything resulted in ENOENT, return it as is FINISH_OP(op); return 2; diff --git a/src/blockstore/blockstore_sync.cpp b/src/blockstore/blockstore_sync.cpp index e293c0e2..72baf4f1 100644 --- a/src/blockstore/blockstore_sync.cpp +++ b/src/blockstore/blockstore_sync.cpp @@ -6,7 +6,21 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op) { - int op_state = PRIV(op)->op_state; + if (!PRIV(op)->op_state) + { + op->retval = 0; + } + int res = do_sync(op, 0); + if (res == 2) + { + FINISH_OP(op); + } + return res; +} + +int blockstore_impl_t::do_sync(blockstore_op_t *op, int base_state) +{ + int op_state = PRIV(op)->op_state - base_state; if (op_state == 1) goto resume_1; if (op_state == 2) goto resume_2; assert(!op_state); @@ -19,8 +33,6 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op) { // We can return immediately because sync is only dequeued after all previous writes unsynced_big_write_count = unsynced_small_write_count = 0; - op->retval = 0; - FINISH_OP(op); return 2; } PRIV(op)->lsn = heap->get_completed_lsn(); @@ -48,12 +60,10 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op) resume_1: if (PRIV(op)->pending_ops > 0) { - PRIV(op)->op_state = 1; + PRIV(op)->op_state = base_state+1; return 1; } resume_2: heap->mark_lsn_fsynced(PRIV(op)->lsn); - op->retval = 0; - FINISH_OP(op); return 2; }