Add readonly flag
parent
9260cd263a
commit
76655929c4
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue