This also required putting in many explicit casts. I avoided large amount of refactoring to the new shard for now,
although I expect some may follow. The main aim here is that the new EC code is strict about using the correct shard_id_t
and that confusion between shards, raw shards, OSDs, etc.. flag up as errors.
Signed-off-by: Alex Ainscow <aainscow@uk.ibm.com>
if (generation != NO_GEN)
f->dump_int("generation", generation);
if (shard_id != shard_id_t::NO_SHARD)
- f->dump_int("shard_id", shard_id);
+ f->dump_int("shard_id", int(shard_id));
f->dump_int("max", (int)max);
}
// look for shard# prefix
const char *start = s.c_str();
const char *p;
- int sh = shard_id_t::NO_SHARD;
+ shard_id_t sh = shard_id_t::NO_SHARD;
for (p = start; *p && isxdigit(*p); ++p) ;
if (!*p && *p != '#')
return false;
if (p > start) {
- int r = sscanf(s.c_str(), "%x", &sh);
+ unsigned int sh_i;
+ int r = sscanf(s.c_str(), "%x", &sh_i);
if (r < 1)
return false;
+ sh = shard_id_t(sh_i);
start = p + 1;
} else {
++start;
else if (shard_map[pg_map.first].has_shallow_errors())
++shallow_errors;
union_shards.errors |= shard_map[pg_map.first].errors;
- shards.emplace(osd_shard_t{pg_map.first.osd, pg_map.first.shard}, shard_map[pg_map.first]);
+ shards.emplace(osd_shard_t{pg_map.first.osd,
+ static_cast<int8_t>(pg_map.first.shard)}, shard_map[pg_map.first]);
}
}
auto shard_id = cmd_getval_or<int64_t>(cmdmap,
"shardid",
- shard_id_t::NO_SHARD);
+ static_cast<int64_t>(shard_id_t::NO_SHARD));
return ghobject_t{
hobject_t{
* common interfaces as a full_key_t
*/
shard_t shard() const {
- return ghobj.shard_id;
+ return static_cast<shard_t>(ghobj.shard_id);
}
pool_t pool() const {
return ghobj.hobj.pool;
[](auto &cand) { return cand.has_errors(); })) {
for (auto &eval : shards) {
iow.shards.emplace(
- librados::osd_shard_t{eval.source.osd, eval.source.shard},
+ librados::osd_shard_t{eval.source.osd, static_cast<int8_t>(eval.source.shard)},
eval.shard_info);
iow.union_shards.errors |= eval.shard_info.errors;
}
int8_t id;
shard_id_t() : id(0) {}
- constexpr explicit shard_id_t(int8_t _id) : id(_id) {}
+ explicit constexpr shard_id_t(int8_t _id) : id(_id) {}
- constexpr operator int8_t() const { return id; }
+ explicit constexpr operator int8_t() const { return id; }
+ explicit constexpr operator int64_t() const { return id; }
+ explicit constexpr operator int() const { return id; }
+ explicit constexpr operator unsigned() const { return id; }
const static shard_id_t NO_SHARD;
ls.push_back(new shard_id_t(1));
ls.push_back(new shard_id_t(2));
}
- bool operator==(const shard_id_t&) const = default;
- auto operator<=>(const shard_id_t&) const = default;
+ shard_id_t& operator++() { ++id; return *this; }
+ friend constexpr std::strong_ordering operator<=>(const shard_id_t &lhs,
+ const shard_id_t &rhs) {
+ return lhs.id <=> rhs.id;
+ }
+
+ friend constexpr std::strong_ordering operator<=>(int lhs,
+ const shard_id_t &rhs) {
+ return lhs <=> rhs.id;
+ }
+ friend constexpr std::strong_ordering operator<=>(const shard_id_t &lhs,
+ int rhs) {
+ return lhs.id <=> rhs;
+ }
+
+ shard_id_t& operator=(int other) { id = other; return *this; }
+ bool operator==(const shard_id_t &other) const { return id == other.id; }
+
+ shard_id_t operator+(int other) const { return shard_id_t(id + other); }
+ shard_id_t operator-(int other) const { return shard_id_t(id - other); }
};
WRITE_CLASS_ENCODER(shard_id_t)
std::ostream &operator<<(std::ostream &lhs, const shard_id_t &rhs);
for (set<shard_id_t>::iterator i = op.missing_on_shards.begin();
i != op.missing_on_shards.end();
++i) {
- target[*i] = &(op.returned_data[*i]);
+ target[static_cast<int>(*i)] = &(op.returned_data[static_cast<int>(*i)]);
}
map<int, bufferlist> from;
for(map<pg_shard_t, bufferlist>::iterator i = to_read.get<2>().begin();
i != to_read.get<2>().end();
++i) {
- from[i->first.shard] = std::move(i->second);
+ from[static_cast<int>(i->first.shard)] = std::move(i->second);
}
dout(10) << __func__ << ": " << from << dendl;
int r;
for (set<pg_shard_t>::iterator mi = op.missing_on.begin();
mi != op.missing_on.end();
++mi) {
- ceph_assert(op.returned_data.count(mi->shard));
+ ceph_assert(op.returned_data.count(static_cast<int>(mi->shard)));
m->pushes[*mi].push_back(PushOp());
PushOp &pop = m->pushes[*mi].back();
pop.soid = op.hoid;
pop.version = op.v;
- pop.data = op.returned_data[mi->shard];
+ pop.data = op.returned_data[static_cast<int>(mi->shard)];
dout(10) << __func__ << ": before_progress=" << op.recovery_progress
<< ", after_progress=" << after_progress
<< ", pop.data.length()=" << pop.data.length()
dout(20) << __func__ << ": Checking hash of " << i->first << dendl;
bufferhash h(-1);
h << bl;
- if (h.digest() != hinfo->get_chunk_hash(shard)) {
+ if (h.digest() != hinfo->get_chunk_hash(static_cast<int>(shard))) {
get_parent()->clog_error() << "Bad hash for " << i->first << " digest 0x"
- << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(shard) << dec;
+ << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(static_cast<int>(shard)) << dec;
dout(5) << __func__ << ": Bad hash for " << i->first << " digest 0x"
- << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(shard) << dec << dendl;
+ << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(static_cast<int>(shard)) << dec << dendl;
r = -EIO;
goto error;
}
iter->second.returned.front().get<2>().begin();
j != iter->second.returned.front().get<2>().end();
++j) {
- have.insert(j->first.shard);
+ have.insert(static_cast<int>(j->first.shard));
dout(20) << __func__ << " have shard=" << j->first.shard << dendl;
}
map<int, vector<pair<int, int>>> dummy_minimum;
return 0;
}
- if (hinfo->get_chunk_hash(get_parent()->whoami_shard().shard) !=
+ if (hinfo->get_chunk_hash(static_cast<int>(get_parent()->whoami_shard().shard)) !=
pos.data_hash.digest()) {
dout(0) << "_scan_list " << poid << " got incorrect hash on read 0x"
<< std::hex << pos.data_hash.digest() << " != expected 0x"
- << hinfo->get_chunk_hash(get_parent()->whoami_shard().shard)
+ << hinfo->get_chunk_hash(static_cast<int>(get_parent()->whoami_shard().shard))
<< std::dec << dendl;
o.ec_hash_mismatch = true;
return 0;
for (std::set<pg_shard_t>::const_iterator i = _have.begin();
i != _have.end();
++i) {
- have.insert(i->shard);
+ have.insert(static_cast<int>(i->shard));
}
std::map<int, std::vector<std::pair<int, int>>> min;
return ec_impl->minimum_to_decode(want, have, &min) == 0;
for (set<shard_id_t>::iterator i = op.missing_on_shards.begin();
i != op.missing_on_shards.end();
++i) {
- target[*i] = &(op.returned_data[*i]);
+ int s = static_cast<int>(*i);
+ target[s] = &(op.returned_data[s]);
}
map<int, bufferlist> from;
for(map<pg_shard_t, bufferlist>::iterator i = to_read.get<2>().begin();
i != to_read.get<2>().end();
++i) {
- from[i->first.shard] = std::move(i->second);
+ int s = static_cast<int>(i->first.shard);
+ from[s] = std::move(i->second);
}
dout(10) << __func__ << ": " << from << dendl;
int r;
for (set<pg_shard_t>::iterator mi = op.missing_on.begin();
mi != op.missing_on.end();
++mi) {
- ceph_assert(op.returned_data.count(mi->shard));
+ ceph_assert(op.returned_data.count(static_cast<int>(mi->shard)));
m->pushes[*mi].push_back(PushOp());
PushOp &pop = m->pushes[*mi].back();
pop.soid = op.hoid;
pop.version = op.v;
- pop.data = op.returned_data[mi->shard];
+ pop.data = op.returned_data[static_cast<int>(mi->shard)];
dout(10) << __func__ << ": before_progress=" << op.recovery_progress
<< ", after_progress=" << after_progress
<< ", pop.data.length()=" << pop.data.length()
dout(20) << __func__ << ": Checking hash of " << i->first << dendl;
bufferhash h(-1);
h << bl;
- if (h.digest() != hinfo->get_chunk_hash(shard)) {
+ int s = static_cast<int>(shard);
+ if (h.digest() != hinfo->get_chunk_hash(s)) {
get_parent()->clog_error() << "Bad hash for " << i->first << " digest 0x"
- << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(shard) << dec;
+ << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(s) << dec;
dout(5) << __func__ << ": Bad hash for " << i->first << " digest 0x"
- << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(shard) << dec << dendl;
+ << hex << h.digest() << " expected 0x" << hinfo->get_chunk_hash(s) << dec << dendl;
r = -EIO;
goto error;
}
iter->second.returned.front().get<2>().begin();
j != iter->second.returned.front().get<2>().end();
++j) {
- have.insert(j->first.shard);
+ have.insert(static_cast<int>(j->first.shard));
dout(20) << __func__ << " have shard=" << j->first.shard << dendl;
}
map<int, vector<pair<int, int>>> dummy_minimum;
return 0;
}
- if (hinfo->get_chunk_hash(get_parent()->whoami_shard().shard) !=
- pos.data_hash.digest()) {
+ int s = static_cast<int>(get_parent()->whoami_shard().shard);
+ if (hinfo->get_chunk_hash(s) != pos.data_hash.digest()) {
dout(0) << "_scan_list " << poid << " got incorrect hash on read 0x"
<< std::hex << pos.data_hash.digest() << " != expected 0x"
- << hinfo->get_chunk_hash(get_parent()->whoami_shard().shard)
+ << hinfo->get_chunk_hash(s)
<< std::dec << dendl;
o.ec_hash_mismatch = true;
return 0;
for (std::set<pg_shard_t>::const_iterator i = _have.begin();
i != _have.end();
++i) {
- have.insert(i->shard);
+ have.insert(static_cast<int>(i->shard));
}
std::map<int, std::vector<std::pair<int, int>>> min;
return ec_impl->minimum_to_decode(want, have, &min) == 0;
continue;
}
if (!missing.is_missing(hoid)) {
- ceph_assert(!have.count(i->shard));
- have.insert(i->shard);
+ ceph_assert(!have.count(static_cast<int>(i->shard)));
+ have.insert(static_cast<int>(i->shard));
ceph_assert(!shards.count(i->shard));
shards.insert(make_pair(i->shard, *i));
}
++i) {
if (error_shards.find(*i) != error_shards.end())
continue;
- if (have.count(i->shard)) {
+ if (have.count(static_cast<int>(i->shard))) {
ceph_assert(shards.count(i->shard));
continue;
}
const pg_missing_t &missing = get_parent()->get_shard_missing(*i);
if (hoid < info.last_backfill &&
!missing.is_missing(hoid)) {
- have.insert(i->shard);
+ have.insert(static_cast<int>(i->shard));
shards.insert(make_pair(i->shard, *i));
}
}
}
if (error_shards.find(*i) != error_shards.end())
continue;
- have.insert(i->shard);
+ have.insert(static_cast<int>(i->shard));
shards.insert(make_pair(i->shard, *i));
}
}
res.returned.front().get<2>().begin();
j != res.returned.front().get<2>().end();
++j) {
- to_decode[j->first.shard] = std::move(j->second);
+ to_decode[static_cast<int>(j->first.shard)] = std::move(j->second);
}
dout(20) << __func__ << " going to decode: "
<< " wanted_to_read=" << wanted_to_read
set<int> already_read;
const set<pg_shard_t>& ots = rop.obj_to_source[hoid];
for (set<pg_shard_t>::iterator i = ots.begin(); i != ots.end(); ++i)
- already_read.insert(i->shard);
+ already_read.insert(static_cast<int>(i->shard));
dout(10) << __func__ << " have/error shards=" << already_read << dendl;
map<pg_shard_t, vector<pair<int, int>>> shards;
int r = get_remaining_shards(hoid, already_read, rop.want_to_read[hoid],
continue;
}
if (!missing.is_missing(hoid)) {
- ceph_assert(!have.count(i->shard));
- have.insert(i->shard);
+ ceph_assert(!have.count(static_cast<int>(i->shard)));
+ have.insert(static_cast<int>(i->shard));
ceph_assert(!shards.count(i->shard));
shards.insert(make_pair(i->shard, *i));
}
++i) {
if (error_shards.find(*i) != error_shards.end())
continue;
- if (have.count(i->shard)) {
+ if (have.count(static_cast<int>(i->shard))) {
ceph_assert(shards.count(i->shard));
continue;
}
const pg_missing_t &missing = get_parent()->get_shard_missing(*i);
if (hoid < info.last_backfill &&
!missing.is_missing(hoid)) {
- have.insert(i->shard);
+ have.insert(static_cast<int>(i->shard));
shards.insert(make_pair(i->shard, *i));
}
}
}
if (error_shards.find(*i) != error_shards.end())
continue;
- have.insert(i->shard);
+ have.insert(static_cast<int>(i->shard));
shards.insert(make_pair(i->shard, *i));
}
}
res.returned.front().get<2>().begin();
j != res.returned.front().get<2>().end();
++j) {
- to_decode[j->first.shard] = std::move(j->second);
+ to_decode[static_cast<int>(j->first.shard)] = std::move(j->second);
}
dout(20) << __func__ << " going to decode: "
<< " wanted_to_read=" << wanted_to_read
set<int> already_read;
const set<pg_shard_t>& ots = rop.obj_to_source[hoid];
for (set<pg_shard_t>::iterator i = ots.begin(); i != ots.end(); ++i)
- already_read.insert(i->shard);
+ already_read.insert(static_cast<int>(i->shard));
dout(10) << __func__ << " have/error shards=" << already_read << dendl;
map<pg_shard_t, vector<pair<int, int>>> shards;
int r = get_remaining_shards(hoid, already_read, rop.want_to_read[hoid],
}
for (auto &&i : *transactions) {
- ceph_assert(buffers.count(i.first));
- bufferlist &enc_bl = buffers[i.first];
+ ceph_assert(buffers.count(static_cast<int>(i.first)));
+ bufferlist &enc_bl = buffers[static_cast<int>(i.first)];
if (offset >= before_size) {
i.second.set_alloc_hint(
coll_t(spg_t(pgid, i.first)),
}
for (auto &&i : *transactions) {
- ceph_assert(buffers.count(i.first));
- bufferlist &enc_bl = buffers[i.first];
+ ceph_assert(buffers.count(static_cast<int>(i.first)));
+ bufferlist &enc_bl = buffers[static_cast<int>(i.first)];
if (offset >= before_size) {
i.second.set_alloc_hint(
coll_t(spg_t(pgid, i.first)),
return;
}
- int64_t shardid = cmd_getval_or<int64_t>(cmdmap, "shardid", shard_id_t::NO_SHARD);
+ int64_t shardid64 = cmd_getval_or<int64_t>(cmdmap, "shardid", static_cast<int64_t>(shard_id_t::NO_SHARD));
+ shard_id_t shardid = shard_id_t(static_cast<int8_t>(shardid64));
+
hobject_t obj(object_t(objname), string(""), CEPH_NOSNAP, rawpg.ps(), pool, nspace);
- ghobject_t gobj(obj, ghobject_t::NO_GEN, shard_id_t(uint8_t(shardid)));
- spg_t pgid(curmap->raw_pg_to_pg(rawpg), shard_id_t(shardid));
+ ghobject_t gobj(obj, ghobject_t::NO_GEN, shardid);
+ spg_t pgid(curmap->raw_pg_to_pg(rawpg), shardid);
if (curmap->pg_is_ec(rawpg)) {
if ((command != "injectdataerr") &&
(command != "injectmdataerr") &&
}
}
} else {
- if (who.shard < nrep && acting[who.shard] == who.osd) {
- return who.shard;
+ if (who.shard < nrep && acting[static_cast<int>(who.shard)] == who.osd) {
+ return static_cast<int>(who.shard);
}
}
return -1;
PGBackend *pg) : hoid(hoid), pg(pg) {}
void append(uint64_t old_size) override {
ObjectStore::Transaction temp;
- const uint64_t shard_size = pg->object_size_to_shard_size(old_size, pg->get_parent()->whoami_shard().shard);
+ int s = static_cast<int>(pg->get_parent()->whoami_shard().shard);
+ const uint64_t shard_size = pg->object_size_to_shard_size(old_size, s);
pg->rollback_append(hoid, shard_size, &temp);
temp.append(t);
temp.swap(t);
for (auto j = all_info_by_shard[shard_id_t(i)].begin();
j != all_info_by_shard[shard_id_t(i)].end();
++j) {
- ceph_assert(j->shard == i);
+ ceph_assert(static_cast<int>(j->shard) == i);
if (!all_info.find(*j)->second.is_incomplete() &&
all_info.find(*j)->second.last_update >=
auth_log_shard->second.log_tail) {
p != ps->acting_recovery_backfill.end();
++p) {
if (p->shard != ps->pg_whoami.shard) {
- ps->blocked_by.insert(p->shard);
+ ps->blocked_by.insert(static_cast<int>(p->shard));
}
}
pl->publish_stats_to_osd();
ps->peer_activated.insert(infoevt.from).second) {
psdout(10) << " peer osd." << infoevt.from
<< " activated and committed" << dendl;
- ps->blocked_by.erase(infoevt.from.shard);
+ ps->blocked_by.erase(static_cast<int>(infoevt.from.shard));
pl->publish_stats_to_osd();
if (ps->peer_activated.size() == ps->acting_recovery_backfill.size()) {
all_activated_and_committed();
}
static bool has_shard(bool ec, const std::vector<int>& v, pg_shard_t osd) {
if (ec) {
- return v.size() > (unsigned)osd.shard && v[osd.shard] == osd.osd;
+ return v.size() > (unsigned)osd.shard && v[static_cast<int>(osd.shard)] == osd.osd;
} else {
return std::find(v.begin(), v.end(), osd.osd) != v.end();
}
void pg_notify_t::dump(Formatter *f) const
{
- f->dump_int("from", from);
- f->dump_int("to", to);
+ f->dump_int("from", static_cast<int>(from));
+ f->dump_int("to", static_cast<int>(to));
f->dump_unsigned("query_epoch", query_epoch);
f->dump_unsigned("epoch_sent", epoch_sent);
{
void pg_query_t::dump(Formatter *f) const
{
- f->dump_int("from", from);
- f->dump_int("to", to);
+ f->dump_int("from", static_cast<int>(from));
+ f->dump_int("to", static_cast<int>(to));
f->dump_string("type", get_type_name());
f->dump_stream("since") << since;
f->dump_stream("epoch_sent") << epoch_sent;
#include "compressor/Compressor.h"
#include "osd_perf_counters.h"
#include "pg_features.h"
+#include "ECTypes.h"
#define CEPH_OSD_ONDISK_MAGIC "ceph osd volume v026"
void dump(ceph::Formatter *f) const {
f->dump_unsigned("osd", osd);
if (shard != shard_id_t::NO_SHARD) {
- f->dump_unsigned("shard", shard);
+ f->dump_unsigned("shard", static_cast<unsigned>(shard));
}
}
static void generate_test_instances(std::list<pg_shard_t*>& o) {
}
void dump(ceph::Formatter *f) const {
f->dump_stream("pgid") << pgid;
- f->dump_unsigned("shard", shard);
+ f->dump_unsigned("shard", static_cast<unsigned>(shard));
}
static void generate_test_instances(std::list<spg_t*>& o) {
o.push_back(new spg_t);
size_t operator()( const spg_t& x ) const
{
static hash<uint32_t> H;
- return H(hash<pg_t>()(x.pgid) ^ x.shard);
+ // Historically a "shard" was an int8_t, hence the unexpected cast in
+ // this XOR.
+ return H(hash<pg_t>()(x.pgid) ^ static_cast<int8_t>(x.shard));
}
};
} // namespace std
template <typename FormatContext>
auto format(const spg_t& spg, FormatContext& ctx) const
{
- if (shard_id_t::NO_SHARD == spg.shard.id) {
+ if (shard_id_t::NO_SHARD == spg.shard) {
return fmt::format_to(ctx.out(), "{}", spg.pgid);
} else {
return fmt::format_to(ctx.out(), "{}s{}", spg.pgid, spg.shard.id);
bool found_selected_oi = false;
for (const auto &shard : shards) {
auto siter = obj_error.shards.find(
- librados::osd_shard_t{shard.osd, shard.shard}
+ librados::osd_shard_t{shard.osd, static_cast<int8_t>(shard.shard)}
);
if (siter == obj_error.shards.end()) {
EXPECT_NE(siter, obj_error.shards.end());
f.dump_int("osd", osd_shard.osd);
f.dump_bool("primary", shard_info.second.primary);
auto shard = osd_shard.shard;
- if (shard != shard_id_t::NO_SHARD)
+ if (shard != static_cast<int>(shard_id_t::NO_SHARD))
f.dump_unsigned("shard", shard);
dump_shard(shard_info.second, inc, f);
f.close_section();