]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/: update peer_missing and local missing if we write a degraded object
authorSamuel Just <sjust@redhat.com>
Wed, 19 Nov 2014 01:27:36 +0000 (17:27 -0800)
committerSamuel Just <sjust@redhat.com>
Fri, 30 Jan 2015 19:27:59 +0000 (11:27 -0800)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/osd/ECBackend.cc
src/osd/PG.cc
src/osd/PG.h
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h

index a8c75c5de1cbe07c5f51e7b6ed362afa873694e1..b44bc2adecf3f55c8e457145a14565aacfb743bf 100644 (file)
@@ -1540,6 +1540,13 @@ void ECBackend::start_write(Op *op) {
       trans.find(i->shard);
     assert(iter != trans.end());
     bool should_send = get_parent()->should_send_op(*i, op->hoid);
+    if (should_send) {
+      dout(10) << __func__ << ": sending transaction for object "
+              << op->hoid << " to shard " << *i << dendl;
+    } else {
+      dout(10) << __func__ << ": NOT sending transaction for object "
+              << op->hoid << " to shard " << *i << dendl;
+    }
     pg_stat_t stats =
       should_send ?
       get_info().stats :
index 3325b4c66785d3952055c0865209954a58820a2c..cddd94aeaa3ca410d88cf71e3709e43aa65ea028 100644 (file)
@@ -2881,6 +2881,30 @@ void PG::append_log(
   for (vector<pg_log_entry_t>::const_iterator p = logv.begin();
        p != logv.end();
        ++p) {
+    // we might get log entries for missing objects since we can write to
+    // degraded objects
+    if (!transaction_applied) {
+      if (p->is_delete())
+       t.remove(coll, p->soid);
+
+      assert(
+       p->soid > info.last_backfill ||
+       pg_log.get_missing().is_missing(p->soid) ||
+       (p->is_clone() || p->is_promote() ||
+        (p->is_modify() && (p->prior_version == eversion_t())))
+       );
+
+      if (p->soid <= info.last_backfill) {
+       dout(10) << __func__ << ": transaction empty, adding event "
+                << *p << " to missing"
+                << dendl;
+       pg_log.missing_add_event(*p);
+      } else {
+       dout(10) << __func__ << ": transaction empty, backfill, "
+                << "not adding event " << *p << " to missing"
+                << dendl;
+      }
+    }
     add_log_entry(*p, keys[p->get_key_name()]);
   }
 
index e269596855b37bda04f30e1927150602739bae18..692ecba76b67457aa2c9a26eb54687b9a8de0e83 100644 (file)
@@ -395,6 +395,44 @@ public:
       assert(needs_recovery(hoid));
       needs_recovery_map[hoid].need = need;
     }
+    void rebuild_object_location(
+      const hobject_t &hoid,
+      const set<pg_shard_t> &actingbackfill,
+      const map<pg_shard_t, const pg_missing_t *> &all_missing,
+      const map<pg_shard_t, const pg_info_t *> &all_info) {
+      needs_recovery_map.erase(hoid);
+      missing_loc.erase(hoid);
+      eversion_t need;
+      for (set<pg_shard_t>::const_iterator peer = actingbackfill.begin();
+          peer != actingbackfill.end();
+          ++peer) {
+       map<pg_shard_t, const pg_missing_t *>::const_iterator pm =
+         all_missing.find(*peer);
+       assert(pm != all_missing.end());
+       if (pm->second->is_missing(hoid)) {
+         need = pm->second->missing.find(hoid)->second.need;
+         break;
+       }
+      }
+      if (need == eversion_t())
+       return;
+
+      set<pg_shard_t> have;
+      for (map<pg_shard_t, const pg_missing_t *>::const_iterator pm =
+            all_missing.begin();
+          pm != all_missing.end();
+          ++pm) {
+       map<pg_shard_t, const pg_info_t *>::const_iterator pi =
+         all_info.find(pm->first);
+       assert(pi != all_info.end());
+       if (pi->second->last_update >= need &&
+           !pm->second->is_missing(hoid)) {
+         have.insert(pm->first);
+       }
+      }
+      missing_loc[hoid].swap(have);
+      add_missing(hoid, need, eversion_t());
+    }
 
     /// Adds info about a possible recovery source
     bool add_source_info(
index 910a95579594f80dfab1f8dfa3e6750b567c3196..1278298ea238cd24cbc65355d75a70ac72a42ec8 100644 (file)
@@ -7531,6 +7531,40 @@ void ReplicatedPG::issue_repop(RepGather *repop, utime_t now)
     repop->ctx->reqid,
     repop->ctx->op);
   repop->ctx->op_t = NULL;
+
+  if (is_degraded_object(soid)) {
+    dout(10) << __func__ << ": " << soid
+            << " degraded, maintaining missing sets"
+            << dendl;
+    assert(!is_missing_object(soid));
+    for (vector<pg_log_entry_t>::iterator j = repop->ctx->log.begin();
+        j != repop->ctx->log.end();
+        ++j) {
+      for (set<pg_shard_t>::const_iterator peer = actingbackfill.begin();
+          peer != actingbackfill.end();
+          ++peer) {
+       if (*peer == pg_whoami) {
+         assert(!is_missing_object(j->soid));
+         continue;
+       }
+       map<pg_shard_t, pg_missing_t>::iterator pm = peer_missing.find(*peer);
+       assert(pm != peer_missing.end());
+       if (!pm->second.is_missing(soid)) {
+         assert(!pm->second.is_missing(j->soid));
+         continue;
+       }
+       dout(10) << __func__ << ": " << soid << " missing on "
+                << *peer << ", adding event " << *j << " to missing"
+                << dendl;
+       pm->second.add_next_event(*j);
+      }
+      missing_loc.rebuild_object_location(
+       j->soid,
+       actingbackfill,
+       get_all_missing(),
+       get_all_info());
+    }
+  }
 }
 
 template<typename T, int MSGTYPE>
index a32e80d6bb307f54f375c407f91edb310e2f56bf..e5a83af044340d6852ed2c7b794a9f65bfa82e0d 100644 (file)
@@ -368,6 +368,26 @@ public:
   const pg_pool_t &get_pool() const {
     return pool.info;
   }
+  map<pg_shard_t, const pg_missing_t *> get_all_missing() const {
+    map<pg_shard_t, const pg_missing_t *> all_missing;
+    all_missing[pg_whoami] = &(pg_log.get_missing());
+    for (map<pg_shard_t, pg_missing_t>::const_iterator i = peer_missing.begin();
+        i != peer_missing.end();
+        ++i) {
+      all_missing[i->first] = &(i->second);
+    }
+    return all_missing;
+  }
+  const map<pg_shard_t, const pg_info_t *> get_all_info() const {
+    map<pg_shard_t, const pg_info_t *> all_info;
+    all_info[pg_whoami] = &info;
+    for (map<pg_shard_t, pg_info_t>::const_iterator i = peer_info.begin();
+        i != peer_info.end();
+        ++i) {
+      all_info[i->first] = &(i->second);
+    }
+    return all_info;
+  }
   ObjectContextRef get_obc(
     const hobject_t &hoid,
     map<string, bufferlist> &attrs) {