diff --git a/src/blockstore.cpp b/src/blockstore.cpp index c1bc574d7..783db4fa8 100644 --- a/src/blockstore.cpp +++ b/src/blockstore.cpp @@ -43,6 +43,11 @@ std::unordered_map & blockstore_t::get_unstable_writes() return impl->unstable_writes; } +std::map & blockstore_t::get_inode_space_stats() +{ + return impl->inode_space_stats; +} + uint32_t blockstore_t::get_block_size() { return impl->get_block_size(); diff --git a/src/blockstore.h b/src/blockstore.h index c0b24a7d0..bc4bc29ae 100644 --- a/src/blockstore.h +++ b/src/blockstore.h @@ -183,6 +183,9 @@ public: // Unstable writes are added here (map of object_id -> version) std::unordered_map & get_unstable_writes(); + // Get per-inode space usage statistics + std::map & get_inode_space_stats(); + // FIXME rename to object_size uint32_t get_block_size(); uint64_t get_block_count(); diff --git a/src/blockstore_impl.h b/src/blockstore_impl.h index 134ccc58d..e9fb3ea8d 100644 --- a/src/blockstore_impl.h +++ b/src/blockstore_impl.h @@ -326,6 +326,9 @@ public: // Unstable writes are added here (map of object_id -> version) std::unordered_map unstable_writes; + // Space usage statistics + std::map inode_space_stats; + inline uint32_t get_block_size() { return block_size; } inline uint64_t get_block_count() { return block_count; } inline uint64_t get_free_block_count() { return data_alloc->get_free_count(); } diff --git a/src/blockstore_init.cpp b/src/blockstore_init.cpp index 4fcbeeefb..75deba821 100644 --- a/src/blockstore_init.cpp +++ b/src/blockstore_init.cpp @@ -115,6 +115,10 @@ void blockstore_init_meta::handle_entries(void* entries, unsigned count, int blo #endif bs->data_alloc->set(clean_it->second.location >> block_order, false); } + else + { + bs->inode_space_stats[entry->oid.inode] += bs->block_size; + } entries_loaded++; #ifdef BLOCKSTORE_DEBUG printf("Allocate block (clean entry) %lu: %lx:%lx v%lu\n", done_cnt+i, entry->oid.inode, entry->oid.stripe, entry->version); @@ -705,7 +709,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u printf("je_delete oid=%lx:%lx ver=%lu\n", je->del.oid.inode, je->del.oid.stripe, je->del.version); #endif auto clean_it = bs->clean_db.find(je->del.oid); - if (clean_it == bs->clean_db.end() || + if (clean_it != bs->clean_db.end() && clean_it->second.version < je->del.version) { // oid, version diff --git a/src/blockstore_rollback.cpp b/src/blockstore_rollback.cpp index 8da6457b1..c30d8b856 100644 --- a/src/blockstore_rollback.cpp +++ b/src/blockstore_rollback.cpp @@ -163,10 +163,7 @@ void blockstore_impl_t::mark_rolled_back(const obj_ver_id & ov) auto rm_start = it; auto rm_end = it; it--; - while (it->first.oid == ov.oid && - it->first.version > ov.version && - !IS_IN_FLIGHT(it->second.state) && - !IS_STABLE(it->second.state)) + while (1) { if (it->first.oid != ov.oid) break; @@ -176,7 +173,7 @@ void blockstore_impl_t::mark_rolled_back(const obj_ver_id & ov) max_unstable = it->first.version; break; } - else if (IS_STABLE(it->second.state)) + else if (IS_IN_FLIGHT(it->second.state) || IS_STABLE(it->second.state)) break; // Remove entry rm_start = it; @@ -187,14 +184,14 @@ void blockstore_impl_t::mark_rolled_back(const obj_ver_id & ov) if (rm_start != rm_end) { erase_dirty(rm_start, rm_end, UINT64_MAX); - } - auto unstab_it = unstable_writes.find(ov.oid); - if (unstab_it != unstable_writes.end()) - { - if (max_unstable == 0) - unstable_writes.erase(unstab_it); - else - unstab_it->second = max_unstable; + auto unstab_it = unstable_writes.find(ov.oid); + if (unstab_it != unstable_writes.end()) + { + if (max_unstable == 0) + unstable_writes.erase(unstab_it); + else + unstab_it->second = max_unstable; + } } } } diff --git a/src/blockstore_stable.cpp b/src/blockstore_stable.cpp index b9ae9564d..3cc6e9df7 100644 --- a/src/blockstore_stable.cpp +++ b/src/blockstore_stable.cpp @@ -186,6 +186,15 @@ void blockstore_impl_t::mark_stable(const obj_ver_id & v) if ((dirty_it->second.state & BS_ST_WORKFLOW_MASK) == BS_ST_SYNCED) { dirty_it->second.state = (dirty_it->second.state & ~BS_ST_WORKFLOW_MASK) | BS_ST_STABLE; + // Allocations and deletions are counted when they're stabilized + if (IS_BIG_WRITE(dirty_it->second.state)) + { + inode_space_stats[dirty_it->first.oid.inode] += block_size; + } + else if (IS_DELETE(dirty_it->second.state)) + { + inode_space_stats[dirty_it->first.oid.inode] -= block_size; + } } else if (IS_STABLE(dirty_it->second.state)) {