]> git.proxmox.com Git - ceph.git/blame - ceph/src/osd/ScrubStore.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / osd / ScrubStore.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "ScrubStore.h"
5#include "osd_types.h"
6#include "common/scrub_types.h"
7#include "include/rados/rados_types.hpp"
8
f67539c2
TL
9using std::ostringstream;
10using std::string;
11using std::vector;
12
13using ceph::bufferlist;
14
7c673cae
FG
15namespace {
16ghobject_t make_scrub_object(const spg_t& pgid)
17{
18 ostringstream ss;
19 ss << "scrub_" << pgid;
20 return pgid.make_temp_ghobject(ss.str());
21}
22
23string first_object_key(int64_t pool)
24{
25 auto hoid = hobject_t(object_t(),
26 "",
27 0,
28 0x00000000,
29 pool,
30 "");
31 hoid.build_hash_cache();
32 return "SCRUB_OBJ_" + hoid.to_str();
33}
34
35// the object_key should be unique across pools
36string to_object_key(int64_t pool, const librados::object_id_t& oid)
37{
38 auto hoid = hobject_t(object_t(oid.name),
39 oid.locator, // key
40 oid.snap,
41 0, // hash
42 pool,
43 oid.nspace);
44 hoid.build_hash_cache();
45 return "SCRUB_OBJ_" + hoid.to_str();
46}
47
48string last_object_key(int64_t pool)
49{
50 auto hoid = hobject_t(object_t(),
51 "",
52 0,
53 0xffffffff,
54 pool,
55 "");
56 hoid.build_hash_cache();
57 return "SCRUB_OBJ_" + hoid.to_str();
58}
59
60string first_snap_key(int64_t pool)
61{
62 // scrub object is per spg_t object, so we can misuse the hash (pg.seed) for
63 // the representing the minimal and maximum keys. and this relies on how
64 // hobject_t::to_str() works: hex(pool).hex(revhash).
65 auto hoid = hobject_t(object_t(),
66 "",
67 0,
68 0x00000000,
69 pool,
70 "");
71 hoid.build_hash_cache();
72 return "SCRUB_SS_" + hoid.to_str();
73}
74
75string to_snap_key(int64_t pool, const librados::object_id_t& oid)
76{
77 auto hoid = hobject_t(object_t(oid.name),
78 oid.locator, // key
79 oid.snap,
80 0x77777777, // hash
81 pool,
82 oid.nspace);
83 hoid.build_hash_cache();
84 return "SCRUB_SS_" + hoid.to_str();
85}
86
87string last_snap_key(int64_t pool)
88{
89 auto hoid = hobject_t(object_t(),
90 "",
91 0,
92 0xffffffff,
93 pool,
94 "");
95 hoid.build_hash_cache();
96 return "SCRUB_SS_" + hoid.to_str();
97}
98}
99
100namespace Scrub {
101
102Store*
103Store::create(ObjectStore* store,
104 ObjectStore::Transaction* t,
105 const spg_t& pgid,
106 const coll_t& coll)
107{
11fdf7f2
TL
108 ceph_assert(store);
109 ceph_assert(t);
7c673cae
FG
110 ghobject_t oid = make_scrub_object(pgid);
111 t->touch(coll, oid);
112 return new Store{coll, oid, store};
113}
114
115Store::Store(const coll_t& coll, const ghobject_t& oid, ObjectStore* store)
116 : coll(coll),
117 hoid(oid),
118 driver(store, coll, hoid),
119 backend(&driver)
120{}
121
122Store::~Store()
123{
11fdf7f2 124 ceph_assert(results.empty());
7c673cae
FG
125}
126
127void Store::add_object_error(int64_t pool, const inconsistent_obj_wrapper& e)
128{
129 bufferlist bl;
130 e.encode(bl);
131 results[to_object_key(pool, e.object)] = bl;
132}
133
134void Store::add_snap_error(int64_t pool, const inconsistent_snapset_wrapper& e)
135{
136 bufferlist bl;
137 e.encode(bl);
138 results[to_snap_key(pool, e.object)] = bl;
139}
140
141bool Store::empty() const
142{
143 return results.empty();
144}
145
146void Store::flush(ObjectStore::Transaction* t)
147{
148 if (t) {
149 OSDriver::OSTransaction txn = driver.get_transaction(t);
150 backend.set_keys(results, &txn);
151 }
152 results.clear();
153}
154
155void Store::cleanup(ObjectStore::Transaction* t)
156{
157 t->remove(coll, hoid);
158}
159
160std::vector<bufferlist>
f67539c2 161Store::get_snap_errors(int64_t pool,
7c673cae 162 const librados::object_id_t& start,
f67539c2 163 uint64_t max_return) const
7c673cae
FG
164{
165 const string begin = (start.name.empty() ?
166 first_snap_key(pool) : to_snap_key(pool, start));
167 const string end = last_snap_key(pool);
f67539c2 168 return get_errors(begin, end, max_return);
7c673cae
FG
169}
170
171std::vector<bufferlist>
f67539c2 172Store::get_object_errors(int64_t pool,
7c673cae 173 const librados::object_id_t& start,
f67539c2 174 uint64_t max_return) const
7c673cae
FG
175{
176 const string begin = (start.name.empty() ?
177 first_object_key(pool) : to_object_key(pool, start));
178 const string end = last_object_key(pool);
f67539c2 179 return get_errors(begin, end, max_return);
7c673cae
FG
180}
181
182std::vector<bufferlist>
f67539c2 183Store::get_errors(const string& begin,
7c673cae 184 const string& end,
f67539c2 185 uint64_t max_return) const
7c673cae
FG
186{
187 vector<bufferlist> errors;
188 auto next = std::make_pair(begin, bufferlist{});
189 while (max_return && !backend.get_next(next.first, &next)) {
190 if (next.first >= end)
191 break;
192 errors.push_back(next.second);
193 max_return--;
194 }
195 return errors;
196}
197
198} // namespace Scrub