Add readonly flag

blocking-uring-test
Vitaliy Filippov 2019-11-30 23:39:10 +03:00
parent 9260cd263a
commit 76655929c4
4 changed files with 46 additions and 24 deletions

View File

@ -178,7 +178,10 @@ void blockstore::loop()
} }
} }
} }
flusher->loop(); if (!readonly)
{
flusher->loop();
}
int ret = ringloop->submit(); int ret = ringloop->submit();
if (ret < 0) 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, // It's safe to stop blockstore when there are no in-flight operations,
// no in-progress syncs and flusher isn't doing anything // 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; return false;
} }
if (unsynced_big_writes.size() > 0 || unsynced_small_writes.size() > 0) 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 // We should sync the blockstore before unmounting
blockstore_operation *op = new blockstore_operation; blockstore_operation *op = new blockstore_operation;
@ -275,7 +278,8 @@ void blockstore::enqueue_op(blockstore_operation *op)
{ {
int type = op->flags & OP_TYPE_MASK; int type = op->flags & OP_TYPE_MASK;
if (type < OP_READ || type > OP_DELETE || (type == OP_READ || type == OP_WRITE) && 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 // Basic verification not passed
op->retval = -EINVAL; op->retval = -EINVAL;

View File

@ -270,7 +270,7 @@ class blockstore
uint64_t meta_offset, meta_size, meta_area, meta_len; uint64_t meta_offset, meta_size, meta_area, meta_len;
uint64_t data_offset, data_size, data_len; uint64_t data_offset, data_size, data_len;
// FIXME: add readonly option bool readonly = false;
struct journal_t journal; struct journal_t journal;
journal_flusher_t *flusher; journal_flusher_t *flusher;

View File

@ -209,9 +209,6 @@ resume_1:
bs->journal.used_start = 512; bs->journal.used_start = 512;
bs->journal.next_free = 512; bs->journal.next_free = 512;
// Initialize journal "superblock" and the first block // 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); memset(submitted_buf, 0, 1024);
*((journal_entry_start*)submitted_buf) = { *((journal_entry_start*)submitted_buf) = {
.crc32 = 0, .crc32 = 0,
@ -222,25 +219,37 @@ resume_1:
.journal_start = 512, .journal_start = 512,
}; };
((journal_entry_start*)submitted_buf)->crc32 = je_crc32((journal_entry*)submitted_buf); ((journal_entry_start*)submitted_buf)->crc32 = je_crc32((journal_entry*)submitted_buf);
data->iov = (struct iovec){ submitted_buf, 1024 }; if (bs->readonly)
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; printf("Skipping journal initialization because blockstore is readonly\n");
return 1; }
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) if (!bs->journal.inmemory)
{
free(submitted_buf); free(submitted_buf);
}
} }
else else
{ {
@ -293,13 +302,18 @@ resume_1:
{ {
// journal ended // journal ended
// zero out corrupted entry, if required // zero out corrupted entry, if required
if (init_write_buf) if (init_write_buf && !bs->readonly)
{ {
GET_SQE(); GET_SQE();
data->iov = { init_write_buf, 512 }; data->iov = { init_write_buf, 512 };
data->callback = simple_callback; data->callback = simple_callback;
wait_count++; wait_count++;
my_uring_prep_writev(sqe, bs->journal.fd, &data->iov, 1, bs->journal.offset + init_write_sector); 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(); bs->ringloop->submit();
resume_5: resume_5:
if (wait_count > 0) if (wait_count > 0)

View File

@ -2,6 +2,10 @@
void blockstore::calc_lengths(blockstore_config_t & config) void blockstore::calc_lengths(blockstore_config_t & config)
{ {
if (config["readonly"] == "true" || config["readonly"] == "1" || config["readonly"] == "yes")
{
readonly = true;
}
// data // data
data_len = data_size - data_offset; data_len = data_size - data_offset;
if (data_fd == meta_fd && data_offset < meta_offset) if (data_fd == meta_fd && data_offset < meta_offset)