From: Xuehan Xu Date: Tue, 6 Apr 2021 08:42:04 +0000 (+0800) Subject: crimson/os/seastore: add write/read_meta methods for seastore X-Git-Tag: v17.1.0~2162^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=85a180a765949f28060d73c7774b6142179f7101;p=ceph.git crimson/os/seastore: add write/read_meta methods for seastore Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index 9c6ff428a5c..ea0fb10b5dd 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -209,8 +209,9 @@ std::optional Cache::try_construct_record(Transaction &t) { // First, validate read set for (auto &i: t.read_set) { - if (i->state == CachedExtent::extent_state_t::INVALID) + if (i->state == CachedExtent::extent_state_t::INVALID) { return std::nullopt; + } } record_t record; diff --git a/src/crimson/os/seastore/root_block.h b/src/crimson/os/seastore/root_block.h index 57d64ad7ca1..fe7bdf99316 100644 --- a/src/crimson/os/seastore/root_block.h +++ b/src/crimson/os/seastore/root_block.h @@ -38,6 +38,8 @@ struct RootBlock : CachedExtent { root_t root; + std::map meta; + RootBlock() : CachedExtent(0) {} RootBlock(const RootBlock &rhs) = default; @@ -66,6 +68,11 @@ struct RootBlock : CachedExtent { ceph::bufferlist bl = _bl; bl.rebuild(); root = *reinterpret_cast(bl.front().c_str()); + if (root.have_meta) { + ceph::bufferlist meta_bl; + meta_bl.rebuild(ceph::buffer::ptr_node::create(&root.meta[0], root_t::MAX_META_LENGTH)); + decode(meta, meta_bl); + } root.adjust_addrs_from_base(base); } @@ -83,6 +90,7 @@ struct RootBlock : CachedExtent { } root_t &get_root() { return root; } + }; using RootBlockRef = RootBlock::Ref; diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index b44a3290b91..8a477b591d8 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -911,13 +911,41 @@ boost::intrusive_ptr SeaStore::_get_collection(const coll_t& seastar::future<> SeaStore::write_meta(const std::string& key, const std::string& value) { - return seastar::make_ready_future<>(); + logger().debug("{}, key: {}; value: {}", __func__, key, value); + return seastar::do_with(key, value, + [this](auto& key, auto& value) { + return repeat_eagain([this, &key, &value] { + auto t = transaction_manager->create_transaction(); + return transaction_manager->get_root(*t).safe_then( + [this, t=std::move(t), &key, &value](auto root) mutable { + transaction_manager->update_root_meta(*t, key, value); + return transaction_manager->submit_transaction(std::move(t)); + }); + }); + }).handle_error( + crimson::ct_error::assert_all{"Invalid error in Seastar::write_meta"} + ); } seastar::future> SeaStore::read_meta(const std::string& key) { - return seastar::make_ready_future>( - std::make_tuple(0, ""s)); + logger().debug("{}, key: {}", __func__, key); + return seastar::do_with(transaction_manager->create_transaction(), key, + [this](auto& t, auto& key) { + return transaction_manager->get_root(*t).safe_then( + [this, &key](auto root) { + auto& meta = root->meta; + auto it = meta.find(key); + if (it != meta.end()) { + return seastar::make_ready_future>( + std::make_tuple(0, it->second)); + } + return seastar::make_ready_future>( + std::make_tuple(-1, std::string(""))); + }); + }).handle_error( + crimson::ct_error::assert_all{"Invalid error in Seastar::write_meta"} + ); } uuid_d SeaStore::get_fsid() const diff --git a/src/crimson/os/seastore/seastore_types.h b/src/crimson/os/seastore/seastore_types.h index 59b329c0fcc..9b0e43fb801 100644 --- a/src/crimson/os/seastore/seastore_types.h +++ b/src/crimson/os/seastore/seastore_types.h @@ -655,9 +655,14 @@ public: * TODO: generalize this to permit more than one lba_manager implementation */ struct __attribute__((packed)) root_t { + + static constexpr int MAX_META_LENGTH = 1024; + lba_root_t lba_root; laddr_le_t onode_root; coll_root_le_t collection_root; + char meta[MAX_META_LENGTH]; + bool have_meta = false; void adjust_addrs_from_base(paddr_t base) { lba_root.adjust_addrs_from_base(base); diff --git a/src/crimson/os/seastore/transaction.h b/src/crimson/os/seastore/transaction.h index d17907a3fa9..7a46e5c2993 100644 --- a/src/crimson/os/seastore/transaction.h +++ b/src/crimson/os/seastore/transaction.h @@ -15,6 +15,7 @@ namespace crimson::os::seastore { struct retired_extent_gate_t; +class SeaStore; /** * Transaction @@ -161,6 +162,8 @@ public: write_set.erase(*i++); } } + + friend class crimson::os::seastore::SeaStore; }; using TransactionRef = Transaction::Ref; diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index a49af8c9e5c..68736657f09 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -374,6 +374,53 @@ public: return segment_manager.release(id); } + /** + * get_root + * + * Get root block's ondisk layout + */ + using get_root_ertr = base_ertr; + using get_root_ret = get_root_ertr::future; + get_root_ret get_root(Transaction &t) { + return cache->get_root(t); + } + + /** + * update_root_meta + * + * modify root block's meta field + */ + using update_root_meta_ertr = base_ertr::extend< + crimson::ct_error::value_too_large>; + using update_root_meta_ret = update_root_meta_ertr::future<>; + update_root_meta_ret update_root_meta(Transaction& t, + const std::string& key, + const std::string& value) { + auto root = cache->get_root_fast(t); + root = cache->duplicate_for_write(t, root)->cast(); + root->meta[key] = value; + + // calculate meta size + // TODO: we probably need a uniformal interface for calcuting + // the encoded size of data structures + uint32_t meta_size = 4; // initial 4 bytes for std::map size + for (auto& [key, val] : root->meta) { + // sizes of length fields for key and val + sizes of key and val + meta_size += 8 + key.length() + val.length(); + } + + if (meta_size > root_t::MAX_META_LENGTH) { + return crimson::ct_error::value_too_large::make(); + } + + ceph::bufferlist bl(1); + bl.rebuild(ceph::buffer::ptr_node::create( + &root->get_root().meta[0], root_t::MAX_META_LENGTH)); + encode(root->meta, bl); + root->get_root().have_meta = true; + return update_root_meta_ertr::now(); + } + /** * read_onode_root *