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
);