From 22f4d0cc010c5887b52847f050a361bc1ac20e40 Mon Sep 17 00:00:00 2001 From: David Zafman Date: Fri, 30 Jun 2017 16:04:02 -0700 Subject: [PATCH] osd: Check for and automatically repair object info soid during scrub Fixes: http://tracker.ceph.com/issues/20471 Signed-off-by: David Zafman --- src/osd/PG.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/osd/PG.h | 1 + 2 files changed, 48 insertions(+) diff --git a/src/osd/PG.cc b/src/osd/PG.cc index f2ee9d952ae..725c5dd2d5a 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -4023,6 +4023,52 @@ void PG::_scan_snaps(ScrubMap &smap) } } +void PG::_repair_oinfo_oid(ScrubMap &smap) +{ + for (map::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 @@ -4055,6 +4101,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; diff --git a/src/osd/PG.h b/src/osd/PG.h index 36ed41a22ce..a033763b4f9 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -1347,6 +1347,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 &rollback_obs, ThreadPool::TPHandle &handle); -- 2.39.5