]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #pragma once | |
5 | ||
6 | #include "crimson/os/seastore/onode_manager.h" | |
7 | #include "crimson/os/seastore/onode_manager/staged-fltree/value.h" | |
8 | #include "crimson/os/seastore/onode_manager/staged-fltree/tree.h" | |
9 | ||
10 | namespace crimson::os::seastore::onode { | |
11 | ||
12 | struct FLTreeOnode final : Onode, Value { | |
13 | static constexpr tree_conf_t TREE_CONF = { | |
14 | value_magic_t::ONODE, | |
15 | 256, // max_ns_size | |
16 | // same to option osd_max_object_namespace_len | |
17 | 2048, // max_oid_size | |
18 | // same to option osd_max_object_name_len | |
19 | 1200, // max_value_payload_size | |
20 | // see crimson::os::seastore::onode_layout_t | |
21 | 8192, // internal_node_size | |
22 | // see the formula in validate_tree_config | |
23 | 16384 // leaf_node_size | |
24 | // see the formula in validate_tree_config | |
25 | }; | |
26 | ||
27 | enum class status_t { | |
28 | STABLE, | |
29 | MUTATED, | |
30 | DELETED | |
31 | } status = status_t::STABLE; | |
32 | ||
33 | FLTreeOnode(FLTreeOnode&&) = default; | |
34 | FLTreeOnode& operator=(FLTreeOnode&&) = delete; | |
35 | ||
36 | FLTreeOnode(const FLTreeOnode&) = default; | |
37 | FLTreeOnode& operator=(const FLTreeOnode&) = delete; | |
38 | ||
39 | template <typename... T> | |
40 | FLTreeOnode(uint32_t ddr, uint32_t dmr, T&&... args) | |
41 | : Onode(ddr, dmr), | |
42 | Value(std::forward<T>(args)...) {} | |
43 | ||
44 | template <typename... T> | |
45 | FLTreeOnode(T&&... args) | |
46 | : Onode(0, 0), | |
47 | Value(std::forward<T>(args)...) {} | |
48 | ||
49 | struct Recorder : public ValueDeltaRecorder { | |
50 | Recorder(bufferlist &bl) : ValueDeltaRecorder(bl) {} | |
51 | ||
52 | value_magic_t get_header_magic() const final { | |
53 | return TREE_CONF.value_magic; | |
54 | } | |
55 | ||
56 | void apply_value_delta( | |
57 | ceph::bufferlist::const_iterator &bliter, | |
58 | NodeExtentMutable &value, | |
59 | laddr_t) final { | |
60 | assert(value.get_length() == sizeof(onode_layout_t)); | |
61 | bliter.copy(value.get_length(), value.get_write()); | |
62 | } | |
63 | ||
64 | void record_delta(NodeExtentMutable &value) { | |
65 | // TODO: probably could use versioning, etc | |
66 | assert(value.get_length() == sizeof(onode_layout_t)); | |
67 | ceph::buffer::ptr bptr(value.get_length()); | |
68 | memcpy(bptr.c_str(), value.get_read(), value.get_length()); | |
69 | get_encoded(value).append(bptr); | |
70 | } | |
71 | }; | |
72 | ||
73 | const onode_layout_t &get_layout() const final { | |
74 | assert(status != status_t::DELETED); | |
75 | return *read_payload<onode_layout_t>(); | |
76 | } | |
77 | ||
78 | onode_layout_t &get_mutable_layout(Transaction &t) final { | |
79 | assert(status != status_t::DELETED); | |
80 | auto p = prepare_mutate_payload< | |
81 | onode_layout_t, | |
82 | Recorder>(t); | |
83 | status = status_t::MUTATED; | |
84 | return *reinterpret_cast<onode_layout_t*>(p.first.get_write()); | |
85 | }; | |
86 | ||
87 | void populate_recorder(Transaction &t) { | |
88 | assert(status == status_t::MUTATED); | |
89 | auto p = prepare_mutate_payload< | |
90 | onode_layout_t, | |
91 | Recorder>(t); | |
92 | if (p.second) { | |
93 | p.second->record_delta( | |
94 | p.first); | |
95 | } | |
96 | status = status_t::STABLE; | |
97 | } | |
98 | ||
99 | void mark_delete() { | |
100 | assert(status != status_t::DELETED); | |
101 | status = status_t::DELETED; | |
102 | } | |
103 | ||
104 | laddr_t get_hint() const final { | |
105 | return Value::get_hint(); | |
106 | } | |
107 | ~FLTreeOnode() final {} | |
108 | }; | |
109 | ||
110 | using OnodeTree = Btree<FLTreeOnode>; | |
111 | ||
112 | using crimson::common::get_conf; | |
113 | ||
114 | class FLTreeOnodeManager : public crimson::os::seastore::OnodeManager { | |
115 | OnodeTree tree; | |
116 | ||
117 | uint32_t default_data_reservation = 0; | |
118 | uint32_t default_metadata_offset = 0; | |
119 | uint32_t default_metadata_range = 0; | |
120 | public: | |
121 | FLTreeOnodeManager(TransactionManager &tm) : | |
122 | tree(NodeExtentManager::create_seastore(tm)), | |
123 | default_data_reservation( | |
124 | get_conf<uint64_t>("seastore_default_max_object_size")), | |
125 | default_metadata_offset(default_data_reservation), | |
126 | default_metadata_range( | |
127 | get_conf<uint64_t>("seastore_default_object_metadata_reservation")) | |
128 | {} | |
129 | ||
130 | mkfs_ret mkfs(Transaction &t) { | |
131 | return tree.mkfs(t); | |
132 | } | |
133 | ||
134 | contains_onode_ret contains_onode( | |
135 | Transaction &trans, | |
136 | const ghobject_t &hoid) final; | |
137 | ||
138 | get_onode_ret get_onode( | |
139 | Transaction &trans, | |
140 | const ghobject_t &hoid) final; | |
141 | ||
142 | get_or_create_onode_ret get_or_create_onode( | |
143 | Transaction &trans, | |
144 | const ghobject_t &hoid) final; | |
145 | ||
146 | get_or_create_onodes_ret get_or_create_onodes( | |
147 | Transaction &trans, | |
148 | const std::vector<ghobject_t> &hoids) final; | |
149 | ||
150 | write_dirty_ret write_dirty( | |
151 | Transaction &trans, | |
152 | const std::vector<OnodeRef> &onodes) final; | |
153 | ||
154 | erase_onode_ret erase_onode( | |
155 | Transaction &trans, | |
156 | OnodeRef &onode) final; | |
157 | ||
158 | list_onodes_ret list_onodes( | |
159 | Transaction &trans, | |
160 | const ghobject_t& start, | |
161 | const ghobject_t& end, | |
162 | uint64_t limit) final; | |
163 | ||
164 | ~FLTreeOnodeManager(); | |
165 | }; | |
166 | using FLTreeOnodeManagerRef = std::unique_ptr<FLTreeOnodeManager>; | |
167 | ||
168 | } |