]>
Commit | Line | Data |
---|---|---|
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 | ||
8 | namespace 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 | */ | |
35 | struct 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 | }; |
103 | using RootBlockRef = RootBlock::Ref; | |
104 | ||
105 | } | |
1e59de90 TL |
106 | |
107 | #if FMT_VERSION >= 90000 | |
108 | template <> struct fmt::formatter<crimson::os::seastore::RootBlock> : fmt::ostream_formatter {}; | |
109 | #endif |