From: Igor Fedotov Date: Wed, 21 Jul 2021 12:28:52 +0000 (+0300) Subject: os/bluestore: fix additional errors during missed shared blob repair. X-Git-Tag: v16.2.7~42^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bd971c086b574e54c87041d2a4f8ae46563d78a5;p=ceph.git os/bluestore: fix additional errors during missed shared blob repair. Fixes: https://tracker.ceph.com/issues/51762 Signed-off-by: Igor Fedotov (cherry picked from commit d92ebd3ebea9a153c22a711bb2aae0ce17f5b304) --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 232e44d949d9..5d50ff5b55bb 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -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; diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 0690717c8b4b..3783f12c928d 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -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);