From: David Zafman Date: Tue, 4 Aug 2015 20:38:13 +0000 (-0700) Subject: osd: Fix ECBackend to handle mismatch of total chunk size X-Git-Tag: v9.1.0~244^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=da2987d79db679e7b44d7886462c81d34994af26;p=ceph.git osd: Fix ECBackend to handle mismatch of total chunk size Fixes: #12200 Signed-off-by: David Zafman --- diff --git a/src/osd/ECBackend.cc b/src/osd/ECBackend.cc index 50e8a5b33c5..21816346279 100644 --- a/src/osd/ECBackend.cc +++ b/src/osd/ECBackend.cc @@ -1297,7 +1297,7 @@ void ECBackend::submit_transaction( for (set::iterator i = need_hinfos.begin(); i != need_hinfos.end(); ++i) { - ECUtil::HashInfoRef ref = get_hash_info(*i); + ECUtil::HashInfoRef ref = get_hash_info(*i, false); if (!ref) { derr << __func__ << ": get_hash_info(" << *i << ")" << " returned a null pointer and there is no " @@ -1505,7 +1505,7 @@ void ECBackend::start_read_op( } ECUtil::HashInfoRef ECBackend::get_hash_info( - const hobject_t &hoid) + const hobject_t &hoid, bool checks) { dout(10) << __func__ << ": Getting attr on " << hoid << dendl; ECUtil::HashInfoRef ref = unstable_hashinfo_registry.lookup(hoid); @@ -1517,7 +1517,8 @@ ECUtil::HashInfoRef ECBackend::get_hash_info( ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard), &st); ECUtil::HashInfo hinfo(ec_impl->get_chunk_count()); - if (r >= 0 && st.st_size > 0) { + // XXX: What does it mean if there is no object on disk? + if (r >= 0) { dout(10) << __func__ << ": found on disk, size " << st.st_size << dendl; bufferlist bl; r = store->getattr( @@ -1528,8 +1529,12 @@ ECUtil::HashInfoRef ECBackend::get_hash_info( if (r >= 0) { bufferlist::iterator bp = bl.begin(); ::decode(hinfo, bp); - assert(hinfo.get_total_chunk_size() == (uint64_t)st.st_size); - } else { + if (checks && hinfo.get_total_chunk_size() != (uint64_t)st.st_size) { + dout(0) << __func__ << ": Mismatch of total_chunk_size " + << hinfo.get_total_chunk_size() << dendl; + return ECUtil::HashInfoRef(); + } + } else if (st.st_size > 0) { // If empty object and no hinfo, create it return ECUtil::HashInfoRef(); } } @@ -1845,7 +1850,7 @@ void ECBackend::be_deep_scrub( o.read_error = true; } - ECUtil::HashInfoRef hinfo = get_hash_info(poid); + ECUtil::HashInfoRef hinfo = get_hash_info(poid, false); if (!hinfo) { dout(0) << "_scan_list " << poid << " could not retrieve hash info" << dendl; o.read_error = true; diff --git a/src/osd/ECBackend.h b/src/osd/ECBackend.h index 8f5201c5d26..f416e30f3f8 100644 --- a/src/osd/ECBackend.h +++ b/src/osd/ECBackend.h @@ -447,7 +447,7 @@ public: const ECUtil::stripe_info_t sinfo; /// If modified, ensure that the ref is held until the update is applied SharedPtrRegistry unstable_hashinfo_registry; - ECUtil::HashInfoRef get_hash_info(const hobject_t &hoid); + ECUtil::HashInfoRef get_hash_info(const hobject_t &hoid, bool checks = true); friend struct ReadCB; void check_op(Op *op);