]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/root_block.h
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / crimson / os / seastore / root_block.h
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#pragma once
5
6#include "crimson/os/seastore/cached_extent.h"
7
8namespace crimson::os::seastore {
9
f67539c2
TL
10/**
11 * RootBlock
12 *
13 * Holds the physical addresses of all metadata roots.
14 * In-memory values may be
15 * - absolute: reference to block which predates the current transaction
16 * - record_relative: reference to block updated in this transaction
17 * if !pending()
18 *
19 * Journal replay only considers deltas and must always discover the most
20 * recent value for the RootBlock. Because the contents of root_t above are
21 * very small, it's simplest to stash the entire root_t value into the delta
22 * and never actually write the RootBlock to a physical location (safe since
23 * nothing references the location of the RootBlock).
24 *
25 * As a result, Cache treats the root differently in a few ways including:
26 * - state will only ever be DIRTY or MUTATION_PENDING
27 * - RootBlock's never show up in the transaction fresh or dirty lists --
28 * there's a special Transaction::root member for when the root needs to
29 * be mutated.
30 *
31 * TODO: Journal trimming will need to be aware of the most recent RootBlock
32 * delta location, or, even easier, just always write one out with the
33 * mutation which changes the journal trim bound.
34 */
35struct RootBlock : CachedExtent {
1e59de90 36 constexpr static extent_len_t SIZE = 4<<10;
f67539c2
TL
37 using Ref = TCachedExtentRef<RootBlock>;
38
39 root_t root;
40
1e59de90
TL
41 CachedExtent* lba_root_node = nullptr;
42 CachedExtent* backref_root_node = nullptr;
43
aee94f69 44 RootBlock() : CachedExtent(zero_length_t()) {};
f67539c2 45
1e59de90
TL
46 RootBlock(const RootBlock &rhs)
47 : CachedExtent(rhs),
48 root(rhs.root),
49 lba_root_node(nullptr),
50 backref_root_node(nullptr)
51 {}
f67539c2 52
1e59de90 53 CachedExtentRef duplicate_for_write(Transaction&) final {
f67539c2
TL
54 return CachedExtentRef(new RootBlock(*this));
55 };
56
57 static constexpr extent_types_t TYPE = extent_types_t::ROOT;
58 extent_types_t get_type() const final {
59 return extent_types_t::ROOT;
60 }
61
1e59de90
TL
62 void on_replace_prior(Transaction &t) final;
63
f67539c2
TL
64 /// dumps root as delta
65 ceph::bufferlist get_delta() final {
66 ceph::bufferlist bl;
67 ceph::buffer::ptr bptr(sizeof(root_t));
68 *reinterpret_cast<root_t*>(bptr.c_str()) = root;
69 bl.append(bptr);
70 return bl;
71 }
72
73 /// overwrites root
74 void apply_delta_and_adjust_crc(paddr_t base, const ceph::bufferlist &_bl) final {
75 assert(_bl.length() == sizeof(root_t));
76 ceph::bufferlist bl = _bl;
77 bl.rebuild();
78 root = *reinterpret_cast<const root_t*>(bl.front().c_str());
79 root.adjust_addrs_from_base(base);
80 }
81
82 /// Patches relative addrs in memory based on record commit addr
83 void on_delta_write(paddr_t record_block_offset) final {
84 root.adjust_addrs_from_base(record_block_offset);
85 }
86
87 complete_load_ertr::future<> complete_load() final {
88 ceph_abort_msg("Root is only written via deltas");
89 }
90
91 void on_initial_write() final {
92 ceph_abort_msg("Root is only written via deltas");
93 }
94
95 root_t &get_root() { return root; }
20effc67 96
1e59de90
TL
97 std::ostream &print_detail(std::ostream &out) const final {
98 return out << ", root_block(lba_root_node=" << (void*)lba_root_node
99 << ", backref_root_node=" << (void*)backref_root_node
100 << ")";
101 }
f67539c2
TL
102};
103using RootBlockRef = RootBlock::Ref;
104
105}
1e59de90
TL
106
107#if FMT_VERSION >= 90000
108template <> struct fmt::formatter<crimson::os::seastore::RootBlock> : fmt::ostream_formatter {};
109#endif