forked from vitalif/vitastor
Add option to disable multiple overwrites of the same journal sector
This makes sense for some SSDs like Intel D3-4510 because they don't like overwrites of the same sector: $ fio -direct=1 -rw=write -bs=4k -size=4k -loops=100000 -iodepth=1 write: IOPS=3142, BW=12.3MiB/s (12.9MB/s)(97.9MiB/7977msec) $ fio -direct=1 -rw=write -bs=4k -size=128k -loops=100000 -iodepth=1 write: IOPS=20.8k, BW=81.4MiB/s (85.3MB/s)(543MiB/6675msec)
parent
8f9f438e25
commit
de6919b02b
|
@ -17,7 +17,9 @@ int blockstore_journal_check_t::check_available(blockstore_op_t *op, int entries
|
||||||
int required = entries_required;
|
int required = entries_required;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int fits = (bs->journal.block_size - next_in_pos) / size;
|
int fits = bs->journal.no_same_sector_overwrites && bs->journal.sector_info[next_sector].written
|
||||||
|
? 0
|
||||||
|
: (bs->journal.block_size - next_in_pos) / size;
|
||||||
if (fits > 0)
|
if (fits > 0)
|
||||||
{
|
{
|
||||||
if (first_sector == -1)
|
if (first_sector == -1)
|
||||||
|
@ -110,10 +112,12 @@ int blockstore_journal_check_t::check_available(blockstore_op_t *op, int entries
|
||||||
|
|
||||||
journal_entry* prefill_single_journal_entry(journal_t & journal, uint16_t type, uint32_t size)
|
journal_entry* prefill_single_journal_entry(journal_t & journal, uint16_t type, uint32_t size)
|
||||||
{
|
{
|
||||||
if (journal.block_size - journal.in_sector_pos < size)
|
if (journal.block_size - journal.in_sector_pos < size ||
|
||||||
|
journal.no_same_sector_overwrites && journal.sector_info[journal.cur_sector].written)
|
||||||
{
|
{
|
||||||
assert(!journal.sector_info[journal.cur_sector].dirty);
|
assert(!journal.sector_info[journal.cur_sector].dirty);
|
||||||
// Move to the next journal sector
|
// Move to the next journal sector
|
||||||
|
journal.sector_info[journal.cur_sector].written = false;
|
||||||
if (journal.sector_info[journal.cur_sector].usage_count > 0)
|
if (journal.sector_info[journal.cur_sector].usage_count > 0)
|
||||||
{
|
{
|
||||||
// Also select next sector buffer in memory
|
// Also select next sector buffer in memory
|
||||||
|
@ -148,6 +152,7 @@ journal_entry* prefill_single_journal_entry(journal_t & journal, uint16_t type,
|
||||||
void prepare_journal_sector_write(journal_t & journal, int cur_sector, io_uring_sqe *sqe, std::function<void(ring_data_t*)> cb)
|
void prepare_journal_sector_write(journal_t & journal, int cur_sector, io_uring_sqe *sqe, std::function<void(ring_data_t*)> cb)
|
||||||
{
|
{
|
||||||
journal.sector_info[cur_sector].dirty = false;
|
journal.sector_info[cur_sector].dirty = false;
|
||||||
|
journal.sector_info[cur_sector].written = true;
|
||||||
journal.sector_info[cur_sector].usage_count++;
|
journal.sector_info[cur_sector].usage_count++;
|
||||||
ring_data_t *data = ((ring_data_t*)sqe->user_data);
|
ring_data_t *data = ((ring_data_t*)sqe->user_data);
|
||||||
data->iov = (struct iovec){
|
data->iov = (struct iovec){
|
||||||
|
|
|
@ -129,6 +129,7 @@ struct journal_sector_info_t
|
||||||
{
|
{
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
uint64_t usage_count;
|
uint64_t usage_count;
|
||||||
|
bool written;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ struct journal_t
|
||||||
void *sector_buf = NULL;
|
void *sector_buf = NULL;
|
||||||
journal_sector_info_t *sector_info = NULL;
|
journal_sector_info_t *sector_info = NULL;
|
||||||
uint64_t sector_count;
|
uint64_t sector_count;
|
||||||
|
bool no_same_sector_overwrites = false;
|
||||||
int cur_sector = 0;
|
int cur_sector = 0;
|
||||||
int in_sector_pos = 0;
|
int in_sector_pos = 0;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@ void blockstore_impl_t::parse_config(blockstore_config_t & config)
|
||||||
journal_device = config["journal_device"];
|
journal_device = config["journal_device"];
|
||||||
journal.offset = strtoull(config["journal_offset"].c_str(), NULL, 10);
|
journal.offset = strtoull(config["journal_offset"].c_str(), NULL, 10);
|
||||||
journal.sector_count = strtoull(config["journal_sector_buffer_count"].c_str(), NULL, 10);
|
journal.sector_count = strtoull(config["journal_sector_buffer_count"].c_str(), NULL, 10);
|
||||||
|
journal.no_same_sector_overwrites = config["journal_no_same_sector_overwrites"] == "true" ||
|
||||||
|
config["journal_no_same_sector_overwrites"] == "1" || config["journal_no_same_sector_overwrites"] == "yes";
|
||||||
journal.inmemory = config["inmemory_journal"] != "false";
|
journal.inmemory = config["inmemory_journal"] != "false";
|
||||||
disk_alignment = strtoull(config["disk_alignment"].c_str(), NULL, 10);
|
disk_alignment = strtoull(config["disk_alignment"].c_str(), NULL, 10);
|
||||||
journal_block_size = strtoull(config["journal_block_size"].c_str(), NULL, 10);
|
journal_block_size = strtoull(config["journal_block_size"].c_str(), NULL, 10);
|
||||||
|
|
Loading…
Reference in New Issue