]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Check for and automatically repair object info soid during scrub
authorDavid Zafman <dzafman@redhat.com>
Fri, 30 Jun 2017 23:04:02 +0000 (16:04 -0700)
committerDavid Zafman <dzafman@redhat.com>
Tue, 27 Feb 2018 18:20:13 +0000 (10:20 -0800)
Fixes: http://tracker.ceph.com/issues/20471
Signed-off-by: David Zafman <dzafman@redhat.com>
(cherry picked from commit 22f4d0cc010c5887b52847f050a361bc1ac20e40)

src/osd/PG.cc
src/osd/PG.h

index 28937961b15d4cc9e15b2e7cfcddeee76f880154..d05dc6bc7f17052556012a0cada4d5027acc6753 100644 (file)
@@ -3927,6 +3927,52 @@ void PG::_scan_snaps(ScrubMap &smap)
   }
 }
 
+void PG::_repair_oinfo_oid(ScrubMap &smap)
+{
+  for (map<hobject_t, ScrubMap::object>::reverse_iterator i = smap.objects.rbegin();
+       i != smap.objects.rend();
+       ++i) {
+    const hobject_t &hoid = i->first;
+    ScrubMap::object &o = i->second;
+
+    bufferlist bl;
+    if (o.attrs.find(OI_ATTR) == o.attrs.end()) {
+      continue;
+    }
+    bl.push_back(o.attrs[OI_ATTR]);
+    object_info_t oi;
+    try {
+      oi.decode(bl);
+    } catch(...) {
+      continue;
+    }
+    if (oi.soid != hoid) {
+      ObjectStore::Transaction t;
+      OSDriver::OSTransaction _t(osdriver.get_transaction(&t));
+      osd->clog->error() << "osd." << osd->whoami
+                           << " found object info error on pg "
+                           << info.pgid
+                           << " oid " << hoid << " oid in object info: "
+                           << oi.soid
+                           << "...repaired";
+      // Fix object info
+      oi.soid = hoid;
+      bl.clear();
+      ::encode(oi, bl, get_osdmap()->get_features(CEPH_ENTITY_TYPE_OSD, nullptr));
+
+      bufferptr bp(bl.c_str(), bl.length());
+      o.attrs[OI_ATTR] = bp;
+
+      t.setattr(coll, ghobject_t(hoid), OI_ATTR, bl);
+      int r = osd->store->apply_transaction(osr.get(), std::move(t));
+      if (r != 0) {
+       derr << __func__ << ": apply_transaction got " << cpp_strerror(r)
+            << dendl;
+      }
+    }
+  }
+}
+
 /*
  * build a scrub map over a chunk without releasing the lock
  * only used by chunky scrub
@@ -3959,6 +4005,7 @@ int PG::build_scrub_map_chunk(
   get_pgbackend()->be_scan_list(map, ls, deep, seed, handle);
   _scan_rollback_obs(rollback_obs, handle);
   _scan_snaps(map);
+  _repair_oinfo_oid(map);
 
   dout(20) << __func__ << " done" << dendl;
   return 0;
index 3ed3c5238e5e2395e86f3f8c2f056d3797f77dc4..696913c76d71278a2340a78c1fc1d2608fdae006 100644 (file)
@@ -1326,6 +1326,7 @@ public:
   void scrub_finish();
   void scrub_clear_state();
   void _scan_snaps(ScrubMap &map);
+  void _repair_oinfo_oid(ScrubMap &map);
   void _scan_rollback_obs(
     const vector<ghobject_t> &rollback_obs,
     ThreadPool::TPHandle &handle);