From 00eeedae90e7ece128c628613b5fb46925a19bf1 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 30 Nov 2019 23:55:30 +0300 Subject: [PATCH] Add "fsync disabled" mode --- blockstore.h | 2 +- blockstore_flush.cpp | 3 +- blockstore_flush.h | 1 - blockstore_init.cpp | 26 +++++++++------- blockstore_open.cpp | 4 +++ blockstore_sync.cpp | 70 ++++++++++++++++++++++++++------------------ fio_engine.cpp | 15 +++++++++- 7 files changed, 77 insertions(+), 44 deletions(-) diff --git a/blockstore.h b/blockstore.h index 6655a8e5..36489169 100644 --- a/blockstore.h +++ b/blockstore.h @@ -38,7 +38,6 @@ #define ST_D_SUBMITTED 16 #define ST_D_WRITTEN 17 -#define ST_D_SYNCED 18 #define ST_D_META_WRITTEN 19 #define ST_D_META_SYNCED 20 #define ST_D_STABLE 21 @@ -271,6 +270,7 @@ class blockstore uint64_t data_offset, data_size, data_len; bool readonly = false; + bool disable_fsync = false; struct journal_t journal; journal_flusher_t *flusher; diff --git a/blockstore_flush.cpp b/blockstore_flush.cpp index f0377edd..96c1d100 100644 --- a/blockstore_flush.cpp +++ b/blockstore_flush.cpp @@ -6,7 +6,6 @@ journal_flusher_t::journal_flusher_t(int flusher_count, blockstore *bs) this->flusher_count = flusher_count; active_flushers = 0; active_until_sync = 0; - sync_required = true; sync_threshold = flusher_count == 1 ? 1 : flusher_count/2; journal_trim_interval = sync_threshold; journal_trim_counter = 0; @@ -378,7 +377,7 @@ resume_0: } v.clear(); flusher->active_until_sync--; - if (flusher->sync_required) + if (!bs->disable_fsync) { // And sync everything (in batches - not per each operation!) cur_sync = flusher->syncs.end(); diff --git a/blockstore_flush.h b/blockstore_flush.h index 84fec326..5393717a 100644 --- a/blockstore_flush.h +++ b/blockstore_flush.h @@ -50,7 +50,6 @@ class journal_flusher_t { int flusher_count; int sync_threshold; - bool sync_required; journal_flusher_co *co; blockstore *bs; friend class journal_flusher_co; diff --git a/blockstore_init.cpp b/blockstore_init.cpp index 69b27e83..0f2cd806 100644 --- a/blockstore_init.cpp +++ b/blockstore_init.cpp @@ -232,11 +232,14 @@ resume_1: data->callback = simple_callback; my_uring_prep_writev(sqe, bs->journal.fd, &data->iov, 1, bs->journal.offset); wait_count++; - GET_SQE(); - my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC); - data->iov = { 0 }; - data->callback = simple_callback; - wait_count++; + if (!bs->disable_fsync) + { + GET_SQE(); + my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC); + data->iov = { 0 }; + data->callback = simple_callback; + wait_count++; + } printf("Resetting journal\n"); bs->ringloop->submit(); resume_4: @@ -309,11 +312,14 @@ resume_1: data->callback = simple_callback; wait_count++; my_uring_prep_writev(sqe, bs->journal.fd, &data->iov, 1, bs->journal.offset + init_write_sector); - GET_SQE(); - data->iov = { 0 }; - data->callback = simple_callback; - wait_count++; - my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC); + if (!bs->disable_fsync) + { + GET_SQE(); + data->iov = { 0 }; + data->callback = simple_callback; + wait_count++; + my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC); + } bs->ringloop->submit(); resume_5: if (wait_count > 0) diff --git a/blockstore_open.cpp b/blockstore_open.cpp index e9233660..957ea78a 100644 --- a/blockstore_open.cpp +++ b/blockstore_open.cpp @@ -6,6 +6,10 @@ void blockstore::calc_lengths(blockstore_config_t & config) { readonly = true; } + if (config["disable_fsync"] == "true" || config["disable_fsync"] == "1" || config["disable_fsync"] == "yes") + { + disable_fsync = true; + } // data data_len = data_size - data_offset; if (data_fd == meta_fd && data_offset < meta_offset) diff --git a/blockstore_sync.cpp b/blockstore_sync.cpp index 4dd99d97..ea76e7de 100644 --- a/blockstore_sync.cpp +++ b/blockstore_sync.cpp @@ -39,28 +39,40 @@ int blockstore::continue_sync(blockstore_operation *op) if (op->sync_state == SYNC_HAS_SMALL) { // No big writes, just fsync the journal - // FIXME: Add no-fsync mode - BS_SUBMIT_GET_SQE(sqe, data); - my_uring_prep_fsync(sqe, journal.fd, IORING_FSYNC_DATASYNC); - data->iov = { 0 }; - data->callback = cb; - op->min_used_journal_sector = op->max_used_journal_sector = 0; - op->pending_ops = 1; - op->sync_state = SYNC_JOURNAL_SYNC_SENT; + if (!disable_fsync) + { + BS_SUBMIT_GET_SQE(sqe, data); + my_uring_prep_fsync(sqe, journal.fd, IORING_FSYNC_DATASYNC); + data->iov = { 0 }; + data->callback = cb; + op->min_used_journal_sector = op->max_used_journal_sector = 0; + op->pending_ops = 1; + op->sync_state = SYNC_JOURNAL_SYNC_SENT; + } + else + { + op->sync_state = SYNC_DONE; + } } else if (op->sync_state == SYNC_HAS_BIG) { // 1st step: fsync data - // FIXME: Add no-fsync mode - BS_SUBMIT_GET_SQE(sqe, data); - my_uring_prep_fsync(sqe, data_fd, IORING_FSYNC_DATASYNC); - data->iov = { 0 }; - data->callback = cb; - op->min_used_journal_sector = op->max_used_journal_sector = 0; - op->pending_ops = 1; - op->sync_state = SYNC_DATA_SYNC_SENT; + if (!disable_fsync) + { + BS_SUBMIT_GET_SQE(sqe, data); + my_uring_prep_fsync(sqe, data_fd, IORING_FSYNC_DATASYNC); + data->iov = { 0 }; + data->callback = cb; + op->min_used_journal_sector = op->max_used_journal_sector = 0; + op->pending_ops = 1; + op->sync_state = SYNC_DATA_SYNC_SENT; + } + else + { + op->sync_state = SYNC_DATA_SYNC_DONE; + } } - else if (op->sync_state == SYNC_DATA_SYNC_DONE) + if (op->sync_state == SYNC_DATA_SYNC_DONE) { // 2nd step: Data device is synced, prepare & write journal entries // Check space in the journal and journal memory buffers @@ -70,8 +82,8 @@ int blockstore::continue_sync(blockstore_operation *op) return 0; } // Get SQEs. Don't bother about merging, submit each journal sector as a separate request - struct io_uring_sqe *sqe[space_check.sectors_required+1]; - for (int i = 0; i < space_check.sectors_required+1; i++) + struct io_uring_sqe *sqe[space_check.sectors_required + (disable_fsync ? 0 : 1)]; + for (int i = 0; i < space_check.sectors_required + (disable_fsync ? 0 : 1); i++) { BS_SUBMIT_GET_SQE_DECL(sqe[i]); } @@ -103,11 +115,16 @@ int blockstore::continue_sync(blockstore_operation *op) } op->max_used_journal_sector = 1 + journal.cur_sector; // ... And a journal fsync - my_uring_prep_fsync(sqe[s], journal.fd, IORING_FSYNC_DATASYNC); - struct ring_data_t *data = ((ring_data_t*)sqe[s]->user_data); - data->iov = { 0 }; - data->callback = cb; - op->pending_ops = 1 + s; + if (!disable_fsync) + { + my_uring_prep_fsync(sqe[s], journal.fd, IORING_FSYNC_DATASYNC); + struct ring_data_t *data = ((ring_data_t*)sqe[s]->user_data); + data->iov = { 0 }; + data->callback = cb; + op->pending_ops = 1 + s; + } + else + op->pending_ops = s; op->sync_state = SYNC_JOURNAL_SYNC_SENT; ringloop->submit(); } @@ -143,11 +160,6 @@ void blockstore::handle_sync_event(ring_data_t *data, blockstore_operation *op) if (op->sync_state == SYNC_DATA_SYNC_SENT) { op->sync_state = SYNC_DATA_SYNC_DONE; - // FIXME: This is not needed, in fact - for (auto it = op->sync_big_writes.begin(); it != op->sync_big_writes.end(); it++) - { - dirty_db[*it].state = ST_D_SYNCED; - } } else if (op->sync_state == SYNC_JOURNAL_SYNC_SENT) { diff --git a/fio_engine.cpp b/fio_engine.cpp index 416ade0e..2ceeb3d3 100644 --- a/fio_engine.cpp +++ b/fio_engine.cpp @@ -34,7 +34,7 @@ struct bs_data struct bs_options { int __pad; - char *data_device, *meta_device, *journal_device; + char *data_device = NULL, *meta_device = NULL, *journal_device = NULL, *disable_fsync = NULL; }; static struct fio_option options[] = { @@ -65,6 +65,15 @@ static struct fio_option options[] = { .category = FIO_OPT_C_ENGINE, .group = FIO_OPT_G_FILENAME, }, + { + .name = "disable_fsync", + .lname = "Disable fsync", + .type = FIO_OPT_STR_STORE, + .off1 = offsetof(struct bs_options, disable_fsync), + .help = "Disable fsyncs for blockstore (unsafe if your disk has cache)", + .category = FIO_OPT_C_ENGINE, + .group = FIO_OPT_G_FILENAME, + }, { .name = NULL, }, @@ -130,6 +139,10 @@ static int bs_init(struct thread_data *td) config["journal_device"] = o->journal_device; config["meta_device"] = o->meta_device; config["data_device"] = o->data_device; + if (o->disable_fsync) + config["disable_fsync"] = o->disable_fsync; + if (read_only) + config["readonly"] = "true"; bsd->ringloop = new ring_loop_t(512); bsd->bs = new blockstore(config, bsd->ringloop); while (1)