Use an interface instead of explicit blockstore_t wrapper

This commit is contained in:
Vitaliy Filippov
2025-11-23 01:48:44 +03:00
parent 1badc6ad13
commit 8ee7058ec8
10 changed files with 50 additions and 121 deletions
+2 -93
View File
@@ -3,98 +3,7 @@
#include "blockstore_impl.h"
blockstore_t::blockstore_t(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd)
blockstore_i* blockstore_i::create(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd)
{
impl = new blockstore_impl_t(config, ringloop, tfd);
}
blockstore_t::~blockstore_t()
{
delete impl;
}
void blockstore_t::parse_config(blockstore_config_t & config)
{
impl->parse_config(config, false);
}
void blockstore_t::loop()
{
impl->loop();
}
bool blockstore_t::is_started()
{
return impl->is_started();
}
bool blockstore_t::is_stalled()
{
return impl->is_stalled();
}
bool blockstore_t::is_safe_to_stop()
{
return impl->is_safe_to_stop();
}
void blockstore_t::enqueue_op(blockstore_op_t *op)
{
impl->enqueue_op(op);
}
int blockstore_t::read_bitmap(object_id oid, uint64_t target_version, void *bitmap, uint64_t *result_version)
{
return impl->read_bitmap(oid, target_version, bitmap, result_version);
}
const std::map<uint64_t, uint64_t> & blockstore_t::get_inode_space_stats()
{
return impl->get_inode_space_stats();
}
void blockstore_t::dump_diagnostics()
{
return impl->dump_diagnostics();
}
std::string blockstore_t::get_op_diag(blockstore_op_t *op)
{
char buf[256];
auto priv = PRIV(op);
if (priv->wait_for)
snprintf(buf, sizeof(buf), "state=%d wait=%d (detail=%ju)", priv->op_state, priv->wait_for, priv->wait_detail);
else
snprintf(buf, sizeof(buf), "state=%d", priv->op_state);
return std::string(buf);
}
uint32_t blockstore_t::get_block_size()
{
return impl->get_block_size();
}
uint64_t blockstore_t::get_block_count()
{
return impl->get_block_count();
}
uint64_t blockstore_t::get_free_block_count()
{
return impl->get_free_block_count();
}
uint64_t blockstore_t::get_journal_size()
{
return impl->get_journal_size();
}
uint32_t blockstore_t::get_bitmap_granularity()
{
return impl->get_bitmap_granularity();
}
void blockstore_t::set_no_inode_stats(const std::vector<uint64_t> & pool_ids)
{
impl->set_no_inode_stats(pool_ids);
return new blockstore_impl_t(config, ringloop, tfd);
}
+20 -22
View File
@@ -173,56 +173,54 @@ struct __attribute__ ((visibility("default"))) blockstore_op_t
typedef std::map<std::string, std::string> blockstore_config_t;
class blockstore_impl_t;
class __attribute__((visibility("default"))) blockstore_t
class __attribute__((visibility("default"))) blockstore_i
{
blockstore_impl_t *impl;
public:
blockstore_t(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd);
~blockstore_t();
static blockstore_i* create(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd);
virtual ~blockstore_i() = default;
// Update configuration
void parse_config(blockstore_config_t & config);
virtual void parse_config(blockstore_config_t & config) = 0;
// Event loop
void loop();
virtual void loop() = 0;
// Returns true when blockstore is ready to process operations
// (Although you're free to enqueue them before that)
bool is_started();
virtual bool is_started() = 0;
// Returns true when blockstore is stalled
bool is_stalled();
virtual bool is_stalled() = 0;
// Returns true when it's safe to destroy the instance. If destroying the instance
// requires to purge some queues, starts that process. Should be called in the event
// loop until it returns true.
bool is_safe_to_stop();
virtual bool is_safe_to_stop() = 0;
// Submission
void enqueue_op(blockstore_op_t *op);
virtual void enqueue_op(blockstore_op_t *op) = 0;
// Simplified synchronous operation: get object bitmap & current version
int read_bitmap(object_id oid, uint64_t target_version, void *bitmap, uint64_t *result_version = NULL);
virtual int read_bitmap(object_id oid, uint64_t target_version, void *bitmap, uint64_t *result_version = NULL) = 0;
// Get per-inode space usage statistics
const std::map<uint64_t, uint64_t> & get_inode_space_stats();
virtual const std::map<uint64_t, uint64_t> & get_inode_space_stats() = 0;
// Set per-pool no_inode_stats
void set_no_inode_stats(const std::vector<uint64_t> & pool_ids);
virtual void set_no_inode_stats(const std::vector<uint64_t> & pool_ids) = 0;
// Print diagnostics to stdout
void dump_diagnostics();
virtual void dump_diagnostics() = 0;
// Get diagnostic string for an operation
std::string get_op_diag(blockstore_op_t *op);
virtual std::string get_op_diag(blockstore_op_t *op) = 0;
uint32_t get_block_size();
uint64_t get_block_count();
uint64_t get_free_block_count();
virtual uint32_t get_block_size() = 0;
virtual uint64_t get_block_count() = 0;
virtual uint64_t get_free_block_count() = 0;
uint64_t get_journal_size();
virtual uint64_t get_journal_size() = 0;
uint32_t get_bitmap_granularity();
virtual uint32_t get_bitmap_granularity() = 0;
};
+11
View File
@@ -792,3 +792,14 @@ void blockstore_impl_t::recalc_inode_space_stats(uint64_t pool_id, bool per_inod
dirty_it++;
}
}
std::string blockstore_impl_t::get_op_diag(blockstore_op_t *op)
{
char buf[256];
auto priv = PRIV(op);
if (priv->wait_for)
snprintf(buf, sizeof(buf), "state=%d wait=%d (detail=%ju)", priv->op_state, priv->wait_for, priv->wait_detail);
else
snprintf(buf, sizeof(buf), "state=%d", priv->op_state);
return std::string(buf);
}
+5 -1
View File
@@ -196,7 +196,7 @@ struct pool_shard_settings_t
#define STAB_SPLIT_SYNC 3
#define STAB_SPLIT_TODO 4
class blockstore_impl_t
class blockstore_impl_t: public blockstore_i
{
blockstore_disk_t dsk;
@@ -361,6 +361,7 @@ public:
blockstore_impl_t(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd);
~blockstore_impl_t();
void parse_config(blockstore_config_t & config);
void parse_config(blockstore_config_t & config, bool init);
// Event loop
@@ -396,6 +397,9 @@ public:
// Print diagnostics to stdout
void dump_diagnostics();
// Get diagnostic string for an operation
std::string get_op_diag(blockstore_op_t *op);
inline uint32_t get_block_size() { return dsk.data_block_size; }
inline uint64_t get_block_count() { return dsk.block_count; }
inline uint64_t get_free_block_count() { return dsk.block_count - used_blocks; }
+2
View File
@@ -3,6 +3,8 @@
#pragma once
class blockstore_impl_t;
struct journal_sector_info_t
{
uint64_t offset;
+5
View File
@@ -4,6 +4,11 @@
#include <sys/file.h>
#include "blockstore_impl.h"
void blockstore_impl_t::parse_config(blockstore_config_t & config)
{
return parse_config(config, false);
}
void blockstore_impl_t::parse_config(blockstore_config_t & config, bool init)
{
// Online-configurable options:
+2 -2
View File
@@ -32,7 +32,7 @@
struct bs_data
{
blockstore_t *bs;
blockstore_i *bs;
epoll_manager_t *epmgr;
ring_loop_t *ringloop;
/* The list of completed io_u structs. */
@@ -162,7 +162,7 @@ static int bs_init(struct thread_data *td)
}
bsd->ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE);
bsd->epmgr = new epoll_manager_t(bsd->ringloop);
bsd->bs = new blockstore_t(config, bsd->ringloop, bsd->epmgr->tfd);
bsd->bs = blockstore_i::create(config, bsd->ringloop, bsd->epmgr->tfd);
bsd->imm = config.find("immediate_commit") == config.end() ||
config["immediate_commit"] == "all";
while (1)
+1 -1
View File
@@ -34,7 +34,7 @@ osd_t::osd_t(const json11::Json & config, ring_loop_t *ringloop)
if (!json_is_true(this->config["disable_blockstore"]))
{
auto bs_cfg = json_to_string_map(this->config);
this->bs = new blockstore_t(bs_cfg, ringloop, tfd);
this->bs = blockstore_i::create(bs_cfg, ringloop, tfd);
// Wait for blockstore initialisation before actually starting OSD logic
// to prevent peering timeouts during restart with filled databases
while (!bs->is_started())
+1 -1
View File
@@ -202,7 +202,7 @@ class osd_t
bool stopping = false;
int inflight_ops = 0;
blockstore_t *bs = NULL;
blockstore_i *bs = NULL;
void *zero_buffer = NULL;
uint64_t zero_buffer_size = 0;
uint32_t bs_block_size, bs_bitmap_granularity, clean_entry_bitmap_size;
+1 -1
View File
@@ -13,7 +13,7 @@ int main(int narg, char *args[])
config["data_device"] = "./test_data.bin";
ring_loop_t *ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE);
epoll_manager_t *epmgr = new epoll_manager_t(ringloop);
blockstore_t *bs = new blockstore_t(config, ringloop, epmgr->tfd);
blockstore_i *bs = blockstore_i::create(config, ringloop, epmgr->tfd);
blockstore_op_t op;
int main_state = 0;