From dd7244075e244521553508e2cb2ba8cb3a33cc05 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Wed, 10 Feb 2021 18:58:58 -0800 Subject: [PATCH] crimson/os/seastore: wire up FLTreeOnodeManager and FlatCollectionManager Signed-off-by: Samuel Just --- src/crimson/os/seastore/CMakeLists.txt | 1 + src/crimson/os/seastore/seastore.cc | 183 +++++++++++++++--- src/crimson/os/seastore/seastore.h | 32 +++ src/test/crimson/seastore/CMakeLists.txt | 10 + src/test/crimson/seastore/test_seastore.cc | 113 +++++++++++ .../seastore/transaction_manager_test_state.h | 52 +++++ 6 files changed, 364 insertions(+), 27 deletions(-) create mode 100644 src/test/crimson/seastore/test_seastore.cc diff --git a/src/crimson/os/seastore/CMakeLists.txt b/src/crimson/os/seastore/CMakeLists.txt index 39fe5bdfef012..79777fb7aa87d 100644 --- a/src/crimson/os/seastore/CMakeLists.txt +++ b/src/crimson/os/seastore/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(crimson-seastore STATIC onode_manager/staged-fltree/stages/sub_items_stage.cc onode_manager/staged-fltree/super.cc onode_manager/staged-fltree/value.cc + onode_manager/staged-fltree/fltree_onode_manager.cc extentmap_manager.cc extentmap_manager/btree/extentmap_btree_node_impl.cc extentmap_manager/btree/btree_extentmap_manager.cc diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index f9221294cc00c..8edf97648a0f6 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -3,6 +3,8 @@ #include "seastore.h" +#include + #include #include #include @@ -37,12 +39,23 @@ struct SeastoreCollection final : public FuturizedCollection { seastar::future<> SeaStore::stop() { - return seastar::now(); + return transaction_manager->close( + ).handle_error( + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::stop" + } + ); + } seastar::future<> SeaStore::mount() { - return seastar::now(); + return transaction_manager->mount( + ).handle_error( + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::mount" + } + ); } seastar::future<> SeaStore::umount() @@ -52,7 +65,27 @@ seastar::future<> SeaStore::umount() seastar::future<> SeaStore::mkfs(uuid_d new_osd_fsid) { - return seastar::now(); + return transaction_manager->mkfs( + ).safe_then([this] { + return seastar::do_with( + make_transaction(), + [this](auto &t) { + return onode_manager->mkfs(*t + ).safe_then([this, &t] { + return collection_manager->mkfs(*t); + }).safe_then([this, &t](auto coll_root) { + transaction_manager->write_collection_root( + *t, + coll_root); + return transaction_manager->submit_transaction( + std::move(t)); + }); + }); + }).handle_error( + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::mkfs" + } + ); } seastar::future SeaStore::stat() const @@ -75,7 +108,20 @@ SeaStore::list_objects(CollectionRef ch, seastar::future SeaStore::create_new_collection(const coll_t& cid) { auto c = _get_collection(cid); - return seastar::make_ready_future(c); + return repeat_with_internal_context( + c, + ceph::os::Transaction{}, + [this, cid](auto &ctx) { + return _create_collection( + ctx, + cid, + 4 /* TODO */ + ).safe_then([this, &ctx] { + return transaction_manager->submit_transaction(std::move(ctx.transaction)); + }); + }).then([c] { + return CollectionRef(c); + }); } seastar::future SeaStore::open_collection(const coll_t& cid) @@ -85,7 +131,34 @@ seastar::future SeaStore::open_collection(const coll_t& cid) seastar::future> SeaStore::list_collections() { - return seastar::make_ready_future>(); + return seastar::do_with( + std::vector(), + [this](auto &ret) { + return repeat_eagain([this, &ret] { + + return seastar::do_with( + make_transaction(), + [this, &ret](auto &t) { + return transaction_manager->read_collection_root(*t + ).safe_then([this, &ret, &t](auto coll_root) { + return collection_manager->list( + coll_root, + *t); + }).safe_then([this, &ret, &t](auto colls) { + ret.resize(colls.size()); + std::transform( + colls.begin(), colls.end(), ret.begin(), + [](auto p) { return p.first; }); + }); + }); + }).safe_then([&ret] { + return seastar::make_ready_future>(ret); + }); + }).handle_error( + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::list_collections" + } + ); } SeaStore::read_errorator::future SeaStore::read( @@ -128,20 +201,26 @@ SeaStore::get_attrs_ertr::future SeaStore::get_attrs( return crimson::ct_error::enoent::make(); } -seastar::future stat( - CollectionRef c, - const ghobject_t& oid) -{ - return seastar::make_ready_future(); -} - - seastar::future SeaStore::stat( CollectionRef c, const ghobject_t& oid) { - struct stat st; - return seastar::make_ready_future(st); + return repeat_with_onode( + c, + oid, + [=](auto &t, auto &onode) { + struct stat st; + auto &olayout = onode.get_layout(); + st.st_size = olayout.size; + st.st_blksize = 4096; + st.st_blocks = (st.st_size + st.st_blksize - 1) / st.st_blksize; + st.st_nlink = 1; + return seastar::make_ready_future(); + }).handle_error( + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::stat" + } + ); } auto @@ -305,6 +384,12 @@ SeaStore::tm_ret SeaStore::_do_transaction_step( return _create_collection(ctx, cid, op->split_bits); } break; + case Transaction::OP_RMCOLL: + { + coll_t cid = i.get_cid(op->cid); + return _remove_collection(ctx, cid); + } + break; case Transaction::OP_OMAP_SETKEYS: { std::map aset; @@ -377,17 +462,6 @@ SeaStore::tm_ret SeaStore::_write( logger().debug("{}: {} {} ~ {}", __func__, *onode, offset, len); assert(len == bl.length()); - -/* - return onode_manager->get_or_create_onode(cid, oid).safe_then([=, &bl](auto ref) { - return; - }).handle_error( - crimson::ct_error::enoent::handle([]() { - return; - }), - OnodeManager::open_ertr::pass_further{} - ); - */ return tm_ertr::now(); } @@ -461,7 +535,62 @@ SeaStore::tm_ret SeaStore::_create_collection( internal_context_t &ctx, const coll_t& cid, int bits) { - return tm_ertr::now(); + return transaction_manager->read_collection_root( + *ctx.transaction + ).safe_then([=, &ctx](auto _cmroot) { + return seastar::do_with( + _cmroot, + [=, &ctx](auto &cmroot) { + return collection_manager->create( + cmroot, + *ctx.transaction, + cid, + bits + ).safe_then([=, &ctx, &cmroot] { + if (cmroot.must_update()) { + transaction_manager->write_collection_root( + *ctx.transaction, + cmroot); + } + }); + }); + }).handle_error( + tm_ertr::pass_further{}, + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::_create_collection" + } + ); +} + +SeaStore::tm_ret SeaStore::_remove_collection( + internal_context_t &ctx, + const coll_t& cid) +{ + return transaction_manager->read_collection_root( + *ctx.transaction + ).safe_then([=, &ctx](auto _cmroot) { + return seastar::do_with( + _cmroot, + [=, &ctx](auto &cmroot) { + return collection_manager->remove( + cmroot, + *ctx.transaction, + cid + ).safe_then([=, &ctx, &cmroot] { + // param here denotes whether it already existed, probably error + if (cmroot.must_update()) { + transaction_manager->write_collection_root( + *ctx.transaction, + cmroot); + } + }); + }); + }).handle_error( + tm_ertr::pass_further{}, + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::_create_collection" + } + ); } boost::intrusive_ptr SeaStore::_get_collection(const coll_t& cid) diff --git a/src/crimson/os/seastore/seastore.h b/src/crimson/os/seastore/seastore.h index 3bdc7bdb22905..1d5627201e074 100644 --- a/src/crimson/os/seastore/seastore.h +++ b/src/crimson/os/seastore/seastore.h @@ -15,6 +15,7 @@ #include "include/uuid.h" #include "os/Transaction.h" +#include "crimson/os/futurized_collection.h" #include "crimson/os/futurized_store.h" #include "crimson/os/seastore/transaction.h" #include "crimson/os/seastore/onode_manager.h" @@ -166,6 +167,34 @@ private: }); } + template + auto repeat_with_onode( + CollectionRef ch, + const ghobject_t &oid, + F &&f) { + return seastar::do_with( + oid, + Ret{}, + TransactionRef(), + OnodeRef(), + std::forward(f), + [=](auto &oid, auto &ret, auto &t, auto &onode, auto &f) { + return repeat_eagain([&, this] { + t = make_transaction(); + return onode_manager->get_onode( + *t, oid + ).safe_then([&, this](auto onode_ret) { + onode = std::move(onode_ret); + return f(*t, *onode); + }).safe_then([&ret](auto _ret) { + ret = _ret; + }); + }).safe_then([&ret] { + return seastar::make_ready_future(ret); + }); + }); + } + TransactionManagerRef transaction_manager; CollectionManagerRef collection_manager; OnodeManagerRef onode_manager; @@ -216,6 +245,9 @@ private: tm_ret _create_collection( internal_context_t &ctx, const coll_t& cid, int bits); + tm_ret _remove_collection( + internal_context_t &ctx, + const coll_t& cid); boost::intrusive_ptr _get_collection(const coll_t& cid); }; diff --git a/src/test/crimson/seastore/CMakeLists.txt b/src/test/crimson/seastore/CMakeLists.txt index bbe47d34bad24..7155704a4bc98 100644 --- a/src/test/crimson/seastore/CMakeLists.txt +++ b/src/test/crimson/seastore/CMakeLists.txt @@ -67,4 +67,14 @@ target_link_libraries( ${CMAKE_DL_LIBS} crimson-seastore) +add_executable(unittest-seastore + test_seastore.cc + ../gtest_seastar.cc) +add_ceph_unittest(unittest-seastore) +target_link_libraries( + unittest-seastore + ${CMAKE_DL_LIBS} + crimson-seastore + crimson-common) + add_subdirectory(onode_tree) diff --git a/src/test/crimson/seastore/test_seastore.cc b/src/test/crimson/seastore/test_seastore.cc new file mode 100644 index 0000000000000..fd6f6452b504a --- /dev/null +++ b/src/test/crimson/seastore/test_seastore.cc @@ -0,0 +1,113 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include +#include +#include + +#include "test/crimson/gtest_seastar.h" + +#include "test/crimson/seastore/transaction_manager_test_state.h" + +#include "crimson/os/futurized_collection.h" +#include "crimson/os/seastore/seastore.h" + +using namespace crimson; +using namespace crimson::os; +using namespace crimson::os::seastore; +using CTransaction = ceph::os::Transaction; +using namespace std; + +namespace { + [[maybe_unused]] seastar::logger& logger() { + return crimson::get_logger(ceph_subsys_test); + } +} + + +struct seastore_test_t : + public seastar_test_suite_t, + SeaStoreTestState { + + coll_t coll_name{spg_t{pg_t{0, 0}}}; + CollectionRef coll; + + seastore_test_t() {} + + seastar::future<> set_up_fut() final { + return tm_setup( + ).then([this] { + return seastore->create_new_collection(coll_name); + }).then([this](auto coll_ref) { + coll = coll_ref; + }); + } + + seastar::future<> tear_down_fut() final { + return tm_teardown(); + } + + void do_transaction(CTransaction &&t) { + return seastore->do_transaction( + coll, + std::move(t)).get0(); + } +}; + +ghobject_t make_oid(int i) { + stringstream ss; + ss << "object_" << i; + auto ret = ghobject_t( + hobject_t( + sobject_t(ss.str(), CEPH_NOSNAP))); + ret.hobj.nspace = "asdf"; + return ret; +} + +template +auto contains(const T &t, const V &v) { + return std::find( + t.begin(), + t.end(), + v) != t.end(); +} + +TEST_F(seastore_test_t, collection_create_list_remove) +{ + run_async([this] { + coll_t test_coll{spg_t{pg_t{1, 0}}}; + { + seastore->create_new_collection(test_coll).get0(); + auto collections = seastore->list_collections().get0(); + EXPECT_EQ(collections.size(), 2); + EXPECT_TRUE(contains(collections, coll_name)); + EXPECT_TRUE(contains(collections, test_coll)); + } + + { + CTransaction t; + t.remove_collection(test_coll); + do_transaction(std::move(t)); + auto collections = seastore->list_collections().get0(); + EXPECT_EQ(collections.size(), 1); + EXPECT_TRUE(contains(collections, coll_name)); + } + }); +} + +TEST_F(seastore_test_t, touch_stat) +{ + run_async([this] { + auto test = make_oid(0); + { + CTransaction t; + t.touch(coll_name, test); + do_transaction(std::move(t)); + + auto result = seastore->stat( + coll, + test).get0(); + EXPECT_EQ(result.st_size, 0); + } + }); +} diff --git a/src/test/crimson/seastore/transaction_manager_test_state.h b/src/test/crimson/seastore/transaction_manager_test_state.h index ed422329669de..0158da44ce0dc 100644 --- a/src/test/crimson/seastore/transaction_manager_test_state.h +++ b/src/test/crimson/seastore/transaction_manager_test_state.h @@ -9,7 +9,10 @@ #include "crimson/os/seastore/cache.h" #include "crimson/os/seastore/transaction_manager.h" #include "crimson/os/seastore/segment_manager/ephemeral.h" +#include "crimson/os/seastore/seastore.h" #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" using namespace crimson; using namespace crimson::os; @@ -87,6 +90,28 @@ auto get_transaction_manager( return ret; } +auto get_seastore( + SegmentManager &segment_manager +) { + auto segment_cleaner = std::make_unique( + SegmentCleaner::config_t::default_from_segment_manager( + segment_manager), + true); + auto journal = std::make_unique(segment_manager); + auto cache = std::make_unique(segment_manager); + auto lba_manager = lba_manager::create_lba_manager(segment_manager, *cache); + + journal->set_segment_provider(&*segment_cleaner); + + auto tm = get_transaction_manager(segment_manager); + auto cm = std::make_unique(*tm); + return std::make_unique( + std::move(tm), + std::move(cm), + std::make_unique(*tm)); +} + + class TMTestState : public EphemeralTestState { protected: std::unique_ptr tm; @@ -128,3 +153,30 @@ protected: ); } }; + +class SeaStoreTestState : public EphemeralTestState { +protected: + std::unique_ptr seastore; + + SeaStoreTestState() : EphemeralTestState() {} + + virtual void _init() { + seastore = get_seastore(*segment_manager); + } + + virtual void _destroy() { + seastore.reset(); + } + + virtual seastar::future<> _teardown() { + return seastore->stop(); + } + + virtual seastar::future<> _mount() { + return seastore->mount(); + } + + virtual seastar::future<> _mkfs() { + return seastore->mkfs(uuid_d{}); + } +}; -- 2.39.5