mirror of
https://github.com/ceph/ceph
synced 2025-02-24 03:27:10 +00:00
crimson/os/seastore: fix bug in check_node
EXIST_CLEAN and EXIST_MUTATION_PENDING shuold not be treated as CLEAN in check_node because they are transaction private and the leafnode has been duplicated for write. fix: https://tracker.ceph.com/issues/61626 Signed-off-by: Xinyu Huang <xinyu.huang@intel.com>
This commit is contained in:
parent
ea80783410
commit
f02f20c2ae
@ -506,28 +506,7 @@ public:
|
||||
}
|
||||
}
|
||||
if (ret == Transaction::get_extent_ret::PRESENT) {
|
||||
if (child_node->is_mutation_pending()) {
|
||||
auto &prior = (child_node_t &)*child_node->prior_instance;
|
||||
assert(prior.is_valid());
|
||||
assert(prior.is_parent_valid());
|
||||
if (node->is_mutation_pending()) {
|
||||
auto &n = node->get_stable_for_key(i->get_key());
|
||||
assert(prior.get_parent_node().get() == &n);
|
||||
auto pos = n.lower_bound_offset(i->get_key());
|
||||
assert(pos < n.get_node_size());
|
||||
assert(n.children[pos] == &prior);
|
||||
} else {
|
||||
assert(prior.get_parent_node().get() == node.get());
|
||||
assert(node->children[i->get_offset()] == &prior);
|
||||
}
|
||||
} else if (child_node->is_initial_pending()) {
|
||||
auto cnode = child_node->template cast<child_node_t>();
|
||||
auto pos = node->find(i->get_key()).get_offset();
|
||||
auto child = node->children[pos];
|
||||
assert(child);
|
||||
assert(child == cnode.get());
|
||||
assert(cnode->is_parent_valid());
|
||||
} else {
|
||||
if (child_node->is_stable()) {
|
||||
assert(child_node->is_valid());
|
||||
auto cnode = child_node->template cast<child_node_t>();
|
||||
assert(cnode->has_parent_tracker());
|
||||
@ -541,6 +520,32 @@ public:
|
||||
assert(cnode->get_parent_node().get() == node.get());
|
||||
assert(node->children[i->get_offset()] == cnode.get());
|
||||
}
|
||||
} else if (child_node->is_pending()) {
|
||||
if (child_node->is_mutation_pending()) {
|
||||
auto &prior = (child_node_t &)*child_node->prior_instance;
|
||||
assert(prior.is_valid());
|
||||
assert(prior.is_parent_valid());
|
||||
if (node->is_mutation_pending()) {
|
||||
auto &n = node->get_stable_for_key(i->get_key());
|
||||
assert(prior.get_parent_node().get() == &n);
|
||||
auto pos = n.lower_bound_offset(i->get_key());
|
||||
assert(pos < n.get_node_size());
|
||||
assert(n.children[pos] == &prior);
|
||||
} else {
|
||||
assert(prior.get_parent_node().get() == node.get());
|
||||
assert(node->children[i->get_offset()] == &prior);
|
||||
}
|
||||
} else {
|
||||
auto cnode = child_node->template cast<child_node_t>();
|
||||
auto pos = node->find(i->get_key()).get_offset();
|
||||
auto child = node->children[pos];
|
||||
assert(child);
|
||||
assert(child == cnode.get());
|
||||
assert(cnode->is_parent_valid());
|
||||
}
|
||||
} else {
|
||||
ceph_assert(!child_node->is_valid());
|
||||
ceph_abort("impossible");
|
||||
}
|
||||
} else if (ret == Transaction::get_extent_ret::ABSENT) {
|
||||
ChildableCachedExtent* child = nullptr;
|
||||
|
@ -415,6 +415,13 @@ public:
|
||||
return is_mutable() || state == extent_state_t::EXIST_CLEAN;
|
||||
}
|
||||
|
||||
/// Returns true if extent is stable and shared among transactions
|
||||
bool is_stable() const {
|
||||
return state == extent_state_t::CLEAN_PENDING ||
|
||||
state == extent_state_t::CLEAN ||
|
||||
state == extent_state_t::DIRTY;
|
||||
}
|
||||
|
||||
/// Returns true if extent has a pending delta
|
||||
bool is_mutation_pending() const {
|
||||
return state == extent_state_t::MUTATION_PENDING;
|
||||
|
Loading…
Reference in New Issue
Block a user