Browse Source

Add "fsync disabled" mode

blocking-uring-test
Vitaliy Filippov 2 years ago
parent
commit
00eeedae90
  1. 2
      blockstore.h
  2. 3
      blockstore_flush.cpp
  3. 1
      blockstore_flush.h
  4. 26
      blockstore_init.cpp
  5. 4
      blockstore_open.cpp
  6. 70
      blockstore_sync.cpp
  7. 15
      fio_engine.cpp

2
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;

3
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();

1
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;

26
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)

4
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)

70
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)
{

15
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)

Loading…
Cancel
Save