From 84175d6060508a4c16890507a124a8e7adbdeec1 Mon Sep 17 00:00:00 2001 From: myoungwon oh Date: Fri, 8 Apr 2022 17:20:02 +0900 Subject: [PATCH] seastore: enable cbjournal when running unittest_transaction_manager Signed-off-by: Myoungwon Oh --- src/crimson/os/seastore/btree/fixed_kv_node.h | 7 +- src/crimson/os/seastore/cache.cc | 18 +- .../journal/circular_bounded_journal.cc | 18 +- .../journal/circular_bounded_journal.h | 3 + .../lba_manager/btree/lba_btree_node.cc | 6 +- .../random_block_manager/nvme_manager.cc | 14 +- .../random_block_manager/nvmedevice.cc | 6 +- .../random_block_manager/nvmedevice.h | 72 +++++++- src/crimson/os/seastore/seastore_types.h | 16 +- src/crimson/os/seastore/segment_cleaner.cc | 3 + src/crimson/os/seastore/segment_cleaner.h | 4 + .../os/seastore/transaction_manager.cc | 10 +- src/crimson/os/seastore/transaction_manager.h | 19 ++- .../seastore/nvmedevice/test_nvmedevice.cc | 2 +- src/test/crimson/seastore/test_cbjournal.cc | 2 +- .../seastore/test_transaction_manager.cc | 161 ++++++++++++------ .../seastore/transaction_manager_test_state.h | 47 ++++- 17 files changed, 304 insertions(+), 104 deletions(-) diff --git a/src/crimson/os/seastore/btree/fixed_kv_node.h b/src/crimson/os/seastore/btree/fixed_kv_node.h index c48d3c0e0ff..bf6d9d3396f 100644 --- a/src/crimson/os/seastore/btree/fixed_kv_node.h +++ b/src/crimson/os/seastore/btree/fixed_kv_node.h @@ -217,7 +217,12 @@ struct FixedKVInternalNode LOG_PREFIX(FixedKVInternalNode::resolve_relative_addrs); for (auto i: *this) { if (i->get_val().is_relative()) { - auto updated = base.add_relative(i->get_val()); + paddr_t updated; + if (base.get_addr_type() == addr_types_t::SEGMENT) { + updated = base.add_relative(i->get_val()); + } else { + updated = base.add_offset(i->get_val().as_seg_paddr().get_segment_off()); + } SUBTRACE(seastore_fixedkv_tree, "{} -> {}", i->get_val(), updated); i->set_val(updated); } diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index 3f738fe9580..5e7f23520a4 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -1063,7 +1063,8 @@ record_t Cache::prepare_record( } else { auto sseq = NULL_SEG_SEQ; auto stype = segment_type_t::NULL_SEG; - if (cleaner != nullptr) { + if (cleaner != nullptr && i->get_paddr().get_addr_type() == + addr_types_t::SEGMENT) { auto sid = i->get_paddr().as_seg_paddr().get_segment_id(); auto &sinfo = cleaner->get_seg_info(sid); sseq = sinfo.seq; @@ -1347,7 +1348,13 @@ void Cache::complete_commit( bool is_inline = false; if (i->is_inline()) { is_inline = true; - i->set_paddr(final_block_start.add_relative(i->get_paddr())); + if (final_block_start.get_addr_type() == addr_types_t::SEGMENT) { + i->set_paddr(final_block_start.add_relative(i->get_paddr())); + } else if (final_block_start.get_addr_type() == + addr_types_t::RANDOM_BLOCK) { + i->set_paddr(final_block_start.add_offset( + i->get_paddr().as_seg_paddr().get_segment_off())); + } } i->last_committed_crc = i->get_crc32c(); i->on_initial_write(); @@ -1536,7 +1543,12 @@ Cache::replay_delta( for (auto &alloc_blk : alloc_delta.alloc_blk_ranges) { if (alloc_blk.paddr.is_relative()) { assert(alloc_blk.paddr.is_record_relative()); - alloc_blk.paddr = record_base.add_relative(alloc_blk.paddr); + if (record_base.get_addr_type() == addr_types_t::SEGMENT) { + alloc_blk.paddr = record_base.add_relative(alloc_blk.paddr); + } else { + alloc_blk.paddr = record_base.add_offset( + alloc_blk.paddr.as_seg_paddr().get_segment_off()); + } } DEBUG("replay alloc_blk {}~{} {}, journal_seq: {}", alloc_blk.paddr, alloc_blk.len, alloc_blk.laddr, journal_seq); diff --git a/src/crimson/os/seastore/journal/circular_bounded_journal.cc b/src/crimson/os/seastore/journal/circular_bounded_journal.cc index c01122dca42..a2207d29945 100644 --- a/src/crimson/os/seastore/journal/circular_bounded_journal.cc +++ b/src/crimson/os/seastore/journal/circular_bounded_journal.cc @@ -46,7 +46,8 @@ CircularBoundedJournal::mkfs(mkfs_config_t& config) ).safe_then([this, config, FNAME]() mutable -> mkfs_ret { rbm_abs_addr start_addr = convert_paddr_to_abs_addr( config.start); - assert(config.block_size == device->get_block_size()); + assert(static_cast(config.block_size) == + device->get_block_size()); ceph::bufferlist bl; CircularBoundedJournal::cbj_header_t head; head.magic = CBJOURNAL_MAGIC; @@ -82,16 +83,14 @@ CircularBoundedJournal::mkfs(mkfs_config_t& config) }).safe_then([]() { return mkfs_ertr::now(); }); - }).handle_error( - mkfs_ertr::pass_further{}, - crimson::ct_error::assert_all{ - "Invalid error _open_device in CircularBoundedJournal::mkfs" - }).finally([this] { + }).safe_then([this]() { if (device) { - return device->close(); - } else { - return seastar::now(); + return device->close( + ).safe_then([]() { + return mkfs_ertr::now(); + }); } + return mkfs_ertr::now(); }); } @@ -431,6 +430,7 @@ Journal::replay_ret CircularBoundedJournal::replay( auto& delta = p.second; return d_handler(locator, delta, + locator.write_result.start_seq, seastar::lowres_system_clock::time_point( seastar::lowres_system_clock::duration(commit_time)) ); diff --git a/src/crimson/os/seastore/journal/circular_bounded_journal.h b/src/crimson/os/seastore/journal/circular_bounded_journal.h index 2537df12503..d7830b8ee00 100644 --- a/src/crimson/os/seastore/journal/circular_bounded_journal.h +++ b/src/crimson/os/seastore/journal/circular_bounded_journal.h @@ -301,6 +301,9 @@ public: size_t get_block_size() const { return header.block_size; } + void add_device(NVMeBlockDevice* dev) { + device = dev; + } private: cbj_header_t header; NVMeBlockDevice* device; diff --git a/src/crimson/os/seastore/lba_manager/btree/lba_btree_node.cc b/src/crimson/os/seastore/lba_manager/btree/lba_btree_node.cc index e3e69421fc6..ba0619d35cc 100644 --- a/src/crimson/os/seastore/lba_manager/btree/lba_btree_node.cc +++ b/src/crimson/os/seastore/lba_manager/btree/lba_btree_node.cc @@ -39,7 +39,11 @@ void LBALeafNode::resolve_relative_addrs(paddr_t base) for (auto i: *this) { if (i->get_val().paddr.is_relative()) { auto val = i->get_val(); - val.paddr = base.add_relative(val.paddr); + if (base.get_addr_type() == addr_types_t::SEGMENT) { + val.paddr = base.add_relative(val.paddr); + } else { + val.paddr = base.add_offset(val.paddr.as_seg_paddr().get_segment_off()); + } TRACE("{} -> {}", i->get_val().paddr, val.paddr); i->set_val(val); } diff --git a/src/crimson/os/seastore/random_block_manager/nvme_manager.cc b/src/crimson/os/seastore/random_block_manager/nvme_manager.cc index 0cfa30e58e1..e4c885810a6 100644 --- a/src/crimson/os/seastore/random_block_manager/nvme_manager.cc +++ b/src/crimson/os/seastore/random_block_manager/nvme_manager.cc @@ -162,16 +162,18 @@ NVMeManager::mkfs_ertr::future<> NVMeManager::mkfs(mkfs_config_t config) "Invalid error read_rbm_header in NVMeManager::mkfs" } ); + }).safe_then([this]() { + if (device) { + return device->close( + ).safe_then([]() { + return mkfs_ertr::now(); + }); + } + return mkfs_ertr::now(); }).handle_error( mkfs_ertr::pass_further{}, crimson::ct_error::assert_all{ "Invalid error open_device in NVMeManager::mkfs" - }).finally([this] { - if (device) { - return device->close(); - } else { - return seastar::now(); - } }); } diff --git a/src/crimson/os/seastore/random_block_manager/nvmedevice.cc b/src/crimson/os/seastore/random_block_manager/nvmedevice.cc index ca829e6e575..a29fefe4d4e 100644 --- a/src/crimson/os/seastore/random_block_manager/nvmedevice.cc +++ b/src/crimson/os/seastore/random_block_manager/nvmedevice.cc @@ -132,7 +132,7 @@ read_ertr::future<> PosixNVMeDevice::read( }); } -seastar::future<> PosixNVMeDevice::close() { +Device::close_ertr::future<> PosixNVMeDevice::close() { logger().debug(" close "); return device.close().then([this]() { return seastar::do_for_each(io_device, [](auto target_device) { @@ -254,8 +254,8 @@ read_ertr::future<> TestMemory::read( return read_ertr::now(); } -seastar::future<> TestMemory::close() { +Device::close_ertr::future<> TestMemory::close() { logger().debug(" close "); - return seastar::now(); + return close_ertr::now(); } } diff --git a/src/crimson/os/seastore/random_block_manager/nvmedevice.h b/src/crimson/os/seastore/random_block_manager/nvmedevice.h index f54eb10db7e..03b7a428be6 100644 --- a/src/crimson/os/seastore/random_block_manager/nvmedevice.h +++ b/src/crimson/os/seastore/random_block_manager/nvmedevice.h @@ -16,6 +16,9 @@ #include "crimson/osd/exceptions.h" #include "crimson/common/layout.h" +#include "crimson/os/seastore/seastore_types.h" +#include "crimson/os/seastore/random_block_manager.h" +#include "crimson/os/seastore/device.h" namespace ceph { namespace buffer { @@ -229,7 +232,16 @@ struct io_context_t { * Various implementations with different interfaces such as POSIX APIs, Seastar, * and SPDK, are available. */ -class NVMeBlockDevice { +class NVMeBlockDevice : public Device { +public: + using Device::read; + read_ertr::future<> read ( + paddr_t addr, + size_t len, + ceph::bufferptr &out) final { + uint64_t rbm_addr = convert_paddr_to_abs_addr(addr); + return read(rbm_addr, out); + } protected: uint64_t size = 0; @@ -241,7 +253,9 @@ protected: uint32_t atomic_write_unit = 4096; bool data_protection_enabled = false; - + device_id_t device_id; + seastore_meta_t meta; + secondary_device_set_t devices; public: NVMeBlockDevice() {} virtual ~NVMeBlockDevice() = default; @@ -251,6 +265,29 @@ public: return std::make_unique(); } + device_id_t get_device_id() const { + return device_id; + } + void set_device_id(device_id_t id) { + device_id = id; + } + + magic_t get_magic() const final { + return magic_t(); + } + + device_type_t get_device_type() const final { + return device_type_t::RANDOM_BLOCK; + } + + const seastore_meta_t &get_meta() const final { + return meta; + } + + secondary_device_set_t& get_secondary_devices() final { + return devices; + } + /* * Service NVMe device relative size * @@ -267,8 +304,9 @@ public: * by SSD even on power failure. The write equal to or smaller than * atomic_write_unit does not require fsync(). */ - uint64_t get_size() const { return size; } - uint64_t get_block_size() const { return block_size; } + + std::size_t get_size() const { return size; } + seastore_off_t get_block_size() const { return block_size; } uint64_t get_preffered_write_granularity() const { return write_granularity; } uint64_t get_preffered_write_alignment() const { return write_alignment; } @@ -298,7 +336,7 @@ public: virtual open_ertr::future<> open( const std::string& path, seastar::open_flags mode) = 0; - virtual seastar::future<> close() = 0; + //virtual seastar::future<> close() = 0; /* * For passsing through nvme IO or Admin command to SSD @@ -371,16 +409,25 @@ public: bufferptr &bptr, uint16_t stream = 0) override; + using NVMeBlockDevice::read; read_ertr::future<> read( uint64_t offset, - bufferptr &bptr) override; + bufferptr &bptr) final; - seastar::future<> close() override; + close_ertr::future<> close() override; discard_ertr::future<> discard( uint64_t offset, uint64_t len) override; + mkfs_ret mkfs(device_config_t) final { + return mkfs_ertr::now(); + } + + mount_ret mount() final { + return mount_ertr::now(); + } + nvme_command_ertr::future pass_admin( nvme_admin_command_t& admin_cmd) override; nvme_command_ertr::future pass_through_io( @@ -418,6 +465,14 @@ public: } } + mkfs_ret mkfs(device_config_t) final { + return mkfs_ertr::now(); + } + + mount_ret mount() final { + return mount_ertr::now(); + } + open_ertr::future<> open( const std::string &in_path, seastar::open_flags mode) override; @@ -427,11 +482,12 @@ public: bufferptr &bptr, uint16_t stream = 0) override; + using NVMeBlockDevice::read; read_ertr::future<> read( uint64_t offset, bufferptr &bptr) override; - seastar::future<> close() override; + close_ertr::future<> close() override; char *buf; size_t size; diff --git a/src/crimson/os/seastore/seastore_types.h b/src/crimson/os/seastore/seastore_types.h index 7e8eece8bd4..df69e39908b 100644 --- a/src/crimson/os/seastore/seastore_types.h +++ b/src/crimson/os/seastore/seastore_types.h @@ -648,10 +648,10 @@ struct seg_paddr_t : public paddr_t { */ paddr_t maybe_relative_to(paddr_t base) const { assert(!base.is_block_relative()); - seg_paddr_t& s = base.as_seg_paddr(); - if (is_block_relative()) + if (is_block_relative()) { + seg_paddr_t& s = base.as_seg_paddr(); return s.add_block_relative(*this); - else + } else return *this; } }; @@ -1174,7 +1174,12 @@ public: void adjust_addrs_from_base(paddr_t base) { paddr_t _root_addr = root_addr; if (_root_addr.is_relative()) { - root_addr = base.add_record_relative(_root_addr); + if (base.get_addr_type() == addr_types_t::SEGMENT) { + root_addr = base.add_record_relative(_root_addr); + } else { + // RANDOM_BLOCK + root_addr = base.add_offset(_root_addr.as_seg_paddr().get_segment_off()); + } } } }; @@ -1794,6 +1799,9 @@ inline paddr_t paddr_t::add_record_relative(paddr_t o) const { inline paddr_t paddr_t::maybe_relative_to(paddr_t o) const { PADDR_OPERATION(addr_types_t::SEGMENT, seg_paddr_t, maybe_relative_to(o)) + if (get_addr_type() == addr_types_t::RANDOM_BLOCK) { + return *this; + } ceph_assert(0 == "not supported type"); return P_ADDR_NULL; } diff --git a/src/crimson/os/seastore/segment_cleaner.cc b/src/crimson/os/seastore/segment_cleaner.cc index 4463de68dca..c337f490b14 100644 --- a/src/crimson/os/seastore/segment_cleaner.cc +++ b/src/crimson/os/seastore/segment_cleaner.cc @@ -586,6 +586,9 @@ void SegmentCleaner::update_journal_tail_target( journal_seq_t alloc_replay_from) { LOG_PREFIX(SegmentCleaner::update_journal_tail_target); + if (dirty_replay_from.offset.get_addr_type() == addr_types_t::RANDOM_BLOCK) { + return; + } if (dirty_extents_replay_from == JOURNAL_SEQ_NULL || dirty_replay_from > dirty_extents_replay_from) { DEBUG("dirty_extents_replay_from={} => {}", diff --git a/src/crimson/os/seastore/segment_cleaner.h b/src/crimson/os/seastore/segment_cleaner.h index 7843d68727e..748b3e9d3c6 100644 --- a/src/crimson/os/seastore/segment_cleaner.h +++ b/src/crimson/os/seastore/segment_cleaner.h @@ -773,6 +773,8 @@ public: time_point last_modified = time_point(), time_point last_rewritten = time_point(), bool init_scan = false) { + if (addr.get_addr_type() != addr_types_t::SEGMENT) + return; auto& seg_addr = addr.as_seg_paddr(); if (!init_scan && !init_complete) @@ -811,6 +813,8 @@ public: const bool force = false) { if (!init_complete && !force) return; + if (addr.get_addr_type() != addr_types_t::SEGMENT) + return; ceph_assert(stats.used_bytes >= len); stats.used_bytes -= len; diff --git a/src/crimson/os/seastore/transaction_manager.cc b/src/crimson/os/seastore/transaction_manager.cc index 005d0ba2fb4..884d4c5e85f 100644 --- a/src/crimson/os/seastore/transaction_manager.cc +++ b/src/crimson/os/seastore/transaction_manager.cc @@ -634,7 +634,7 @@ TransactionManager::get_extent_if_live_ret TransactionManager::get_extent_if_liv TransactionManager::~TransactionManager() {} -TransactionManagerRef make_transaction_manager(bool detailed) +TransactionManagerRef make_transaction_manager(bool detailed, bool cbjournal) { auto epm = std::make_unique(); auto cache = std::make_unique(*epm); @@ -647,7 +647,13 @@ TransactionManagerRef make_transaction_manager(bool detailed) *backref_manager, *cache, detailed); - auto journal = journal::make_segmented(*segment_cleaner); + JournalRef journal; + if (!cbjournal) { + journal = journal::make_segmented(*segment_cleaner); + } else { + journal = journal::make_circularbounded( + nullptr, ""); + } epm->init_ool_writers( *segment_cleaner, segment_cleaner->get_ool_segment_seq_allocator()); diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index 34490baec08..0e5f3b8ac67 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -294,13 +294,14 @@ public: alloc_extent_ret alloc_extent( Transaction &t, laddr_t laddr_hint, - extent_len_t len) { + extent_len_t len, + placement_hint_t hint = placement_hint_t::HOT) { placement_hint_t placement_hint; if constexpr (T::TYPE == extent_types_t::OBJECT_DATA_BLOCK || T::TYPE == extent_types_t::COLL_BLOCK) { placement_hint = placement_hint_t::COLD; } else { - placement_hint = placement_hint_t::HOT; + placement_hint = hint; } LOG_PREFIX(TransactionManager::alloc_extent); SUBTRACET(seastore_tm, "{} len={}, placement_hint={}, laddr_hint={}", @@ -542,10 +543,11 @@ public: dev->get_device_id(), is_primary); epm->add_device(dev, is_primary); - ceph_assert(dev->get_device_type() == device_type_t::SEGMENTED); - auto sm = dynamic_cast(dev); - ceph_assert(sm != nullptr); - sm_group.add_segment_manager(sm); + if (dev->get_device_type() == device_type_t::SEGMENTED) { + auto sm = dynamic_cast(dev); + ceph_assert(sm != nullptr); + sm_group.add_segment_manager(sm); + } } ~TransactionManager(); @@ -583,9 +585,12 @@ public: auto get_cache() { return cache.get(); } + auto get_journal() { + return journal.get(); + } }; using TransactionManagerRef = std::unique_ptr; -TransactionManagerRef make_transaction_manager(bool detailed); +TransactionManagerRef make_transaction_manager(bool detailed, bool cbjournal = false); } diff --git a/src/test/crimson/seastore/nvmedevice/test_nvmedevice.cc b/src/test/crimson/seastore/nvmedevice/test_nvmedevice.cc index 68010f53c4f..a89688f6240 100644 --- a/src/test/crimson/seastore/nvmedevice/test_nvmedevice.cc +++ b/src/test/crimson/seastore/nvmedevice/test_nvmedevice.cc @@ -80,7 +80,7 @@ TEST_F(nvdev_test_t, write_and_verify_test) } int ret = memcmp(original_data.data, read_data.data, BUF_SIZE); - device->close().wait(); + device->close().unsafe_get(); ASSERT_TRUE(ret == 0); device.reset(nullptr); }); diff --git a/src/test/crimson/seastore/test_cbjournal.cc b/src/test/crimson/seastore/test_cbjournal.cc index 79631495527..13da9fc0a40 100644 --- a/src/test/crimson/seastore/test_cbjournal.cc +++ b/src/test/crimson/seastore/test_cbjournal.cc @@ -211,7 +211,7 @@ struct cbjournal_test_t : public seastar_test_suite_t auto replay() { cbj->replay( - [this](const auto &offsets, const auto &e, auto last_modified) + [this](const auto &offsets, const auto &e, auto j_seq, auto last_modified) -> Journal::replay_ret { bool found = false; for (auto &i : entries) { diff --git a/src/test/crimson/seastore/test_transaction_manager.cc b/src/test/crimson/seastore/test_transaction_manager.cc index cfdfef9a6d2..10d8fecd270 100644 --- a/src/test/crimson/seastore/test_transaction_manager.cc +++ b/src/test/crimson/seastore/test_transaction_manager.cc @@ -53,7 +53,8 @@ std::ostream &operator<<(std::ostream &lhs, const test_extent_record_t &rhs) { struct transaction_manager_test_t : public seastar_test_suite_t, - TMTestState { + TMTestState, + ::testing::WithParamInterface { std::random_device rd; std::mt19937 gen; @@ -71,8 +72,22 @@ struct transaction_manager_test_t : return static_cast(std::uniform_int_distribution<>(0, 255)(gen)); } + bool for_segmented() { + std::string j_type = GetParam(); + if (j_type == "segmented") { + return true; + } + return false; + } seastar::future<> set_up_fut() final { - return tm_setup(); + std::string j_type = GetParam(); + if (j_type == "segmented") { + return tm_setup(); + } else if (j_type == "circularbounded") { + return tm_setup(journal_type::CIRCULARBOUNDED_JOURNAL); + } else { + ceph_assert(0 == "no support"); + } } seastar::future<> tear_down_fut() final { @@ -360,9 +375,10 @@ struct transaction_manager_test_t : test_transaction_t &t, laddr_t hint, extent_len_t len, - char contents) { + char contents, + placement_hint_t p_hint = placement_hint_t::HOT) { auto extent = with_trans_intr(*(t.t), [&](auto& trans) { - return tm->alloc_extent(trans, hint, len); + return tm->alloc_extent(trans, hint, len, p_hint); }).unsafe_get0(); extent->set_contents(contents); EXPECT_FALSE(test_mappings.contains(extent->get_laddr(), t.mapping_delta)); @@ -374,12 +390,14 @@ struct transaction_manager_test_t : TestBlockRef alloc_extent( test_transaction_t &t, laddr_t hint, - extent_len_t len) { + extent_len_t len, + placement_hint_t p_hint = placement_hint_t::HOT) { return alloc_extent( t, hint, len, - get_random_contents()); + get_random_contents(), + p_hint); } bool check_usage() { @@ -391,30 +409,36 @@ struct transaction_manager_test_t : return backref_manager->scan_mapped_space( t, [&tracker](auto offset, auto len, depth_t) { - logger().debug("check_usage: tracker alloc {}~{}", - offset, len); - tracker->allocate( - offset.as_seg_paddr().get_segment_id(), - offset.as_seg_paddr().get_segment_off(), - len); + if (offset.get_addr_type() == addr_types_t::SEGMENT) { + logger().debug("check_usage: tracker alloc {}~{}", + offset, len); + tracker->allocate( + offset.as_seg_paddr().get_segment_id(), + offset.as_seg_paddr().get_segment_off(), + len); + } }).si_then([&tracker, this] { auto &backrefs = cache->get_backrefs(); for (auto &backref : backrefs) { - logger().debug("check_usage: by backref, tracker alloc {}~{}", - backref.paddr, backref.len); - tracker->allocate( - backref.paddr.as_seg_paddr().get_segment_id(), - backref.paddr.as_seg_paddr().get_segment_off(), - backref.len); + if (backref.paddr.get_addr_type() == addr_types_t::SEGMENT) { + logger().debug("check_usage: by backref, tracker alloc {}~{}", + backref.paddr, backref.len); + tracker->allocate( + backref.paddr.as_seg_paddr().get_segment_id(), + backref.paddr.as_seg_paddr().get_segment_off(), + backref.len); + } } auto &del_backrefs = cache->get_del_backrefs(); for (auto &del_backref : del_backrefs) { - logger().debug("check_usage: by backref, tracker release {}~{}", - del_backref.paddr, del_backref.len); - tracker->release( - del_backref.paddr.as_seg_paddr().get_segment_id(), - del_backref.paddr.as_seg_paddr().get_segment_off(), - del_backref.len); + if (del_backref.paddr.get_addr_type() == addr_types_t::SEGMENT) { + logger().debug("check_usage: by backref, tracker release {}~{}", + del_backref.paddr, del_backref.len); + tracker->release( + del_backref.paddr.as_seg_paddr().get_segment_id(), + del_backref.paddr.as_seg_paddr().get_segment_off(), + del_backref.len); + } } return seastar::now(); }); @@ -603,7 +627,8 @@ struct transaction_manager_test_t : boost::make_counting_iterator(num), [&, this](auto) { return tm->alloc_extent( - *(t.t), L_ADDR_MIN, size + *(t.t), L_ADDR_MIN, size, + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE ).si_then([&, this](auto extent) { extent->set_contents(get_random_contents()); EXPECT_FALSE( @@ -645,7 +670,8 @@ struct transaction_manager_test_t : auto extent = alloc_extent( t, i * BSIZE, - BSIZE); + BSIZE, + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(i * BSIZE, extent->get_laddr()); if (try_submit_transaction(std::move(t))) break; @@ -701,7 +727,7 @@ struct tm_multi_device_test_t : tm_multi_device_test_t() : transaction_manager_test_t(3) {} }; -TEST_F(tm_single_device_test_t, basic) +TEST_P(tm_single_device_test_t, basic) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -712,7 +738,8 @@ TEST_F(tm_single_device_test_t, basic) t, ADDR, SIZE, - 'a'); + 'a', + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(ADDR, extent->get_laddr()); check_mappings(t); check(); @@ -722,7 +749,7 @@ TEST_F(tm_single_device_test_t, basic) }); } -TEST_F(tm_single_device_test_t, mutate) +TEST_P(tm_single_device_test_t, mutate) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -733,7 +760,8 @@ TEST_F(tm_single_device_test_t, mutate) t, ADDR, SIZE, - 'a'); + 'a', + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(ADDR, extent->get_laddr()); check_mappings(t); check(); @@ -760,7 +788,7 @@ TEST_F(tm_single_device_test_t, mutate) }); } -TEST_F(tm_single_device_test_t, allocate_lba_conflict) +TEST_P(tm_single_device_test_t, allocate_lba_conflict) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -774,7 +802,8 @@ TEST_F(tm_single_device_test_t, allocate_lba_conflict) t, ADDR, SIZE, - 'a'); + 'a', + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(ADDR, extent->get_laddr()); check_mappings(t); check(); @@ -783,7 +812,8 @@ TEST_F(tm_single_device_test_t, allocate_lba_conflict) t2, ADDR2, SIZE, - 'a'); + 'a', + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(ADDR2, extent2->get_laddr()); check_mappings(t2); extent2.reset(); @@ -793,7 +823,7 @@ TEST_F(tm_single_device_test_t, allocate_lba_conflict) }); } -TEST_F(tm_single_device_test_t, mutate_lba_conflict) +TEST_P(tm_single_device_test_t, mutate_lba_conflict) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -803,7 +833,8 @@ TEST_F(tm_single_device_test_t, mutate_lba_conflict) auto extent = alloc_extent( t, laddr_t(i * SIZE), - SIZE); + SIZE, + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); } check_mappings(t); submit_transaction(std::move(t)); @@ -832,7 +863,7 @@ TEST_F(tm_single_device_test_t, mutate_lba_conflict) }); } -TEST_F(tm_single_device_test_t, concurrent_mutate_lba_no_conflict) +TEST_P(tm_single_device_test_t, concurrent_mutate_lba_no_conflict) { constexpr laddr_t SIZE = 4096; constexpr size_t NUM = 500; @@ -845,7 +876,8 @@ TEST_F(tm_single_device_test_t, concurrent_mutate_lba_no_conflict) auto extent = alloc_extent( t, laddr_t(i * SIZE), - SIZE); + SIZE, + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); } submit_transaction(std::move(t)); } @@ -864,7 +896,7 @@ TEST_F(tm_single_device_test_t, concurrent_mutate_lba_no_conflict) }); } -TEST_F(tm_single_device_test_t, create_remove_same_transaction) +TEST_P(tm_single_device_test_t, create_remove_same_transaction) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -875,7 +907,8 @@ TEST_F(tm_single_device_test_t, create_remove_same_transaction) t, ADDR, SIZE, - 'a'); + 'a', + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(ADDR, extent->get_laddr()); check_mappings(t); dec_ref(t, ADDR); @@ -885,7 +918,8 @@ TEST_F(tm_single_device_test_t, create_remove_same_transaction) t, ADDR, SIZE, - 'a'); + 'a', + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); submit_transaction(std::move(t)); check(); @@ -895,7 +929,7 @@ TEST_F(tm_single_device_test_t, create_remove_same_transaction) }); } -TEST_F(tm_single_device_test_t, split_merge_read_same_transaction) +TEST_P(tm_single_device_test_t, split_merge_read_same_transaction) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -905,7 +939,8 @@ TEST_F(tm_single_device_test_t, split_merge_read_same_transaction) auto extent = alloc_extent( t, laddr_t(i * SIZE), - SIZE); + SIZE, + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); } check_mappings(t); submit_transaction(std::move(t)); @@ -925,7 +960,7 @@ TEST_F(tm_single_device_test_t, split_merge_read_same_transaction) }); } -TEST_F(tm_single_device_test_t, inc_dec_ref) +TEST_P(tm_single_device_test_t, inc_dec_ref) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -936,7 +971,8 @@ TEST_F(tm_single_device_test_t, inc_dec_ref) t, ADDR, SIZE, - 'a'); + 'a', + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(ADDR, extent->get_laddr()); check_mappings(t); check(); @@ -972,7 +1008,7 @@ TEST_F(tm_single_device_test_t, inc_dec_ref) }); } -TEST_F(tm_single_device_test_t, cause_lba_split) +TEST_P(tm_single_device_test_t, cause_lba_split) { constexpr laddr_t SIZE = 4096; run_async([this] { @@ -982,7 +1018,8 @@ TEST_F(tm_single_device_test_t, cause_lba_split) t, i * SIZE, SIZE, - (char)(i & 0xFF)); + (char)(i & 0xFF), + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(i * SIZE, extent->get_laddr()); submit_transaction(std::move(t)); } @@ -990,7 +1027,7 @@ TEST_F(tm_single_device_test_t, cause_lba_split) }); } -TEST_F(tm_single_device_test_t, random_writes) +TEST_P(tm_single_device_test_t, random_writes) { constexpr size_t TOTAL = 4<<20; constexpr size_t BSIZE = 4<<10; @@ -1002,7 +1039,8 @@ TEST_F(tm_single_device_test_t, random_writes) auto extent = alloc_extent( t, i * BSIZE, - BSIZE); + BSIZE, + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); ASSERT_EQ(i * BSIZE, extent->get_laddr()); submit_transaction(std::move(t)); } @@ -1020,7 +1058,8 @@ TEST_F(tm_single_device_test_t, random_writes) auto padding = alloc_extent( t, TOTAL + (k * PADDING_SIZE), - PADDING_SIZE); + PADDING_SIZE, + for_segmented() ? placement_hint_t::HOT : placement_hint_t::REWRITE); dec_ref(t, padding->get_laddr()); } submit_transaction(std::move(t)); @@ -1033,7 +1072,7 @@ TEST_F(tm_single_device_test_t, random_writes) }); } -TEST_F(tm_single_device_test_t, find_hole_assert_trigger) +TEST_P(tm_single_device_test_t, find_hole_assert_trigger) { constexpr unsigned max = 10; constexpr size_t BSIZE = 4<<10; @@ -1048,12 +1087,30 @@ TEST_F(tm_single_device_test_t, find_hole_assert_trigger) }); } -TEST_F(tm_single_device_test_t, random_writes_concurrent) +TEST_P(tm_single_device_test_t, random_writes_concurrent) { test_random_writes_concurrent(); } -TEST_F(tm_multi_device_test_t, random_writes_concurrent) +TEST_P(tm_multi_device_test_t, random_writes_concurrent) { test_random_writes_concurrent(); } + +INSTANTIATE_TEST_SUITE_P( + transaction_manager_test, + tm_single_device_test_t, + ::testing::Values ( + "segmented", + "circularbounded" + ) +); + +INSTANTIATE_TEST_SUITE_P( + transaction_manager_test, + tm_multi_device_test_t, + ::testing::Values ( + "segmented", + "circularbounded" + ) +); diff --git a/src/test/crimson/seastore/transaction_manager_test_state.h b/src/test/crimson/seastore/transaction_manager_test_state.h index 92cf2115ac4..072bb8eaecf 100644 --- a/src/test/crimson/seastore/transaction_manager_test_state.h +++ b/src/test/crimson/seastore/transaction_manager_test_state.h @@ -14,6 +14,8 @@ #include "crimson/os/seastore/segment_manager.h" #include "crimson/os/seastore/collection_manager/flat_collection_manager.h" #include "crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h" +#include "crimson/os/seastore/random_block_manager/nvmedevice.h" +#include "crimson/os/seastore/journal/circular_bounded_journal.h" using namespace crimson; using namespace crimson::os; @@ -23,6 +25,8 @@ class EphemeralTestState { protected: segment_manager::EphemeralSegmentManagerRef segment_manager; std::list secondary_segment_managers; + std::unique_ptr rb_device; + journal_type j_type = journal_type::SEGMENT_JOURNAL; EphemeralTestState(std::size_t num_segment_managers) { assert(num_segment_managers > 0); @@ -58,11 +62,19 @@ protected: _mount().handle_error(crimson::ct_error::assert_all{}).get0(); } - seastar::future<> tm_setup() { + seastar::future<> tm_setup(journal_type j_type = journal_type::SEGMENT_JOURNAL) { + this->j_type = j_type; segment_manager = segment_manager::create_test_ephemeral(); for (auto &sec_sm : secondary_segment_managers) { sec_sm = segment_manager::create_test_ephemeral(); } + if (j_type == journal_type::CIRCULARBOUNDED_JOURNAL) { + auto config = + journal::CircularBoundedJournal::mkfs_config_t::get_default(); + rb_device.reset(new nvme_device::TestMemory(config.total_size)); + rb_device->set_device_id( + 1 << (std::numeric_limits::digits - 1)); + } return segment_manager->init( ).safe_then([this] { return crimson::do_for_each( @@ -109,6 +121,9 @@ protected: for (auto &sec_sm : secondary_segment_managers) { sec_sm.reset(); } + if (j_type == journal_type::CIRCULARBOUNDED_JOURNAL) { + rb_device.reset(); + } }); } }; @@ -139,8 +154,14 @@ protected: TMTestState(std::size_t num_devices) : EphemeralTestState(num_devices) {} virtual void _init() override { - tm = make_transaction_manager(true); + tm = make_transaction_manager(true, + j_type == journal_type::SEGMENT_JOURNAL ? false : true); tm->add_device(segment_manager.get(), true); + if (j_type == journal_type::CIRCULARBOUNDED_JOURNAL) { + tm->add_device(rb_device.get(), false); + static_cast(tm->get_journal())-> + add_device(rb_device.get()); + } if (get_num_devices() > 1) { for (auto &sec_sm : secondary_segment_managers) { tm->add_device(sec_sm.get(), false); @@ -179,10 +200,24 @@ protected: } virtual FuturizedStore::mkfs_ertr::future<> _mkfs() { - return tm->mkfs( - ).handle_error( - crimson::ct_error::assert_all{"Error in teardown"} - ); + if (j_type == journal_type::SEGMENT_JOURNAL) { + return tm->mkfs( + ).handle_error( + crimson::ct_error::assert_all{"Error in mkfs"} + ); + } else { + auto config = journal::CircularBoundedJournal::mkfs_config_t::get_default(); + return static_cast(tm->get_journal())->mkfs( + config + ).safe_then([this]() { + return tm->mkfs( + ).handle_error( + crimson::ct_error::assert_all{"Error in mkfs"} + ); + }).handle_error( + crimson::ct_error::assert_all{"Error in mkfs"} + ); + } } auto create_mutate_transaction() { -- 2.39.5