From 76655929c438e4c096fd8840e40bb0dc5606502e Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 30 Nov 2019 23:39:10 +0300 Subject: [PATCH] Add readonly flag --- blockstore.cpp | 12 +++++++---- blockstore.h | 2 +- blockstore_init.cpp | 52 ++++++++++++++++++++++++++++----------------- blockstore_open.cpp | 4 ++++ 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/blockstore.cpp b/blockstore.cpp index 5aaad1b9..aeabcee5 100644 --- a/blockstore.cpp +++ b/blockstore.cpp @@ -178,7 +178,10 @@ void blockstore::loop() } } } - flusher->loop(); + if (!readonly) + { + flusher->loop(); + } int ret = ringloop->submit(); if (ret < 0) { @@ -191,13 +194,13 @@ bool blockstore::is_safe_to_stop() { // It's safe to stop blockstore when there are no in-flight operations, // no in-progress syncs and flusher isn't doing anything - if (submit_queue.size() > 0 || in_progress_syncs.size() > 0 || flusher->is_active()) + if (submit_queue.size() > 0 || in_progress_syncs.size() > 0 || !readonly && flusher->is_active()) { return false; } if (unsynced_big_writes.size() > 0 || unsynced_small_writes.size() > 0) { - if (!stop_sync_submitted) + if (!readonly && !stop_sync_submitted) { // We should sync the blockstore before unmounting blockstore_operation *op = new blockstore_operation; @@ -275,7 +278,8 @@ void blockstore::enqueue_op(blockstore_operation *op) { int type = op->flags & OP_TYPE_MASK; if (type < OP_READ || type > OP_DELETE || (type == OP_READ || type == OP_WRITE) && - (op->offset >= block_size || op->len > block_size-op->offset || (op->len % DISK_ALIGNMENT))) + (op->offset >= block_size || op->len > block_size-op->offset || (op->len % DISK_ALIGNMENT)) || + readonly && type != OP_READ) { // Basic verification not passed op->retval = -EINVAL; diff --git a/blockstore.h b/blockstore.h index 827730df..6655a8e5 100644 --- a/blockstore.h +++ b/blockstore.h @@ -270,7 +270,7 @@ class blockstore uint64_t meta_offset, meta_size, meta_area, meta_len; uint64_t data_offset, data_size, data_len; - // FIXME: add readonly option + bool readonly = false; struct journal_t journal; journal_flusher_t *flusher; diff --git a/blockstore_init.cpp b/blockstore_init.cpp index 0ab6e244..69b27e83 100644 --- a/blockstore_init.cpp +++ b/blockstore_init.cpp @@ -209,9 +209,6 @@ resume_1: bs->journal.used_start = 512; bs->journal.next_free = 512; // Initialize journal "superblock" and the first block - // Cool effect. Same operations result in journal replay. - // FIXME: Randomize initial crc32. Track crc32 when trimming. - GET_SQE(); memset(submitted_buf, 0, 1024); *((journal_entry_start*)submitted_buf) = { .crc32 = 0, @@ -222,25 +219,37 @@ resume_1: .journal_start = 512, }; ((journal_entry_start*)submitted_buf)->crc32 = je_crc32((journal_entry*)submitted_buf); - data->iov = (struct iovec){ submitted_buf, 1024 }; - 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++; - printf("Resetting journal\n"); - bs->ringloop->submit(); - resume_4: - if (wait_count > 0) + if (bs->readonly) { - wait_state = 4; - return 1; + printf("Skipping journal initialization because blockstore is readonly\n"); + } + else + { + // Cool effect. Same operations result in journal replay. + // FIXME: Randomize initial crc32. Track crc32 when trimming. + GET_SQE(); + data->iov = (struct iovec){ submitted_buf, 1024 }; + 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++; + printf("Resetting journal\n"); + bs->ringloop->submit(); + resume_4: + if (wait_count > 0) + { + wait_state = 4; + return 1; + } } if (!bs->journal.inmemory) + { free(submitted_buf); + } } else { @@ -293,13 +302,18 @@ resume_1: { // journal ended // zero out corrupted entry, if required - if (init_write_buf) + if (init_write_buf && !bs->readonly) { GET_SQE(); data->iov = { init_write_buf, 512 }; 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); bs->ringloop->submit(); resume_5: if (wait_count > 0) diff --git a/blockstore_open.cpp b/blockstore_open.cpp index 0b34d252..e9233660 100644 --- a/blockstore_open.cpp +++ b/blockstore_open.cpp @@ -2,6 +2,10 @@ void blockstore::calc_lengths(blockstore_config_t & config) { + if (config["readonly"] == "true" || config["readonly"] == "1" || config["readonly"] == "yes") + { + readonly = true; + } // data data_len = data_size - data_offset; if (data_fd == meta_fd && data_offset < meta_offset)