]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
PG: add split_into to populate child members
authorSamuel Just <sam.just@inktank.com>
Wed, 21 Nov 2012 00:45:56 +0000 (16:45 -0800)
committerSamuel Just <sam.just@inktank.com>
Wed, 5 Dec 2012 19:34:19 +0000 (11:34 -0800)
Signed-off-by: Samuel Just <sam.just@inktank.com>
src/osd/PG.cc
src/osd/PG.h
src/osd/osd_types.cc
src/osd/osd_types.h

index 89ae7d06d79419a94574c7f7294fc30bef8baf55..dfac75c5ca5748b54633603cee0c23221abdc1c7 100644 (file)
@@ -1907,6 +1907,85 @@ void PG::finish_recovery_op(const hobject_t& soid, bool dequeue)
   osd->osd->finish_recovery_op(this, soid, dequeue);
 }
 
+void PG::IndexedLog::split_into(
+  pg_t child_pgid,
+  unsigned split_bits,
+  PG::IndexedLog *olog)
+{
+  list<pg_log_entry_t> oldlog;
+  oldlog.swap(log);
+
+  eversion_t old_tail;
+  olog->head = head;
+  olog->tail = tail;
+  unsigned mask = ~((~0)<<split_bits);
+  for (list<pg_log_entry_t>::iterator i = oldlog.begin();
+       i != oldlog.end();
+       ) {
+    if ((i->soid.hash & mask) == child_pgid.m_seed) {
+      olog->log.push_back(*i);
+      if (log.empty())
+       tail = i->version;
+    } else {
+      log.push_back(*i);
+      if (olog->empty())
+       olog->tail = i->version;
+    }
+    oldlog.erase(i++);
+  }
+
+  if (log.empty())
+    tail = head;
+  else
+    head = log.rbegin()->version;
+
+  if (olog->empty())
+    olog->tail = olog->head;
+  else
+    olog->head = olog->log.rbegin()->version;
+
+  olog->index();
+  index();
+}
+
+void PG::split_into(pg_t child_pgid, PG *child, unsigned split_bits)
+{
+  child->osdmap_ref = osdmap_ref;
+
+  child->pool = pool;
+
+  // Log
+  log.split_into(child_pgid, split_bits, &(child->log));
+  child->info.last_complete = info.last_complete;
+
+  info.last_update = log.head;
+  child->info.last_update = child->log.head;
+
+  info.log_tail = log.tail;
+  child->info.log_tail = child->log.tail;
+
+  if (info.last_complete < log.tail)
+    info.last_complete = log.tail;
+  if (child->info.last_complete < child->log.tail)
+    child->info.last_complete = child->log.tail;
+
+  // Missing
+  missing.split_into(child_pgid, split_bits, &(child->missing));
+
+  // Info
+  child->info.history = info.history;
+  child->info.purged_snaps = info.purged_snaps;
+  child->info.last_backfill = info.last_backfill;
+
+  child->info.stats = info.stats;
+  info.stats.stats_invalid = true;
+  child->info.stats.stats_invalid = true;
+
+  child->snap_trimq = snap_trimq;
+
+  // History
+  child->past_intervals = past_intervals;
+}
 
 void PG::defer_recovery()
 {
index 536f04dda6416018530faf22acdfec36f5d17cb8..cc2e112f48d47252917eedbde020e6ea6345f84a 100644 (file)
@@ -180,6 +180,11 @@ public:
       index();
     }
 
+    void split_into(
+      pg_t child_pgid,
+      unsigned split_bits,
+      IndexedLog *olog);
+
     void zero() {
       unindex();
       pg_log_t::clear();
@@ -789,6 +794,8 @@ public:
   void start_recovery_op(const hobject_t& soid);
   void finish_recovery_op(const hobject_t& soid, bool dequeue=false);
 
+  void split_into(pg_t child_pgid, PG *child, unsigned split_bits);
+
   loff_t get_log_write_pos() {
     return 0;
   }
index c65797b99880b728647f3e7eb3a761636fe0e4db..c52cf20e28d731f1acc983641a69f4bf31045123 100644 (file)
@@ -221,6 +221,27 @@ bool pg_t::is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t> *childre
   return split;
 }
 
+unsigned pg_t::get_split_bits(unsigned pg_num) const {
+  assert(pg_num > 1);
+
+  // Find unique p such that pg_num \in [2^(p-1), 2^p)
+  unsigned p = pg_pool_t::calc_bits_of(pg_num);
+
+  if ((m_seed % (1<<(p-1))) < (pg_num % (1<<(p-1))))
+    return p;
+  else
+    return p - 1;
+}
+
+pg_t pg_t::get_parent() const
+{
+  unsigned bits = pg_pool_t::calc_bits_of(m_seed);
+  assert(bits);
+  pg_t retval = *this;
+  retval.m_seed &= ~((~0)<<(bits - 1));
+  return retval;
+}
+
 void pg_t::dump(Formatter *f) const
 {
   f->dump_unsigned("pool", m_pool);
@@ -2023,6 +2044,24 @@ void pg_missing_t::got(const std::map<hobject_t, pg_missing_t::item>::iterator &
   missing.erase(m);
 }
 
+void pg_missing_t::split_into(
+  pg_t child_pgid,
+  unsigned split_bits,
+  pg_missing_t *omissing)
+{
+  unsigned mask = ~((~0)<<split_bits);
+  for (map<hobject_t, item>::iterator i = missing.begin();
+       i != missing.end();
+       ) {
+    if ((i->first.hash & mask) == child_pgid.m_seed) {
+      omissing->add(i->first, i->second.need, i->second.have);
+      rm(i++);
+    } else {
+      ++i;
+    }
+  }
+}
+
 // -- pg_create_t --
 
 void pg_create_t::encode(bufferlist &bl) const
index 0cc961965d7338623686342a8e2383c5b9b89feb..a1aa20226a66af7918b64a54c9ce0869b564f274 100644 (file)
@@ -235,11 +235,19 @@ struct pg_t {
     m_preferred = osd;
   }
 
+  pg_t get_parent() const;
+
   int print(char *o, int maxlen) const;
   bool parse(const char *s);
 
   bool is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t> *pchildren) const;
 
+  /**
+   * Returns b such that for all object o:
+   *   ~((~0)<<b) & o.hash) == 0 iff o is in the pg for *this
+   */
+  unsigned get_split_bits(unsigned pg_num) const;
+
   void encode(bufferlist& bl) const {
     __u8 v = 1;
     ::encode(v, bl);
@@ -1450,6 +1458,7 @@ struct pg_missing_t {
   void rm(const std::map<hobject_t, pg_missing_t::item>::iterator &m);
   void got(const hobject_t& oid, eversion_t v);
   void got(const std::map<hobject_t, pg_missing_t::item>::iterator &m);
+  void split_into(pg_t child_pgid, unsigned split_bits, pg_missing_t *omissing);
 
   void clear() {
     missing.clear();