From: Samuel Just Date: Wed, 11 Dec 2013 23:03:44 +0000 (-0800) Subject: osd_types: introduce spg_t, pg_shard_t X-Git-Tag: v0.78~163^2~39 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4a259516336dc9517979b321d1317eceab14637d;p=ceph.git osd_types: introduce spg_t, pg_shard_t Signed-off-by: Samuel Just --- diff --git a/doc/dev/osd_internals/erasure_coding/pgbackend.rst b/doc/dev/osd_internals/erasure_coding/pgbackend.rst index aea201ee5988..7cadaa5f7eca 100644 --- a/doc/dev/osd_internals/erasure_coding/pgbackend.rst +++ b/doc/dev/osd_internals/erasure_coding/pgbackend.rst @@ -196,7 +196,7 @@ Core changes: tuple. - coll_t needs to include a shard_t. - The `OSD pg_map and similar pg mappings need to work in terms of a - cpg_t `_ (essentially + spg_t `_ (essentially pair). Similarly, pg->pg messages need to include a shard_t - For client->PG messages, the OSD will need a way to know which PG diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 848dc8b7b722..404fb4925981 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -62,6 +62,26 @@ string ceph_osd_flag_string(unsigned flags) return string("-"); } +void pg_shard_t::encode(bufferlist &bl) const +{ + ENCODE_START(1, 1, bl); + ::encode(osd, bl); + ::encode(shard, bl); + ENCODE_FINISH(bl); +} +void pg_shard_t::decode(bufferlist::iterator &bl) +{ + DECODE_START(1, bl); + ::decode(osd, bl); + ::decode(shard, bl); + DECODE_FINISH(bl); +} + +ostream &operator<<(ostream &lhs, const pg_shard_t &rhs) +{ + return lhs << '(' << rhs.osd << ',' << (unsigned)(rhs.shard) << ')'; +} + // -- osd_reqid_t -- void osd_reqid_t::encode(bufferlist &bl) const { @@ -322,6 +342,50 @@ bool pg_t::parse(const char *s) return true; } +bool spg_t::parse(const char *s) +{ + pgid.set_preferred(-1); + shard = ghobject_t::NO_SHARD; + uint64_t ppool; + uint32_t pseed; + int32_t pref; + uint32_t pshard; + int r = sscanf(s, "%llu.%x", (long long unsigned *)&ppool, &pseed); + if (r < 2) + return false; + pgid.set_pool(ppool); + pgid.set_ps(pseed); + + const char *p = strchr(s, 'p'); + if (p) { + r = sscanf(p, "p%d", &pref); + if (r == 1) { + pgid.set_preferred(pref); + } else { + return false; + } + } + + p = strchr(s, 's'); + if (p) { + r = sscanf(p, "s%d", &pshard); + if (r == 1) { + shard = pshard; + } else { + return false; + } + } + return true; +} + +ostream& operator<<(ostream& out, const spg_t &pg) +{ + out << pg.pgid; + if (!pg.is_no_shard()) + out << "s" << (unsigned)pg.shard; + return out; +} + bool pg_t::is_split(unsigned old_pg_num, unsigned new_pg_num, set *children) const { assert(m_seed < old_pg_num); diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index 4a958092f8dc..ed3f1870b40d 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -36,7 +36,7 @@ #include "HitSet.h" #include "Watch.h" #include "OpRequest.h" -#include "include/hash_namespace.h" +#include "include/cmp.h" #define CEPH_OSD_ONDISK_MAGIC "ceph osd volume v026" @@ -63,6 +63,25 @@ const char *ceph_osd_flag_name(unsigned flag); /// convert CEPH_OSD_FLAG_* op flags to a string string ceph_osd_flag_string(unsigned flags); +struct pg_shard_t { + int osd; + shard_id_t shard; + pg_shard_t() : osd(-1), shard(ghobject_t::NO_SHARD) {} + pg_shard_t(int osd, shard_id_t shard) : osd(osd), shard(shard) {} + static pg_shard_t undefined_shard() { + return pg_shard_t(-1, ghobject_t::NO_SHARD); + } + bool is_undefined() const { + return osd == -1; + } + void encode(bufferlist &bl) const; + void decode(bufferlist::iterator &bl); +}; +WRITE_CLASS_ENCODER(pg_shard_t) +WRITE_EQ_OPERATORS_2(pg_shard_t, osd, shard) +WRITE_CMP_OPERATORS_2(pg_shard_t, osd, shard) +ostream &operator<<(ostream &lhs, const pg_shard_t &rhs); + inline ostream& operator<<(ostream& out, const osd_reqid_t& r) { return out << r.name << "." << r.inc << ":" << r.tid; } @@ -368,6 +387,74 @@ CEPH_HASH_NAMESPACE_START }; CEPH_HASH_NAMESPACE_END +struct spg_t { + pg_t pgid; + shard_id_t shard; + spg_t() : shard(ghobject_t::NO_SHARD) {} + spg_t(pg_t pgid, shard_id_t shard) : pgid(pgid), shard(shard) {} + explicit spg_t(pg_t pgid) : pgid(pgid), shard(ghobject_t::NO_SHARD) {} + unsigned get_split_bits(unsigned pg_num) const { + return pgid.get_split_bits(pg_num); + } + spg_t get_parent() const { + return spg_t(pgid.get_parent(), shard); + } + ps_t ps() const { + return pgid.ps(); + } + uint64_t pool() const { + return pgid.pool(); + } + int32_t preferred() const { + return pgid.preferred(); + } + bool parse(const char *s); + bool is_split(unsigned old_pg_num, unsigned new_pg_num, + set *pchildren) const { + set _children; + set *children = pchildren ? &_children : NULL; + bool is_split = pgid.is_split(old_pg_num, new_pg_num, children); + if (pchildren && is_split) { + for (set::iterator i = _children.begin(); + i != _children.end(); + ++i) { + pchildren->insert(spg_t(*i, shard)); + } + } + return is_split; + } + bool is_no_shard() const { + return shard == ghobject_t::NO_SHARD; + } + void encode(bufferlist &bl) const { + ENCODE_START(1, 1, bl); + ::encode(pgid, bl); + ::encode(shard, bl); + ENCODE_FINISH(bl); + } + void decode(bufferlist::iterator &bl) { + DECODE_START(1, bl); + ::decode(pgid, bl); + ::decode(shard, bl); + DECODE_FINISH(bl); + } +}; +WRITE_CLASS_ENCODER(spg_t) +WRITE_EQ_OPERATORS_2(spg_t, pgid, shard) +WRITE_CMP_OPERATORS_2(spg_t, pgid, shard) + +CEPH_HASH_NAMESPACE_START + template<> struct hash< spg_t > + { + size_t operator()( const spg_t& x ) const + { + static hash H; + return H(hash()(x.pgid) ^ x.shard); + } + }; +CEPH_HASH_NAMESPACE_END + +ostream& operator<<(ostream& out, const spg_t &pg); // ----------------------