]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Fix ECBackend to handle mismatch of total chunk size
authorDavid Zafman <dzafman@redhat.com>
Tue, 4 Aug 2015 20:38:13 +0000 (13:38 -0700)
committerDavid Zafman <dzafman@redhat.com>
Thu, 27 Aug 2015 21:03:22 +0000 (14:03 -0700)
Fixes: #12200
Signed-off-by: David Zafman <dzafman@redhat.com>
src/osd/ECBackend.cc
src/osd/ECBackend.h

index 50e8a5b33c52ad634e7da38ae2b317ff46cfbee5..21816346279119ac3a469234f83caf96cb322eab 100644 (file)
@@ -1297,7 +1297,7 @@ void ECBackend::submit_transaction(
   for (set<hobject_t, hobject_t::BitwiseComparator>::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;
index 8f5201c5d26be056c1670aec13c203909d08f1d8..f416e30f3f8d2885968d4f24bcdd6316243b0e98 100644 (file)
@@ -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<hobject_t, ECUtil::HashInfo, hobject_t::BitwiseComparator> 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);