]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/osd/pg_meta.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / crimson / osd / pg_meta.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "pg_meta.h"
5
6 #include <string_view>
7
8 #include "crimson/os/futurized_collection.h"
9 #include "crimson/os/futurized_store.h"
10
11 using std::string;
12 using std::string_view;
13 // prefix pgmeta_oid keys with _ so that PGLog::read_log_and_missing() can
14 // easily skip them
15 using crimson::os::FuturizedStore;
16
17 PGMeta::PGMeta(FuturizedStore::Shard& store, spg_t pgid)
18 : store{store},
19 pgid{pgid}
20 {}
21
22 namespace {
23 template<typename T>
24 std::optional<T> find_value(const FuturizedStore::Shard::omap_values_t& values,
25 string_view key)
26 {
27 auto found = values.find(key);
28 if (found == values.end()) {
29 return {};
30 }
31 auto p = found->second.cbegin();
32 T value;
33 decode(value, p);
34 return std::make_optional(std::move(value));
35 }
36 }
37
38 seastar::future<epoch_t> PGMeta::get_epoch()
39 {
40 return store.open_collection(coll_t{pgid}).then([this](auto ch) {
41 return store.omap_get_values(ch,
42 pgid.make_pgmeta_oid(),
43 {string{infover_key},
44 string{epoch_key}}).safe_then(
45 [](auto&& values) {
46 {
47 // sanity check
48 auto infover = find_value<__u8>(values, infover_key);
49 assert(infover);
50 if (*infover < 10) {
51 throw std::runtime_error("incompatible pg meta");
52 }
53 }
54 {
55 auto epoch = find_value<epoch_t>(values, epoch_key);
56 assert(epoch);
57 return seastar::make_ready_future<epoch_t>(*epoch);
58 }
59 },
60 FuturizedStore::Shard::read_errorator::assert_all{
61 "PGMeta::get_epoch: unable to read pgmeta"
62 });
63 });
64 }
65
66 seastar::future<std::tuple<pg_info_t, PastIntervals>> PGMeta::load()
67 {
68 return store.open_collection(coll_t{pgid}).then([this](auto ch) {
69 return store.omap_get_values(ch,
70 pgid.make_pgmeta_oid(),
71 {string{infover_key},
72 string{info_key},
73 string{biginfo_key},
74 string{fastinfo_key}});
75 }).safe_then([](auto&& values) {
76 {
77 // sanity check
78 auto infover = find_value<__u8>(values, infover_key);
79 assert(infover);
80 if (infover < 10) {
81 throw std::runtime_error("incompatible pg meta");
82 }
83 }
84 pg_info_t info;
85 {
86 auto found = find_value<pg_info_t>(values, info_key);
87 assert(found);
88 info = *std::move(found);
89 }
90 PastIntervals past_intervals;
91 {
92 using biginfo_t = std::pair<PastIntervals, decltype(info.purged_snaps)>;
93 auto big_info = find_value<biginfo_t>(values, biginfo_key);
94 assert(big_info);
95 past_intervals = std::move(big_info->first);
96 info.purged_snaps = std::move(big_info->second);
97 }
98 {
99 auto fast_info = find_value<pg_fast_info_t>(values, fastinfo_key);
100 if (fast_info) {
101 fast_info->try_apply_to(&info);
102 }
103 }
104 return seastar::make_ready_future<std::tuple<pg_info_t, PastIntervals>>(
105 std::make_tuple(std::move(info), std::move(past_intervals)));
106 },
107 FuturizedStore::Shard::read_errorator::assert_all{
108 "PGMeta::load: unable to read pgmeta"
109 });
110 }