]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/root_block.h
import quincy beta 17.1.0
[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 {
36 constexpr static segment_off_t SIZE = 4<<10;
37 using Ref = TCachedExtentRef<RootBlock>;
38
39 root_t root;
40
41 RootBlock() : CachedExtent(0) {}
42
43 RootBlock(const RootBlock &rhs) = default;
44
45 CachedExtentRef duplicate_for_write() final {
46 return CachedExtentRef(new RootBlock(*this));
47 };
48
49 static constexpr extent_types_t TYPE = extent_types_t::ROOT;
50 extent_types_t get_type() const final {
51 return extent_types_t::ROOT;
52 }
53
54 /// dumps root as delta
55 ceph::bufferlist get_delta() final {
56 ceph::bufferlist bl;
57 ceph::buffer::ptr bptr(sizeof(root_t));
58 *reinterpret_cast<root_t*>(bptr.c_str()) = root;
59 bl.append(bptr);
60 return bl;
61 }
62
63 /// overwrites root
64 void apply_delta_and_adjust_crc(paddr_t base, const ceph::bufferlist &_bl) final {
65 assert(_bl.length() == sizeof(root_t));
66 ceph::bufferlist bl = _bl;
67 bl.rebuild();
68 root = *reinterpret_cast<const root_t*>(bl.front().c_str());
69 root.adjust_addrs_from_base(base);
70 }
71
72 /// Patches relative addrs in memory based on record commit addr
73 void on_delta_write(paddr_t record_block_offset) final {
74 root.adjust_addrs_from_base(record_block_offset);
75 }
76
77 complete_load_ertr::future<> complete_load() final {
78 ceph_abort_msg("Root is only written via deltas");
79 }
80
81 void on_initial_write() final {
82 ceph_abort_msg("Root is only written via deltas");
83 }
84
85 root_t &get_root() { return root; }
20effc67 86
f67539c2
TL
87};
88using RootBlockRef = RootBlock::Ref;
89
90}