with_head_obc() uses get_cached_obc() to get_or_create obc instances.
If the obc exists in cache, get_or_load_obc is called with `existed`=true.
The assumption above is wrong.
Cache existence (`existed`) only guarantees that the obc instance was created (and inserted) in the obc_registery.
However, it does **not** assure that the obc was actually loaded.
As obc-loading is now concurrent, it's possible for the first user to only create the obc in
cache (without loading yet) and the second concurrent user to assume it was already loaded.
With this patch, we verify that the obc was loaded in get_or_load_obc.
* make loading-obc concurrent PR: https://github.com/ceph/ceph/pull/55488
Fixes: https://tracker.ceph.com/issues/64206
Fixes: https://tracker.ceph.com/issues/66214
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
(cherry picked from commit
0b90ee74e06cc5a3a30088fa39fde5634148bda1)
}
}
+ bool is_loaded() const {
+ return fully_loaded;
+ }
+
+ bool is_valid() const {
+ return !invalidated_by_interval_change;
+ }
+
bool is_loaded_and_valid() const {
- return fully_loaded && !invalidated_by_interval_change;
+ return is_loaded() && is_valid();
}
private:
LOG_PREFIX(ObjectContextLoader::get_or_load_obc);
auto loaded =
load_obc_iertr::make_ready_future<ObjectContextRef>(obc);
- if (existed) {
+ if (existed && obc->is_loaded()) {
if (!obc->is_loaded_and_valid()) {
ERRORDPP(
"obc for {} invalid -- fully_loaded={}, "