]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix additional errors during missed shared blob repair. 43887/head
authorIgor Fedotov <ifedotov@suse.com>
Wed, 21 Jul 2021 12:28:52 +0000 (15:28 +0300)
committerIgor Fedotov <ifed@suse.com>
Thu, 11 Nov 2021 11:52:31 +0000 (14:52 +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 1da41d99a08a04191b36b284e4b32b3d1883d3c9..1765826ee41e6bf427f9674d35bf1db5d77b7526 100644 (file)
@@ -8798,9 +8798,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,
@@ -9025,9 +9025,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;
+         }
         }
       }
     }
@@ -9266,6 +9289,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 218e59da862b9be6dbd806c13519a5791f29f644..720d81dcdbfac6dfda7e3f0f5cf0a418df1031d4 100644 (file)
@@ -2866,6 +2866,8 @@ public:
   /// methods to inject various errors fsck can repair
   void inject_broken_shared_blob_key(const string& key,
                         const bufferlist& 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 string& key, const store_statfs_t& new_statfs);