From: Yingxin Cheng Date: Fri, 21 Jun 2024 05:48:32 +0000 (+0800) Subject: crimson/os/seastore/seastore_types: introduce record_type_t::OOL X-Git-Tag: v19.1.1~40^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=ce0755ad1a3e3307344f4e1dd04d6880f1b0bd08;p=ceph.git crimson/os/seastore/seastore_types: introduce record_type_t::OOL And adjust size calculations for record_type_t::OOL, should be no actual impact yet. Signed-off-by: Yingxin Cheng (cherry picked from commit c837cd07428b082cbe2726995f0a672c07544a31) --- diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index a737b2be29ca7..46bcffcd95a7a 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -1136,7 +1136,7 @@ record_t Cache::prepare_record( t.read_set.clear(); t.write_set.clear(); - record_t record(trans_src); + record_t record(record_type_t::JOURNAL, trans_src); auto commit_time = seastar::lowres_system_clock::now(); // Add new copy of mutated blocks, set_io_wait to block until written diff --git a/src/crimson/os/seastore/extent_placement_manager.cc b/src/crimson/os/seastore/extent_placement_manager.cc index 9b814555b4591..2c59ec590ba59 100644 --- a/src/crimson/os/seastore/extent_placement_manager.cc +++ b/src/crimson/os/seastore/extent_placement_manager.cc @@ -84,7 +84,7 @@ SegmentedOolWriter::do_write( return do_write(t, extents); }); } - record_t record(t.get_src()); + record_t record(record_type_t::JOURNAL, t.get_src()); std::list pending_extents; auto commit_time = seastar::lowres_system_clock::now(); diff --git a/src/crimson/os/seastore/seastore_types.cc b/src/crimson/os/seastore/seastore_types.cc index 1a5d3d3c83c79..070efa0c04690 100644 --- a/src/crimson/os/seastore/seastore_types.cc +++ b/src/crimson/os/seastore/seastore_types.cc @@ -388,20 +388,32 @@ std::ostream &operator<<(std::ostream &out, const segment_tail_t &tail) extent_len_t record_size_t::get_raw_mdlength() const { + assert(record_type < record_type_t::MAX); // empty record is allowed to submit - return plain_mdlength + - ceph::encoded_sizeof_bounded(); + extent_len_t ret = plain_mdlength; + if (record_type == record_type_t::JOURNAL) { + ret += ceph::encoded_sizeof_bounded(); + } else { + // OOL won't contain metadata + assert(ret == 0); + } + return ret; } void record_size_t::account_extent(extent_len_t extent_len) { assert(extent_len); - plain_mdlength += ceph::encoded_sizeof_bounded(); + if (record_type == record_type_t::JOURNAL) { + plain_mdlength += ceph::encoded_sizeof_bounded(); + } else { + // OOL won't contain metadata + } dlength += extent_len; } void record_size_t::account(const delta_info_t& delta) { + assert(record_type == record_type_t::JOURNAL); assert(delta.bl.length()); plain_mdlength += ceph::encoded_sizeof(delta); } @@ -433,11 +445,28 @@ std::ostream &operator<<(std::ostream &os, transaction_type_t type) std::ostream &operator<<(std::ostream& out, const record_size_t& rsize) { return out << "record_size_t(" + << "record_type=" << rsize.record_type << "raw_md=" << rsize.get_raw_mdlength() << ", data=" << rsize.dlength << ")"; } +std::ostream &operator<<(std::ostream& out, const record_type_t& type) +{ + switch (type) { + case record_type_t::JOURNAL: + return out << "JOURNAL"; + case record_type_t::OOL: + return out << "OOL"; + case record_type_t::MAX: + return out << "NULL"; + default: + return out << "INVALID_RECORD_TYPE(" + << static_cast(type) + << ")"; + } +} + std::ostream &operator<<(std::ostream& out, const record_t& r) { return out << "record_t(" @@ -472,9 +501,16 @@ std::ostream& operator<<(std::ostream& out, const record_group_header_t& h) extent_len_t record_group_size_t::get_raw_mdlength() const { - return plain_mdlength + - sizeof(checksum_t) + - ceph::encoded_sizeof_bounded(); + assert(record_type < record_type_t::MAX); + extent_len_t ret = plain_mdlength; + if (record_type == record_type_t::JOURNAL) { + ret += sizeof(checksum_t); + ret += ceph::encoded_sizeof_bounded(); + } else { + // OOL won't contain metadata + assert(ret == 0); + } + return ret; } void record_group_size_t::account( @@ -485,14 +521,23 @@ void record_group_size_t::account( assert(_block_size > 0); assert(rsize.dlength % _block_size == 0); assert(block_size == 0 || block_size == _block_size); - plain_mdlength += rsize.get_raw_mdlength(); - dlength += rsize.dlength; + assert(record_type == RECORD_TYPE_NULL || + record_type == rsize.record_type); block_size = _block_size; + record_type = rsize.record_type; + if (record_type == record_type_t::JOURNAL) { + plain_mdlength += rsize.get_raw_mdlength(); + } else { + // OOL won't contain metadata + assert(rsize.get_raw_mdlength() == 0); + } + dlength += rsize.dlength; } std::ostream& operator<<(std::ostream& out, const record_group_size_t& size) { return out << "record_group_size_t(" + << "record_type=" << size.record_type << "raw_md=" << size.get_raw_mdlength() << ", data=" << size.dlength << ", block_size=" << size.block_size diff --git a/src/crimson/os/seastore/seastore_types.h b/src/crimson/os/seastore/seastore_types.h index 2b3cf60868f85..fe8aa92e9800b 100644 --- a/src/crimson/os/seastore/seastore_types.h +++ b/src/crimson/os/seastore/seastore_types.h @@ -1893,7 +1893,20 @@ constexpr bool is_modify_transaction(transaction_type_t type) { is_background_transaction(type)); } +// Note: It is possible to statically introduce structs for OOL, which must be +// more efficient, but that requires to specialize the RecordSubmitter as well. +// Let's delay this optimization until necessary. +enum class record_type_t { + JOURNAL = 0, + OOL, // no header, no metadata, so no padding + MAX +}; +std::ostream &operator<<(std::ostream&, const record_type_t&); + +static constexpr auto RECORD_TYPE_NULL = record_type_t::MAX; + struct record_size_t { + record_type_t record_type = RECORD_TYPE_NULL; // must not be NULL in use extent_len_t plain_mdlength = 0; // mdlength without the record header extent_len_t dlength = 0; @@ -1923,16 +1936,24 @@ struct record_t { record_size_t size; sea_time_point modify_time = NULL_TIME; - record_t(transaction_type_t t_type) : trans_type{t_type} { } + record_t(record_type_t r_type, + transaction_type_t t_type) + : trans_type{t_type} { + assert(r_type != RECORD_TYPE_NULL); + size.record_type = r_type; + } // unit test only record_t() { trans_type = transaction_type_t::MUTATE; + size.record_type = record_type_t::JOURNAL; } // unit test only record_t(std::vector&& _extents, std::vector&& _deltas) { + trans_type = transaction_type_t::MUTATE; + size.record_type = record_type_t::JOURNAL; auto modify_time = seastar::lowres_system_clock::now(); for (auto& e: _extents) { push_back(std::move(e), modify_time); @@ -1940,7 +1961,6 @@ struct record_t { for (auto& d: _deltas) { push_back(std::move(d)); } - trans_type = transaction_type_t::MUTATE; } bool is_empty() const { @@ -1949,6 +1969,13 @@ struct record_t { } std::size_t get_delta_size() const { + assert(size.record_type < record_type_t::MAX); + if (size.record_type == record_type_t::OOL) { + // OOL won't contain metadata + assert(deltas.size() == 0); + return 0; + } + // JOURNAL auto delta_size = std::accumulate( deltas.begin(), deltas.end(), 0, [](uint64_t sum, auto& delta) { @@ -2018,6 +2045,7 @@ struct record_group_header_t { std::ostream& operator<<(std::ostream&, const record_group_header_t&); struct record_group_size_t { + record_type_t record_type = RECORD_TYPE_NULL; // must not be NULL in use extent_len_t plain_mdlength = 0; // mdlength without the group header extent_len_t dlength = 0; extent_len_t block_size = 0; @@ -2033,7 +2061,14 @@ struct record_group_size_t { extent_len_t get_mdlength() const { assert(block_size > 0); - return p2roundup(get_raw_mdlength(), block_size); + assert(record_type < record_type_t::MAX); + if (record_type == record_type_t::JOURNAL) { + return p2roundup(get_raw_mdlength(), block_size); + } else { + // OOL won't contain metadata + assert(get_raw_mdlength() == 0); + return 0; + } } extent_len_t get_encoded_length() const { @@ -2401,6 +2436,7 @@ template <> struct fmt::formatter template <> struct fmt::formatter : fmt::ostream_formatter {}; template <> struct fmt::formatter : fmt::ostream_formatter {}; template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; template <> struct fmt::formatter : fmt::ostream_formatter {}; template <> struct fmt::formatter : fmt::ostream_formatter {}; template <> struct fmt::formatter : fmt::ostream_formatter {};