]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Move object error check out of be_select_auth_object()
authorDavid Zafman <dzafman@redhat.com>
Wed, 1 Aug 2018 00:53:17 +0000 (17:53 -0700)
committerNathan Cutler <ncutler@suse.com>
Sun, 2 Sep 2018 12:48:56 +0000 (14:48 +0200)
Fixes: http://tracker.ceph.com/issues/25108
Signed-off-by: David Zafman <dzafman@redhat.com>
(cherry picked from commit c789fd1899f697a994a28e45a6f9262c6721d77d)

Conflicts:
src/osd/PGBackend.cc

- luminous still has auth_prio and different way of decoding bliter

src/osd/PGBackend.cc
src/osd/PGBackend.h

index f77b8bfad933203c9c3d3e6520f988f90c3f069e..5132e72a7c22322bd75e65b450f936aa1d43e579 100644 (file)
@@ -626,7 +626,8 @@ bool PGBackend::be_compare_scrub_objects(
   const ScrubMap::object &candidate,
   shard_info_wrapper &shard_result,
   inconsistent_obj_wrapper &obj_result,
-  ostream &errorstream)
+  ostream &errorstream,
+  bool has_snapset)
 {
   enum { CLEAN, FOUND_ERROR } error = CLEAN;
   if (candidate.stat_error) {
@@ -686,6 +687,67 @@ bool PGBackend::be_compare_scrub_objects(
   }
   if (candidate.stat_error)
     return error == FOUND_ERROR;
+  if (!shard_result.has_info_missing()
+      && !shard_result.has_info_corrupted()) {
+    bufferlist can_bl, auth_bl;
+    auto can_attr = candidate.attrs.find(OI_ATTR);
+    auto auth_attr = auth.attrs.find(OI_ATTR);
+
+    assert(auth_attr != auth.attrs.end());
+    assert(can_attr != candidate.attrs.end());
+
+    can_bl.push_back(can_attr->second);
+    auth_bl.push_back(auth_attr->second);
+    if (!can_bl.contents_equal(auth_bl)) {
+      if (error != CLEAN)
+        errorstream << ", ";
+      error = FOUND_ERROR;
+      obj_result.set_object_info_inconsistency();
+      errorstream << "object info inconsistent ";
+    }
+  }
+  if (has_snapset) {
+    if (!shard_result.has_snapset_missing()
+        && !shard_result.has_snapset_corrupted()) {
+      bufferlist can_bl, auth_bl;
+      auto can_attr = candidate.attrs.find(SS_ATTR);
+      auto auth_attr = auth.attrs.find(SS_ATTR);
+
+      assert(auth_attr != auth.attrs.end());
+      assert(can_attr != candidate.attrs.end());
+
+      can_bl.push_back(can_attr->second);
+      auth_bl.push_back(auth_attr->second);
+      if (!can_bl.contents_equal(auth_bl)) {
+         if (error != CLEAN)
+           errorstream << ", ";
+         error = FOUND_ERROR;
+         obj_result.set_snapset_inconsistency();
+         errorstream << "snapset inconsistent ";
+      }
+    }
+  }
+  if (parent->get_pool().is_erasure()) {
+    if (!shard_result.has_hinfo_missing()
+        && !shard_result.has_hinfo_corrupted()) {
+      bufferlist can_bl, auth_bl;
+      auto can_hi = candidate.attrs.find(ECUtil::get_hinfo_key());
+      auto auth_hi = auth.attrs.find(ECUtil::get_hinfo_key());
+
+      assert(auth_hi != auth.attrs.end());
+      assert(can_hi != candidate.attrs.end());
+
+      can_bl.push_back(can_hi->second);
+      auth_bl.push_back(auth_hi->second);
+      if (!can_bl.contents_equal(auth_bl)) {
+        if (error != CLEAN)
+         errorstream << ", ";
+       error = FOUND_ERROR;
+       obj_result.set_hinfo_inconsistency();
+       errorstream << "hinfo inconsistent ";
+      }
+    }
+  }
   uint64_t oi_size = be_get_ondisk_size(auth_oi.size);
   if (oi_size != candidate.size) {
     if (error != CLEAN)
@@ -761,12 +823,10 @@ map<pg_shard_t, ScrubMap *>::const_iterator
   const map<pg_shard_t,ScrubMap*> &maps,
   object_info_t *auth_oi,
   map<pg_shard_t, shard_info_wrapper> &shard_map,
-  inconsistent_obj_wrapper &object_error,
   bool &digest_match)
 {
   eversion_t auth_version;
   bool auth_prio = false;
-  bufferlist first_oi_bl, first_ss_bl, first_hk_bl;
 
   // Create list of shards with primary first so it will be auth copy all
   // other things being equal.
@@ -832,12 +892,6 @@ map<pg_shard_t, ScrubMap *>::const_iterator
         try {
          bufferlist::iterator bliter = ss_bl.begin();
          ::decode(ss, bliter);
-         if (first_ss_bl.length() == 0) {
-           first_ss_bl.append(ss_bl);
-         } else if (!object_error.has_snapset_inconsistency() && !ss_bl.contents_equal(first_ss_bl)) {
-           object_error.set_snapset_inconsistency();
-           error_string += " snapset_inconsistency";
-         }
         } catch (...) {
          // invalid snapset, probably corrupt
          shard_info.set_snapset_corrupted();
@@ -857,12 +911,6 @@ map<pg_shard_t, ScrubMap *>::const_iterator
         try {
          bufferlist::iterator bliter = hk_bl.begin();
          decode(hi, bliter);
-         if (first_hk_bl.length() == 0) {
-           first_hk_bl.append(hk_bl);
-         } else if (!object_error.has_hinfo_inconsistency() && !hk_bl.contents_equal(first_hk_bl)) {
-           object_error.set_hinfo_inconsistency();
-           error_string += " hinfo_inconsistency";
-         }
         } catch (...) {
          // invalid snapset, probably corrupt
          shard_info.set_hinfo_corrupted();
@@ -892,13 +940,6 @@ map<pg_shard_t, ScrubMap *>::const_iterator
     // This is automatically corrected in PG::_repair_oinfo_oid()
     assert(oi.soid == obj);
 
-    if (first_oi_bl.length() == 0) {
-      first_oi_bl.append(bl);
-    } else if (!object_error.has_object_info_inconsistency() && !bl.contents_equal(first_oi_bl)) {
-      object_error.set_object_info_inconsistency();
-      error_string += " object_info_inconsistency";
-    }
-
     if (i->second.size != be_get_ondisk_size(oi.size)) {
       dout(5) << __func__ << " size " << i->second.size << " oi size " << oi.size << dendl;
       shard_info.set_obj_size_info_mismatch();
@@ -983,8 +1024,7 @@ void PGBackend::be_compare_scrubmaps(
 
     bool digest_match;
     map<pg_shard_t, ScrubMap *>::const_iterator auth =
-      be_select_auth_object(*k, maps, &auth_oi, shard_map, object_error,
-                            digest_match);
+      be_select_auth_object(*k, maps, &auth_oi, shard_map, digest_match);
 
     list<pg_shard_t> auth_list;
     set<pg_shard_t> object_errors;
@@ -1020,7 +1060,8 @@ void PGBackend::be_compare_scrubmaps(
                                   j->second->objects[*k],
                                   shard_map[j->first],
                                   object_error,
-                                  ss);
+                                  ss,
+                                  k->has_snapset());
 
        dout(20) << __func__ << (repair ? " repair " : " ") << (parent->get_pool().is_replicated() ? "replicated " : "")
          << (j == auth ? "auth " : "") << "shards " << shard_map.size() << (digest_match ? " digest_match " : " ")
@@ -1057,12 +1098,11 @@ void PGBackend::be_compare_scrubmaps(
          if (found)
            errorstream << pgid << " shard " << j->first << ": soid " << *k
                      << " " << ss.str() << "\n";
-       } else if (object_error.errors != 0) {
+       } else if (found) {
          // Track possible shard to use as authoritative, if needed
          // There are errors, without identifying the shard
          object_errors.insert(j->first);
-         if (found)
-           errorstream << pgid << " : soid " << *k << " " << ss.str() << "\n";
+         errorstream << pgid << " : soid " << *k << " " << ss.str() << "\n";
        } else {
          // XXX: The auth shard might get here that we don't know
          // that it has the "correct" data.
index 054aa3e054a610253d189a2d283b0ed7e8caf484..40b1df81e41804d57466d3a3c72c873472399e78 100644 (file)
@@ -570,13 +570,13 @@ typedef ceph::shared_ptr<const OSDMap> OSDMapRef;
      const ScrubMap::object &candidate,
      shard_info_wrapper& shard_error,
      inconsistent_obj_wrapper &result,
-     ostream &errorstream);
+     ostream &errorstream,
+     bool has_snapset);
    map<pg_shard_t, ScrubMap *>::const_iterator be_select_auth_object(
      const hobject_t &obj,
      const map<pg_shard_t,ScrubMap*> &maps,
      object_info_t *auth_oi,
      map<pg_shard_t, shard_info_wrapper> &shard_map,
-     inconsistent_obj_wrapper &object_error,
      bool &digest_match);
    void be_compare_scrubmaps(
      const map<pg_shard_t,ScrubMap*> &maps,