2020-09-17 23:02:40 +03:00
|
|
|
// Copyright (c) Vitaliy Filippov, 2019+
|
2021-02-06 01:26:07 +03:00
|
|
|
// License: VNPL-1.1 (see README.md for details)
|
2020-09-17 23:02:40 +03:00
|
|
|
|
2020-04-21 01:59:11 +03:00
|
|
|
#include <sys/file.h>
|
2019-12-15 14:49:10 +03:00
|
|
|
#include "blockstore_impl.h"
|
2019-11-03 01:34:29 +03:00
|
|
|
|
2020-01-16 00:35:35 +03:00
|
|
|
void blockstore_impl_t::parse_config(blockstore_config_t & config)
|
|
|
|
{
|
2022-06-30 00:22:48 +03:00
|
|
|
// Common disk options
|
|
|
|
dsk.parse_config(config);
|
2020-01-16 00:35:35 +03:00
|
|
|
// Parse
|
2019-11-30 23:39:10 +03:00
|
|
|
if (config["readonly"] == "true" || config["readonly"] == "1" || config["readonly"] == "yes")
|
|
|
|
{
|
|
|
|
readonly = true;
|
|
|
|
}
|
2020-01-17 13:40:47 +03:00
|
|
|
if (config["disable_data_fsync"] == "true" || config["disable_data_fsync"] == "1" || config["disable_data_fsync"] == "yes")
|
2019-11-30 23:55:30 +03:00
|
|
|
{
|
2020-01-17 13:40:47 +03:00
|
|
|
disable_data_fsync = true;
|
|
|
|
}
|
|
|
|
if (config["disable_meta_fsync"] == "true" || config["disable_meta_fsync"] == "1" || config["disable_meta_fsync"] == "yes")
|
|
|
|
{
|
|
|
|
disable_meta_fsync = true;
|
|
|
|
}
|
|
|
|
if (config["disable_journal_fsync"] == "true" || config["disable_journal_fsync"] == "1" || config["disable_journal_fsync"] == "yes")
|
|
|
|
{
|
|
|
|
disable_journal_fsync = true;
|
2019-11-30 23:55:30 +03:00
|
|
|
}
|
2021-04-10 02:23:55 +03:00
|
|
|
if (config["flush_journal"] == "true" || config["flush_journal"] == "1" || config["flush_journal"] == "yes")
|
|
|
|
{
|
|
|
|
// Only flush journal and exit
|
|
|
|
journal.flush_journal = true;
|
|
|
|
}
|
2020-03-10 01:59:15 +03:00
|
|
|
if (config["immediate_commit"] == "all")
|
|
|
|
{
|
|
|
|
immediate_commit = IMMEDIATE_ALL;
|
|
|
|
}
|
|
|
|
else if (config["immediate_commit"] == "small")
|
|
|
|
{
|
|
|
|
immediate_commit = IMMEDIATE_SMALL;
|
|
|
|
}
|
2020-01-16 00:35:35 +03:00
|
|
|
metadata_buf_size = strtoull(config["meta_buf_size"].c_str(), NULL, 10);
|
|
|
|
inmemory_meta = config["inmemory_metadata"] != "false";
|
|
|
|
journal.sector_count = strtoull(config["journal_sector_buffer_count"].c_str(), NULL, 10);
|
2020-09-12 19:14:51 +03:00
|
|
|
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";
|
2020-01-16 00:35:35 +03:00
|
|
|
journal.inmemory = config["inmemory_journal"] != "false";
|
2021-03-24 01:58:33 +03:00
|
|
|
max_flusher_count = strtoull(config["max_flusher_count"].c_str(), NULL, 10);
|
|
|
|
if (!max_flusher_count)
|
|
|
|
max_flusher_count = strtoull(config["flusher_count"].c_str(), NULL, 10);
|
|
|
|
min_flusher_count = strtoull(config["min_flusher_count"].c_str(), NULL, 10);
|
2021-02-23 01:39:49 +03:00
|
|
|
max_write_iodepth = strtoull(config["max_write_iodepth"].c_str(), NULL, 10);
|
2021-03-28 22:47:35 +03:00
|
|
|
throttle_small_writes = config["throttle_small_writes"] == "true" || config["throttle_small_writes"] == "1" || config["throttle_small_writes"] == "yes";
|
|
|
|
throttle_target_iops = strtoull(config["throttle_target_iops"].c_str(), NULL, 10);
|
|
|
|
throttle_target_mbs = strtoull(config["throttle_target_mbs"].c_str(), NULL, 10);
|
|
|
|
throttle_target_parallelism = strtoull(config["throttle_target_parallelism"].c_str(), NULL, 10);
|
|
|
|
throttle_threshold_us = strtoull(config["throttle_threshold_us"].c_str(), NULL, 10);
|
2020-01-16 00:35:35 +03:00
|
|
|
// Validate
|
2021-03-24 01:58:33 +03:00
|
|
|
if (!max_flusher_count)
|
2020-01-16 00:35:35 +03:00
|
|
|
{
|
2021-03-24 01:58:33 +03:00
|
|
|
max_flusher_count = 256;
|
|
|
|
}
|
2021-04-10 02:23:55 +03:00
|
|
|
if (!min_flusher_count || journal.flush_journal)
|
2021-03-24 01:58:33 +03:00
|
|
|
{
|
|
|
|
min_flusher_count = 1;
|
2020-01-16 00:35:35 +03:00
|
|
|
}
|
2021-02-23 01:39:49 +03:00
|
|
|
if (!max_write_iodepth)
|
|
|
|
{
|
|
|
|
max_write_iodepth = 128;
|
|
|
|
}
|
2020-01-16 00:35:35 +03:00
|
|
|
if (journal.sector_count < 2)
|
|
|
|
{
|
|
|
|
journal.sector_count = 32;
|
|
|
|
}
|
|
|
|
if (metadata_buf_size < 65536)
|
|
|
|
{
|
|
|
|
metadata_buf_size = 4*1024*1024;
|
|
|
|
}
|
2022-06-30 00:22:48 +03:00
|
|
|
if (dsk.meta_device == "")
|
2020-03-10 01:59:15 +03:00
|
|
|
{
|
|
|
|
disable_meta_fsync = disable_data_fsync;
|
|
|
|
}
|
2022-06-30 00:22:48 +03:00
|
|
|
if (dsk.journal_device == "")
|
2020-03-10 01:59:15 +03:00
|
|
|
{
|
|
|
|
disable_journal_fsync = disable_meta_fsync;
|
|
|
|
}
|
|
|
|
if (immediate_commit != IMMEDIATE_NONE && !disable_journal_fsync)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("immediate_commit requires disable_journal_fsync");
|
|
|
|
}
|
|
|
|
if (immediate_commit == IMMEDIATE_ALL && !disable_data_fsync)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("immediate_commit=all requires disable_journal_fsync and disable_data_fsync");
|
|
|
|
}
|
2021-03-28 22:47:35 +03:00
|
|
|
if (!throttle_target_iops)
|
|
|
|
{
|
|
|
|
throttle_target_iops = 100;
|
|
|
|
}
|
|
|
|
if (!throttle_target_mbs)
|
|
|
|
{
|
|
|
|
throttle_target_mbs = 100;
|
|
|
|
}
|
|
|
|
if (!throttle_target_parallelism)
|
|
|
|
{
|
|
|
|
throttle_target_parallelism = 1;
|
|
|
|
}
|
|
|
|
if (!throttle_threshold_us)
|
|
|
|
{
|
|
|
|
throttle_threshold_us = 50;
|
|
|
|
}
|
2020-01-16 00:35:35 +03:00
|
|
|
// init some fields
|
2022-06-30 00:22:48 +03:00
|
|
|
journal.block_size = dsk.journal_block_size;
|
|
|
|
journal.next_free = dsk.journal_block_size;
|
|
|
|
journal.used_start = dsk.journal_block_size;
|
2020-01-16 00:35:35 +03:00
|
|
|
// no free space because sector is initially unmapped
|
2022-06-30 00:22:48 +03:00
|
|
|
journal.in_sector_pos = dsk.journal_block_size;
|
2020-01-16 00:35:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void blockstore_impl_t::calc_lengths()
|
|
|
|
{
|
2022-06-30 00:22:48 +03:00
|
|
|
dsk.calc_lengths();
|
|
|
|
journal.len = dsk.journal_len;
|
|
|
|
journal.block_size = dsk.journal_block_size;
|
|
|
|
journal.offset = dsk.journal_offset;
|
2019-12-02 02:44:56 +03:00
|
|
|
if (inmemory_meta)
|
|
|
|
{
|
2022-06-30 00:22:48 +03:00
|
|
|
metadata_buffer = memalign(MEM_ALIGNMENT, dsk.meta_len);
|
2019-12-02 02:44:56 +03:00
|
|
|
if (!metadata_buffer)
|
2020-01-12 02:11:09 +03:00
|
|
|
throw std::runtime_error("Failed to allocate memory for the metadata");
|
|
|
|
}
|
2022-06-30 00:22:48 +03:00
|
|
|
else if (dsk.clean_entry_bitmap_size)
|
2020-01-12 02:11:09 +03:00
|
|
|
{
|
2022-06-30 00:22:48 +03:00
|
|
|
clean_bitmap = (uint8_t*)malloc(dsk.block_count * 2*dsk.clean_entry_bitmap_size);
|
2020-01-12 02:11:09 +03:00
|
|
|
if (!clean_bitmap)
|
|
|
|
throw std::runtime_error("Failed to allocate memory for the metadata sparse write bitmap");
|
2019-12-02 02:44:56 +03:00
|
|
|
}
|
2019-11-28 14:41:03 +03:00
|
|
|
if (journal.inmemory)
|
|
|
|
{
|
2020-01-06 14:11:47 +03:00
|
|
|
journal.buffer = memalign(MEM_ALIGNMENT, journal.len);
|
2019-11-28 14:41:03 +03:00
|
|
|
if (!journal.buffer)
|
2019-12-02 02:44:56 +03:00
|
|
|
throw std::runtime_error("Failed to allocate memory for journal");
|
2019-11-28 14:41:03 +03:00
|
|
|
}
|
2019-11-16 01:53:17 +03:00
|
|
|
else
|
|
|
|
{
|
2022-06-30 00:22:48 +03:00
|
|
|
journal.sector_buf = (uint8_t*)memalign(MEM_ALIGNMENT, journal.sector_count * dsk.journal_block_size);
|
|
|
|
if (!journal.sector_buf)
|
|
|
|
throw std::bad_alloc();
|
2019-11-03 01:34:29 +03:00
|
|
|
}
|
2019-11-07 16:58:30 +03:00
|
|
|
journal.sector_info = (journal_sector_info_t*)calloc(journal.sector_count, sizeof(journal_sector_info_t));
|
2019-11-28 14:41:03 +03:00
|
|
|
if (!journal.sector_info)
|
2019-11-07 16:58:30 +03:00
|
|
|
{
|
2019-11-16 02:12:27 +03:00
|
|
|
throw std::bad_alloc();
|
2019-11-07 16:58:30 +03:00
|
|
|
}
|
2019-11-03 01:34:29 +03:00
|
|
|
}
|