1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "ScrubStore.h"
6 #include "common/scrub_types.h"
7 #include "include/rados/rados_types.hpp"
10 ghobject_t make_scrub_object(const spg_t& pgid)
13 ss << "scrub_" << pgid;
14 return pgid.make_temp_ghobject(ss.str());
17 string first_object_key(int64_t pool)
19 auto hoid = hobject_t(object_t(),
25 hoid.build_hash_cache();
26 return "SCRUB_OBJ_" + hoid.to_str();
29 // the object_key should be unique across pools
30 string to_object_key(int64_t pool, const librados::object_id_t& oid)
32 auto hoid = hobject_t(object_t(oid.name),
38 hoid.build_hash_cache();
39 return "SCRUB_OBJ_" + hoid.to_str();
42 string last_object_key(int64_t pool)
44 auto hoid = hobject_t(object_t(),
50 hoid.build_hash_cache();
51 return "SCRUB_OBJ_" + hoid.to_str();
54 string first_snap_key(int64_t pool)
56 // scrub object is per spg_t object, so we can misuse the hash (pg.seed) for
57 // the representing the minimal and maximum keys. and this relies on how
58 // hobject_t::to_str() works: hex(pool).hex(revhash).
59 auto hoid = hobject_t(object_t(),
65 hoid.build_hash_cache();
66 return "SCRUB_SS_" + hoid.to_str();
69 string to_snap_key(int64_t pool, const librados::object_id_t& oid)
71 auto hoid = hobject_t(object_t(oid.name),
77 hoid.build_hash_cache();
78 return "SCRUB_SS_" + hoid.to_str();
81 string last_snap_key(int64_t pool)
83 auto hoid = hobject_t(object_t(),
89 hoid.build_hash_cache();
90 return "SCRUB_SS_" + hoid.to_str();
97 Store::create(ObjectStore* store,
98 ObjectStore::Transaction* t,
104 ghobject_t oid = make_scrub_object(pgid);
106 return new Store{coll, oid, store};
109 Store::Store(const coll_t& coll, const ghobject_t& oid, ObjectStore* store)
112 driver(store, coll, hoid),
118 assert(results.empty());
121 void Store::add_object_error(int64_t pool, const inconsistent_obj_wrapper& e)
125 results[to_object_key(pool, e.object)] = bl;
128 void Store::add_snap_error(int64_t pool, const inconsistent_snapset_wrapper& e)
132 results[to_snap_key(pool, e.object)] = bl;
135 bool Store::empty() const
137 return results.empty();
140 void Store::flush(ObjectStore::Transaction* t)
143 OSDriver::OSTransaction txn = driver.get_transaction(t);
144 backend.set_keys(results, &txn);
149 void Store::cleanup(ObjectStore::Transaction* t)
151 t->remove(coll, hoid);
154 std::vector<bufferlist>
155 Store::get_snap_errors(ObjectStore* store,
157 const librados::object_id_t& start,
160 const string begin = (start.name.empty() ?
161 first_snap_key(pool) : to_snap_key(pool, start));
162 const string end = last_snap_key(pool);
163 return get_errors(store, begin, end, max_return);
166 std::vector<bufferlist>
167 Store::get_object_errors(ObjectStore* store,
169 const librados::object_id_t& start,
172 const string begin = (start.name.empty() ?
173 first_object_key(pool) : to_object_key(pool, start));
174 const string end = last_object_key(pool);
175 return get_errors(store, begin, end, max_return);
178 std::vector<bufferlist>
179 Store::get_errors(ObjectStore* store,
184 vector<bufferlist> errors;
185 auto next = std::make_pair(begin, bufferlist{});
186 while (max_return && !backend.get_next(next.first, &next)) {
187 if (next.first >= end)
189 errors.push_back(next.second);