]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix additional errors during missed shared blob repair.
authorIgor Fedotov <ifedotov@suse.com>
Wed, 21 Jul 2021 12:28:52 +0000 (15:28 +0300)
committerIgor Fedotov <ifed@suse.com>
Fri, 29 Oct 2021 12:37:27 +0000 (15:37 +0300)
Fixes: https://tracker.ceph.com/issues/51762
Signed-off-by: Igor Fedotov <ifedotov@suse.com>
(cherry picked from commit d92ebd3ebea9a153c22a711bb2aae0ce17f5b304)

src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index 232e44d949d92b5eb4fc4cd2bb1886e595da1d75..5d50ff5b55bb7c9bef65bbb27dcaf8b45b4fef34 100644 (file)
@@ -8461,9 +8461,9 @@ int BlueStore::_fsck_on_open(BlueStore::FSCKDepth depth, bool repair)
          expected_statfs = &expected_pool_statfs[sbi.pool_id];
        }
        errors += _fsck_check_extents(sbi.cid,
-                                     p->second.oids.front(),
+                                     sbi.oids.front(),
                                      extents,
-                                     p->second.compressed,
+                                     sbi.compressed,
                                      used_blocks,
                                      fm->get_alloc_size(),
                                      repair ? &repairer : nullptr,
@@ -8689,9 +8689,32 @@ int BlueStore::_fsck_on_open(BlueStore::FSCKDepth depth, bool repair)
          bluestore_shared_blob_t persistent(sbid, std::move(sbi.ref_map));
          encode(persistent, bl);
          dout(20) << __func__ << " " << *sbi.sb
-                  << " is " << bl.length() << " bytes, updating" << dendl;
+                  << " is " << bl.length() << " bytes, updating"
+                  << dendl;
 
          repairer.fix_shared_blob(db, sbid, &bl);
+         // we need to account for shared blob pextents at both
+         // stats and used blocks to avoid related errors.
+         PExtentVector extents;
+         for (auto& r : persistent.ref_map.ref_map) {
+           extents.emplace_back(bluestore_pextent_t(r.first, r.second.length));
+         }
+         auto* expected_statfs = &expected_pool_statfs[sbi.pool_id];
+         int errors = _fsck_check_extents(sbi.cid,
+           ghobject_t(), // doesn't matter
+           extents,
+           sbi.compressed,
+           used_blocks,
+           fm->get_alloc_size(),
+           nullptr,
+           *expected_statfs,
+           depth);
+         if (errors) {
+           derr << __func__ << " " << errors
+                << "  unexpected error(s) after missed shared blob repair,"
+                << " perhaps worth one more repair attempt"
+                << dendl;
+         }
         }
       }
     }
@@ -8945,6 +8968,23 @@ void BlueStore::inject_broken_shared_blob_key(const string& key,
   db->submit_transaction_sync(txn);
 };
 
+void BlueStore::inject_no_shared_blob_key()
+{
+  KeyValueDB::Transaction txn;
+  txn = db->get_transaction();
+  ceph_assert(blobid_last > 0);
+  // kill the last used sbid, this can be broken due to blobid preallocation
+  // in rare cases, leaving as-is for the sake of simplicity
+  uint64_t sbid = blobid_last;
+
+  string key;
+  dout(5) << __func__<< " " << sbid << dendl;
+  get_shared_blob_key(sbid, &key);
+  txn->rmkey(PREFIX_SHARED_BLOB, key);
+  db->submit_transaction_sync(txn);
+};
+
+
 void BlueStore::inject_leaked(uint64_t len)
 {
   KeyValueDB::Transaction txn;
index 0690717c8b4b48b9c86eb13c937eae573f8381bd..3783f12c928dbbd5520277cb3bcdcb12e7162a40 100644 (file)
@@ -3009,6 +3009,8 @@ public:
   /// methods to inject various errors fsck can repair
   void inject_broken_shared_blob_key(const std::string& key,
                         const ceph::buffer::list& bl);
+  void inject_no_shared_blob_key();
+
   void inject_leaked(uint64_t len);
   void inject_false_free(coll_t cid, ghobject_t oid);
   void inject_statfs(const std::string& key, const store_statfs_t& new_statfs);