From: Samuel Just Date: Wed, 28 Apr 2021 07:24:00 +0000 (-0700) Subject: crimson/os/seastore: clean up meta implementation X-Git-Tag: v17.1.0~2043^2~14 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=644b58a1e630a33b82f2acccbaa805e4671ca1b5;p=ceph.git crimson/os/seastore: clean up meta implementation There's really no reason to cache the decoded representation here since the meta keys are only accessed during startup, mkfs. This approach is much simpler. Signed-off-by: Samuel Just --- diff --git a/src/crimson/os/seastore/root_block.h b/src/crimson/os/seastore/root_block.h index fe7bdf993168..3144edb82512 100644 --- a/src/crimson/os/seastore/root_block.h +++ b/src/crimson/os/seastore/root_block.h @@ -38,8 +38,6 @@ struct RootBlock : CachedExtent { root_t root; - std::map meta; - RootBlock() : CachedExtent(0) {} RootBlock(const RootBlock &rhs) = default; @@ -68,11 +66,6 @@ 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); } diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index 814bde35eff7..8455a94e033e 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -997,41 +997,51 @@ seastar::future<> SeaStore::write_meta(const std::string& key, { LOG_PREFIX(SeaStore::write_meta); DEBUG("key: {}; value: {}", 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)); + return seastar::do_with( + TransactionRef(), + key, + value, + [this, FNAME](auto &t, auto& key, auto& value) { + return repeat_eagain([this, FNAME, &t, &key, &value] { + t = transaction_manager->create_transaction(); + DEBUGT("Have transaction, key: {}; value: {}", *t, key, value); + return transaction_manager->update_root_meta( + *t, key, value + ).safe_then([this, &t] { + return transaction_manager->submit_transaction(std::move(t)); + }); }); - }); - }).handle_error( - crimson::ct_error::assert_all{"Invalid error in Seastar::write_meta"} - ); + }).handle_error( + crimson::ct_error::assert_all{"Invalid error in SeaStore::write_meta"} + ); } seastar::future> SeaStore::read_meta(const std::string& key) { LOG_PREFIX(SeaStore::read_meta); DEBUG("key: {}", 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"} - ); + return seastar::do_with( + std::tuple(), + TransactionRef(), + key, + [this](auto &ret, auto &t, auto& key) { + return repeat_eagain([this, &ret, &t, &key] { + t = transaction_manager->create_transaction(); + return transaction_manager->read_root_meta( + *t, key + ).safe_then([&ret](auto v) { + if (v) { + ret = std::make_tuple(0, std::move(*v)); + } else { + ret = std::make_tuple(-1, std::string("")); + } + }); + }).safe_then([&ret] { + return std::move(ret); + }); + }).handle_error( + crimson::ct_error::assert_all{"Invalid error in SeaStore::read_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 9b0e43fb801b..c2bd7d3cbef8 100644 --- a/src/crimson/os/seastore/seastore_types.h +++ b/src/crimson/os/seastore/seastore_types.h @@ -655,18 +655,42 @@ public: * TODO: generalize this to permit more than one lba_manager implementation */ struct __attribute__((packed)) root_t { + using meta_t = std::map; 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; + + root_t() { + set_meta(meta_t{}); + } void adjust_addrs_from_base(paddr_t base) { lba_root.adjust_addrs_from_base(base); } + + meta_t get_meta() { + bufferlist bl; + bl.append(ceph::buffer::create_static(MAX_META_LENGTH, meta)); + meta_t ret; + auto iter = bl.cbegin(); + decode(ret, iter); + return ret; + } + + void set_meta(const meta_t &m) { + ceph::bufferlist bl; + encode(m, bl); + ceph_assert(bl.length() < MAX_META_LENGTH); + bl.rebuild(); + auto &bptr = bl.front(); + ::memset(meta, 0, MAX_META_LENGTH); + ::memcpy(meta, bptr.c_str(), bl.length()); + } }; } diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index 07125396d0b0..75f0ed6537ea 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -373,50 +373,52 @@ public: } /** - * get_root + * read_root_meta * - * Get root block's ondisk layout + * Read root block meta entry for key. */ - 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); + using read_root_meta_ertr = base_ertr; + using read_root_meta_bare = std::optional; + using read_root_meta_ret = read_root_meta_ertr::future< + read_root_meta_bare>; + read_root_meta_ret read_root_meta( + Transaction &t, + const std::string &key) { + return cache->get_root( + t + ).safe_then([&key](auto root) { + auto meta = root->root.get_meta(); + auto iter = meta.find(key); + if (iter == meta.end()) { + return seastar::make_ready_future(std::nullopt); + } else { + return seastar::make_ready_future(iter->second); + } + }); } /** * update_root_meta * - * modify root block's meta field + * Update root block meta entry for key to value. */ - using update_root_meta_ertr = base_ertr::extend< - crimson::ct_error::value_too_large>; + using update_root_meta_ertr = base_ertr; 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(); + update_root_meta_ret update_root_meta( + Transaction& t, + const std::string& key, + const std::string& value) { + return cache->get_root( + t + ).safe_then([this, &t, &key, &value](RootBlockRef root) { + root = cache->duplicate_for_write(t, root)->cast(); + + auto meta = root->root.get_meta(); + meta[key] = value; + + root->root.set_meta(meta); + return seastar::now(); + }); } /**