]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc
8d75f9fa837ce7f1c5a7c0f93e9fa727e7634c5d
[ceph.git] / ceph / src / crimson / os / seastore / onode_manager / staged-fltree / fltree_onode_manager.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "crimson/os/seastore/logging.h"
5
6 #include "crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h"
7
8 SET_SUBSYS(seastore_onode);
9
10 namespace crimson::os::seastore::onode {
11
12 FLTreeOnodeManager::contains_onode_ret FLTreeOnodeManager::contains_onode(
13 Transaction &trans,
14 const ghobject_t &hoid)
15 {
16 return tree.contains(trans, hoid);
17 }
18
19 FLTreeOnodeManager::get_onode_ret FLTreeOnodeManager::get_onode(
20 Transaction &trans,
21 const ghobject_t &hoid)
22 {
23 LOG_PREFIX(FLTreeOnodeManager::get_onode);
24 return tree.find(
25 trans, hoid
26 ).si_then([this, &hoid, &trans, FNAME](auto cursor)
27 -> get_onode_ret {
28 if (cursor == tree.end()) {
29 DEBUGT("no entry for {}", trans, hoid);
30 return crimson::ct_error::enoent::make();
31 }
32 auto val = OnodeRef(new FLTreeOnode(
33 default_data_reservation,
34 default_metadata_range,
35 cursor.value()));
36 return get_onode_iertr::make_ready_future<OnodeRef>(
37 val
38 );
39 });
40 }
41
42 FLTreeOnodeManager::get_or_create_onode_ret
43 FLTreeOnodeManager::get_or_create_onode(
44 Transaction &trans,
45 const ghobject_t &hoid)
46 {
47 LOG_PREFIX(FLTreeOnodeManager::get_or_create_onode);
48 return tree.insert(
49 trans, hoid,
50 OnodeTree::tree_value_config_t{sizeof(onode_layout_t)}
51 ).si_then([this, &trans, &hoid, FNAME](auto p)
52 -> get_or_create_onode_ret {
53 auto [cursor, created] = std::move(p);
54 auto val = OnodeRef(new FLTreeOnode(
55 default_data_reservation,
56 default_metadata_range,
57 cursor.value()));
58 if (created) {
59 DEBUGT("created onode for entry for {}", trans, hoid);
60 val->get_mutable_layout(trans) = onode_layout_t{};
61 }
62 return get_or_create_onode_iertr::make_ready_future<OnodeRef>(
63 val
64 );
65 });
66 }
67
68 FLTreeOnodeManager::get_or_create_onodes_ret
69 FLTreeOnodeManager::get_or_create_onodes(
70 Transaction &trans,
71 const std::vector<ghobject_t> &hoids)
72 {
73 return seastar::do_with(
74 std::vector<OnodeRef>(),
75 [this, &hoids, &trans](auto &ret) {
76 ret.reserve(hoids.size());
77 return trans_intr::do_for_each(
78 hoids,
79 [this, &trans, &ret](auto &hoid) {
80 return get_or_create_onode(trans, hoid
81 ).si_then([&ret](auto &&onoderef) {
82 ret.push_back(std::move(onoderef));
83 });
84 }).si_then([&ret] {
85 return std::move(ret);
86 });
87 });
88 }
89
90 FLTreeOnodeManager::write_dirty_ret FLTreeOnodeManager::write_dirty(
91 Transaction &trans,
92 const std::vector<OnodeRef> &onodes)
93 {
94 return trans_intr::do_for_each(
95 onodes,
96 [this, &trans](auto &onode) -> eagain_ifuture<> {
97 auto &flonode = static_cast<FLTreeOnode&>(*onode);
98 switch (flonode.status) {
99 case FLTreeOnode::status_t::MUTATED: {
100 flonode.populate_recorder(trans);
101 return eagain_iertr::make_ready_future<>();
102 }
103 case FLTreeOnode::status_t::DELETED: {
104 return tree.erase(trans, flonode);
105 }
106 case FLTreeOnode::status_t::STABLE: {
107 return eagain_iertr::make_ready_future<>();
108 }
109 default:
110 __builtin_unreachable();
111 }
112 });
113 }
114
115 FLTreeOnodeManager::erase_onode_ret FLTreeOnodeManager::erase_onode(
116 Transaction &trans,
117 OnodeRef &onode)
118 {
119 auto &flonode = static_cast<FLTreeOnode&>(*onode);
120 flonode.mark_delete();
121 return erase_onode_iertr::now();
122 }
123
124 FLTreeOnodeManager::list_onodes_ret FLTreeOnodeManager::list_onodes(
125 Transaction &trans,
126 const ghobject_t& start,
127 const ghobject_t& end,
128 uint64_t limit)
129 {
130 return tree.lower_bound(trans, start
131 ).si_then([this, &trans, end, limit] (auto&& cursor) {
132 using crimson::os::seastore::onode::full_key_t;
133 return seastar::do_with(
134 limit,
135 std::move(cursor),
136 list_onodes_bare_ret(),
137 [this, &trans, end] (auto& to_list, auto& current_cursor, auto& ret) {
138 return trans_intr::repeat(
139 [this, &trans, end, &to_list, &current_cursor, &ret] ()
140 -> eagain_ifuture<seastar::stop_iteration> {
141 if (current_cursor.is_end()) {
142 std::get<1>(ret) = ghobject_t::get_max();
143 return seastar::make_ready_future<seastar::stop_iteration>(
144 seastar::stop_iteration::yes);
145 } else if (current_cursor.get_ghobj() >= end) {
146 std::get<1>(ret) = end;
147 return seastar::make_ready_future<seastar::stop_iteration>(
148 seastar::stop_iteration::yes);
149 }
150 if (to_list == 0) {
151 std::get<1>(ret) = current_cursor.get_ghobj();
152 return seastar::make_ready_future<seastar::stop_iteration>(
153 seastar::stop_iteration::yes);
154 }
155 std::get<0>(ret).emplace_back(current_cursor.get_ghobj());
156 return tree.get_next(trans, current_cursor
157 ).si_then([&to_list, &current_cursor] (auto&& next_cursor) mutable {
158 // we intentionally hold the current_cursor during get_next() to
159 // accelerate tree lookup.
160 --to_list;
161 current_cursor = next_cursor;
162 return seastar::make_ready_future<seastar::stop_iteration>(
163 seastar::stop_iteration::no);
164 });
165 }).si_then([&ret] () mutable {
166 return seastar::make_ready_future<list_onodes_bare_ret>(
167 std::move(ret));
168 // return ret;
169 });
170 });
171 });
172 }
173
174 FLTreeOnodeManager::~FLTreeOnodeManager() {}
175
176 }