Onodes hold references to the onode tree extents. And if it's referencing the root extent, that root
extent is cached in the onode trees root_tracker which caches onode tree roots by transaction address.
Than root_tracker entry only gets removed when the onode(or the corresponding "super") is destroyed.
On the other hand, two non-concurrent transactions can occupy the same address. So if an onode gets destroyed
after its transaction is destroyed, there will be a chance that another transaction occupying the same
address get that not-yet-destroyed and may-be-outdated onode.
BTW, Since we already cache extents in transactions, might want to drop onode tree root_tracker later?
Fixes: https://tracker.ceph.com/issues/53651
Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
).si_then([&](auto onode_ret) {
onode = std::move(onode_ret);
return f(t, *onode);
- }).si_then([&ret](auto _ret) {
+ }).si_then([&ret, &onode](auto _ret) {
+ onode.reset();
ret = _ret;
});
});