@@ -76,19 +76,29 @@ struct OMapInnerNode
7676 }
7777
7878 void prepare_commit() final {
79+ if (unlikely(!is_seen_by_users())) {
80+ ceph_assert(is_rewrite());
81+ auto &prior = *get_prior_instance()->template cast<OMapInnerNode>();
82+ if (!prior.is_seen_by_users()) {
83+ return;
84+ }
85+ set_seen_by_users();
86+ }
7987 this->parent_node_t::prepare_commit();
80- if (is_rewrite() && !is_btree_root() ) {
88+ if (is_rewrite()) {
8189 auto &prior = *get_prior_instance()->template cast<OMapInnerNode>();
82- if (prior.base_child_t::has_parent_tracker()) {
83- assert(prior.is_seen_by_users());
90+ assert(prior.is_seen_by_users());
91+ // Chances are that this transaction is in parallel with another
92+ // user transaction that set the prior's root to true, so we need
93+ // to do this.
94+ set_root(prior.is_btree_root());
95+ if (!is_btree_root()) {
96+ assert(prior.base_child_t::has_parent_tracker());
97+ assert(prior.is_seen_by_users());
8498 // unlike fixed-kv nodes, rewriting child nodes of the omap tree
8599 // won't affect parent nodes, so we have to manually take prior
86100 // instances' parent trackers here.
87101 this->child_node_t::take_parent_from_prior();
88- } else {
89- // dirty omap extent may not be accessed yet during rewrite,
90- // this means the extent may not be initalized yet as linked.
91- assert(!prior.is_seen_by_users());
92102 }
93103 }
94104 }
@@ -292,18 +302,28 @@ struct OMapLeafNode
292302 }
293303
294304 void prepare_commit() final {
295- if (is_rewrite() && !is_btree_root()) {
305+ if (unlikely(!is_seen_by_users())) {
306+ ceph_assert(is_rewrite());
307+ auto &prior = *get_prior_instance()->template cast<OMapLeafNode>();
308+ if (!prior.is_seen_by_users()) {
309+ return;
310+ }
311+ set_seen_by_users();
312+ }
313+ if (is_rewrite()) {
296314 auto &prior = *get_prior_instance()->template cast<OMapLeafNode>();
297- if (prior.base_child_t::has_parent_tracker()) {
298- assert(prior.is_seen_by_users());
315+ assert(prior.is_seen_by_users());
316+ // Chances are that this transaction is in parallel with another
317+ // user transaction that set the prior's root to true, so we need
318+ // to do this.
319+ set_root(prior.is_btree_root());
320+ if (!is_btree_root()) {
321+ assert(prior.base_child_t::has_parent_tracker());
322+ assert(prior.is_seen_by_users());
299323 // unlike fixed-kv nodes, rewriting child nodes of the omap tree
300324 // won't affect parent nodes, so we have to manually take prior
301325 // instances' parent trackers here.
302326 this->child_node_t::take_parent_from_prior();
303- } else {
304- // dirty omap extent may not be accessed yet during rewrite,
305- // this means the extent may not be initalized yet as linked.
306- assert(!prior.is_seen_by_users());
307327 }
308328 }
309329 }
0 commit comments