From e7faed5d903cf7681d77a6af53cf8137eeb2fc69 Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Thu, 6 Nov 2014 17:11:20 +0100 Subject: [PATCH] osd: deep scrub must not abort if hinfo is missing Instead it should set read_error. http://tracker.ceph.com/issues/10018 Fixes: #10018 Signed-off-by: Loic Dachary (cherry picked from commit 9d84d2e8309d26e39ca849a75166d2d7f2dec9ea) --- src/osd/ECBackend.cc | 50 ++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/osd/ECBackend.cc b/src/osd/ECBackend.cc index 1497f7e2bd4d3..78e7699ae85b6 100644 --- a/src/osd/ECBackend.cc +++ b/src/osd/ECBackend.cc @@ -1245,10 +1245,18 @@ void ECBackend::submit_transaction( for (set::iterator i = need_hinfos.begin(); i != need_hinfos.end(); ++i) { + ECUtil::HashInfoRef ref = get_hash_info(*i); + if (!ref) { + derr << __func__ << ": get_hash_info(" << *i << ")" + << " returned a null pointer and there is no " + << " way to recover from such an error in this " + << " context" << dendl; + assert(0); + } op->unstable_hash_infos.insert( make_pair( *i, - get_hash_info(*i))); + ref)); } for (vector::iterator i = op->log_entries.begin(); @@ -1458,7 +1466,7 @@ ECUtil::HashInfoRef ECBackend::get_hash_info( ::decode(hinfo, bp); assert(hinfo.get_total_chunk_size() == (uint64_t)st.st_size); } else { - assert(0 == "missing hash attr"); + return ECUtil::HashInfoRef(); } } ref = unstable_hashinfo_registry.lookup_or_create(hoid, hinfo); @@ -1756,31 +1764,37 @@ void ECBackend::be_deep_scrub( break; } - ECUtil::HashInfoRef hinfo = get_hash_info(poid); if (r == -EIO) { dout(0) << "_scan_list " << poid << " got " << r << " on read, read_error" << dendl; o.read_error = true; } - if (hinfo->get_chunk_hash(get_parent()->whoami_shard().shard) != h.digest()) { - dout(0) << "_scan_list " << poid << " got incorrect hash on read" << dendl; + ECUtil::HashInfoRef hinfo = get_hash_info(poid); + if (!hinfo) { + dout(0) << "_scan_list " << poid << " could not retrieve hash info" << dendl; o.read_error = true; - } + o.digest_present = false; + } else { + if (hinfo->get_chunk_hash(get_parent()->whoami_shard().shard) != h.digest()) { + dout(0) << "_scan_list " << poid << " got incorrect hash on read" << dendl; + o.read_error = true; + } - if (hinfo->get_total_chunk_size() != pos) { - dout(0) << "_scan_list " << poid << " got incorrect size on read" << dendl; - o.read_error = true; - } + if (hinfo->get_total_chunk_size() != pos) { + dout(0) << "_scan_list " << poid << " got incorrect size on read" << dendl; + o.read_error = true; + } - /* We checked above that we match our own stored hash. We cannot - * send a hash of the actual object, so instead we simply send - * our locally stored hash of shard 0 on the assumption that if - * we match our chunk hash and our recollection of the hash for - * chunk 0 matches that of our peers, there is likely no corruption. - */ - o.digest = hinfo->get_chunk_hash(0); - o.digest_present = true; + /* We checked above that we match our own stored hash. We cannot + * send a hash of the actual object, so instead we simply send + * our locally stored hash of shard 0 on the assumption that if + * we match our chunk hash and our recollection of the hash for + * chunk 0 matches that of our peers, there is likely no corruption. + */ + o.digest = hinfo->get_chunk_hash(0); + o.digest_present = true; + } o.omap_digest = 0; o.omap_digest_present = true; -- 2.39.5