Return no_inode_stats feature back

This commit is contained in:
Vitaliy Filippov
2025-12-02 01:52:12 +03:00
parent 0eacce1e1d
commit 07e6eb0b16
3 changed files with 60 additions and 1 deletions
+56 -1
View File
@@ -216,7 +216,7 @@ uint64_t blockstore_heap_t::get_pg_id(inode_t inode, uint64_t stripe)
uint64_t pg_num = 0;
uint64_t pool_id = (inode >> (64-POOL_ID_BITS));
auto sh_it = pool_shard_settings.find(pool_id);
if (sh_it != pool_shard_settings.end())
if (sh_it != pool_shard_settings.end() && sh_it->second.pg_count > 0)
{
// like map_to_pg()
pg_num = (stripe / sh_it->second.pg_stripe_size) % sh_it->second.pg_count + 1;
@@ -1919,6 +1919,9 @@ bool blockstore_heap_t::is_data_used(uint64_t location)
void blockstore_heap_t::use_data(inode_t inode, uint64_t location)
{
auto sh_it = pool_shard_settings.find(INODE_POOL(inode));
if (sh_it != pool_shard_settings.end() && sh_it->second.no_inode_stats)
inode = (INODE_POOL(inode) << POOL_ID_BITS);
assert(!data_alloc->get(location / dsk->data_block_size));
data_alloc->set(location / dsk->data_block_size, true);
inode_space_stats[inode] += dsk->data_block_size;
@@ -1927,6 +1930,9 @@ void blockstore_heap_t::use_data(inode_t inode, uint64_t location)
void blockstore_heap_t::free_data(inode_t inode, uint64_t location)
{
auto sh_it = pool_shard_settings.find(INODE_POOL(inode));
if (sh_it != pool_shard_settings.end() && sh_it->second.no_inode_stats)
inode = (INODE_POOL(inode) << POOL_ID_BITS);
assert(data_alloc->get(location / dsk->data_block_size));
data_alloc->set(location / dsk->data_block_size, false);
inode_space_stats[inode] -= dsk->data_block_size;
@@ -2156,6 +2162,55 @@ uint64_t blockstore_heap_t::get_fsynced_lsn()
return dsk->disable_meta_fsync && dsk->disable_journal_fsync ? completed_lsn : fsynced_lsn;
}
void blockstore_heap_t::set_no_inode_stats(const std::vector<uint64_t> & pool_ids)
{
for (auto & ps: pool_shard_settings)
{
ps.second.no_inode_stats *= 2;
}
for (auto pool_id: pool_ids)
{
pool_shard_settings[pool_id].no_inode_stats |= 1;
}
for (auto & ps: pool_shard_settings)
{
// Recalculate if changed
if (ps.second.no_inode_stats == 2 || ps.second.no_inode_stats == 1)
recalc_inode_space_stats(ps.first, ps.second.no_inode_stats == 1);
ps.second.no_inode_stats &= 1;
}
}
void blockstore_heap_t::recalc_inode_space_stats(uint64_t pool_id, bool per_inode)
{
auto & ps = pool_shard_settings.at(pool_id);
auto sp_begin = inode_space_stats.lower_bound((pool_id << (64-POOL_ID_BITS)));
auto sp_end = inode_space_stats.lower_bound(((pool_id+1) << (64-POOL_ID_BITS)));
inode_space_stats.erase(sp_begin, sp_end);
uint32_t pg_count = ps.pg_count ? ps.pg_count : 1;
for (uint32_t pg_num = 1; pg_num <= pg_count; pg_num++)
{
auto & pg_idx = block_index[(pool_id << (64-POOL_ID_BITS)) | pg_num];
for (auto & ip: pg_idx)
{
uint64_t space_id = per_inode ? ip.first : (pool_id << (64-POOL_ID_BITS));
inode_map_iterate(ip.second, [&](heap_list_item_t *li)
{
uint32_t used_big = UINT32_MAX;
for (auto wr = &li->entry; wr && !wr->is_garbage(); wr = prev(wr))
{
if ((wr->type() == BS_HEAP_BIG_WRITE || wr->type() == BS_HEAP_BIG_INTENT) &&
wr->big().block_num != used_big)
{
inode_space_stats[space_id] += dsk->data_block_size;
used_big = wr->big().block_num;
}
}
});
}
}
}
// sizeof(robin_hood_map) is 56 bytes which is quite a bit of overhead for us if an inode has, say, only 1 object.
// small-size-optimized inode_maps utilize the fact that malloc returns 16-byte aligned pointers on 64-bit systems
// and allow to reduce memory usage when some inodes on the OSD have a very low number of objects. 4 lower bits
+3
View File
@@ -19,6 +19,7 @@ struct pool_shard_settings_t
{
uint32_t pg_count;
uint32_t pg_stripe_size;
uint32_t no_inode_stats;
};
#define BS_HEAP_TYPE 0x07
@@ -249,6 +250,8 @@ public:
bool recheck_small_writes(std::function<void(bool is_data, uint64_t offset, uint64_t len, uint8_t* buf, std::function<void()>)> read_buffer, int queue_depth);
// reshard database according to the pool's PG count
void reshard(pool_id_t pool, uint32_t pg_count, uint32_t pg_stripe_size);
void set_no_inode_stats(const std::vector<uint64_t> & pool_ids);
void recalc_inode_space_stats(uint64_t pool_id, bool per_inode);
// read an object entry and lock it against removal
// in the future, may become asynchronous
heap_entry_t *lock_and_read_entry(object_id oid);
+1
View File
@@ -350,6 +350,7 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
void blockstore_impl_t::set_no_inode_stats(const std::vector<uint64_t> & pool_ids)
{
heap->set_no_inode_stats(pool_ids);
}
void blockstore_impl_t::dump_diagnostics()