vitastor/blockstore.cpp

113 lines
2.6 KiB
C++
Raw Normal View History

#include "blockstore.h"
2019-11-01 02:47:57 +03:00
blockstore::blockstore(spp::sparse_hash_map<std::string, std::string> & config, io_uring *ring)
2019-11-01 02:47:57 +03:00
{
this->ring = ring;
2019-11-05 02:12:04 +03:00
ring_data = (struct ring_data_t*)malloc(sizeof(ring_data_t) * ring->sq.ring_sz);
initialized = 0;
block_order = stoull(config["block_size_order"]);
block_size = 1 << block_order;
if (block_size <= 1 || block_size >= MAX_BLOCK_SIZE)
2019-11-01 02:47:57 +03:00
{
throw new std::runtime_error("Bad block size");
2019-10-31 13:49:46 +03:00
}
data_fd = meta_fd = journal_fd = -1;
try
2019-10-31 13:49:46 +03:00
{
open_data(config);
open_meta(config);
open_journal(config);
calc_lengths(config);
data_alloc = allocator_create(block_count);
if (!data_alloc)
throw new std::bad_alloc();
2019-10-31 13:49:46 +03:00
}
catch (std::exception & e)
2019-10-31 13:49:46 +03:00
{
if (data_fd >= 0)
close(data_fd);
if (meta_fd >= 0 && meta_fd != data_fd)
close(meta_fd);
if (journal_fd >= 0 && journal_fd != meta_fd)
close(journal_fd);
throw e;
2019-10-31 13:49:46 +03:00
}
}
2019-10-31 13:49:46 +03:00
blockstore::~blockstore()
{
2019-11-05 02:12:04 +03:00
free(ring_data);
if (data_fd >= 0)
close(data_fd);
if (meta_fd >= 0 && meta_fd != data_fd)
close(meta_fd);
if (journal_fd >= 0 && journal_fd != meta_fd)
close(journal_fd);
}
2019-11-05 02:12:04 +03:00
struct io_uring_sqe* blockstore::get_sqe()
{
struct io_uring_sqe* sqe = io_uring_get_sqe(ring);
if (sqe)
{
io_uring_sqe_set_data(sqe, ring_data + (sqe - ring->sq.sqes));
}
return sqe;
}
// must be called in the event loop until it returns 0
int blockstore::init_loop()
{
// read metadata, then journal
if (initialized)
2019-10-31 13:49:46 +03:00
{
return 0;
2019-10-31 13:49:46 +03:00
}
if (!metadata_init_reader)
2019-10-31 13:49:46 +03:00
{
metadata_init_reader = new blockstore_init_meta(this);
2019-10-31 13:49:46 +03:00
}
if (metadata_init_reader->read_loop())
2019-10-31 13:49:46 +03:00
{
return 1;
}
if (!journal_init_reader)
{
journal_init_reader = new blockstore_init_journal(this);
}
if (journal_init_reader->read_loop())
{
return 1;
2019-10-31 13:49:46 +03:00
}
initialized = true;
delete metadata_init_reader;
delete journal_init_reader;
metadata_init_reader = NULL;
journal_init_reader = NULL;
return 0;
}
2019-11-05 02:12:04 +03:00
// main event loop
int blockstore::main_loop()
{
while (true)
{
struct io_uring_cqe *cqe;
io_uring_peek_cqe(ring, &cqe);
if (cqe)
{
struct ring_data *d = cqe->user_data;
if (d->source == SRC_BLOCKSTORE)
{
handle_event();
}
else
{
// someone else
}
io_uring_cqe_seen(ring, cqe);
}
}
return 0;
}