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"
9 using std::ostringstream
;
13 using ceph::bufferlist
;
16 ghobject_t
make_scrub_object(const spg_t
& pgid
)
19 ss
<< "scrub_" << pgid
;
20 return pgid
.make_temp_ghobject(ss
.str());
23 string
first_object_key(int64_t pool
)
25 auto hoid
= hobject_t(object_t(),
31 hoid
.build_hash_cache();
32 return "SCRUB_OBJ_" + hoid
.to_str();
35 // the object_key should be unique across pools
36 string
to_object_key(int64_t pool
, const librados::object_id_t
& oid
)
38 auto hoid
= hobject_t(object_t(oid
.name
),
44 hoid
.build_hash_cache();
45 return "SCRUB_OBJ_" + hoid
.to_str();
48 string
last_object_key(int64_t pool
)
50 auto hoid
= hobject_t(object_t(),
56 hoid
.build_hash_cache();
57 return "SCRUB_OBJ_" + hoid
.to_str();
60 string
first_snap_key(int64_t pool
)
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(),
71 hoid
.build_hash_cache();
72 return "SCRUB_SS_" + hoid
.to_str();
75 string
to_snap_key(int64_t pool
, const librados::object_id_t
& oid
)
77 auto hoid
= hobject_t(object_t(oid
.name
),
83 hoid
.build_hash_cache();
84 return "SCRUB_SS_" + hoid
.to_str();
87 string
last_snap_key(int64_t pool
)
89 auto hoid
= hobject_t(object_t(),
95 hoid
.build_hash_cache();
96 return "SCRUB_SS_" + hoid
.to_str();
103 Store::create(ObjectStore
* store
,
104 ObjectStore::Transaction
* t
,
110 ghobject_t oid
= make_scrub_object(pgid
);
112 return new Store
{coll
, oid
, store
};
115 Store::Store(const coll_t
& coll
, const ghobject_t
& oid
, ObjectStore
* store
)
118 driver(store
, coll
, hoid
),
124 ceph_assert(results
.empty());
127 void Store::add_object_error(int64_t pool
, const inconsistent_obj_wrapper
& e
)
131 results
[to_object_key(pool
, e
.object
)] = bl
;
134 void Store::add_snap_error(int64_t pool
, const inconsistent_snapset_wrapper
& e
)
138 results
[to_snap_key(pool
, e
.object
)] = bl
;
141 bool Store::empty() const
143 return results
.empty();
146 void Store::flush(ObjectStore::Transaction
* t
)
149 OSDriver::OSTransaction txn
= driver
.get_transaction(t
);
150 backend
.set_keys(results
, &txn
);
155 void Store::cleanup(ObjectStore::Transaction
* t
)
157 t
->remove(coll
, hoid
);
160 std::vector
<bufferlist
>
161 Store::get_snap_errors(int64_t pool
,
162 const librados::object_id_t
& start
,
163 uint64_t max_return
) const
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
);
168 return get_errors(begin
, end
, max_return
);
171 std::vector
<bufferlist
>
172 Store::get_object_errors(int64_t pool
,
173 const librados::object_id_t
& start
,
174 uint64_t max_return
) const
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
);
179 return get_errors(begin
, end
, max_return
);
182 std::vector
<bufferlist
>
183 Store::get_errors(const string
& begin
,
185 uint64_t max_return
) const
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
)
192 errors
.push_back(next
.second
);