tls.push_back(std::move(op.t));
    tls.push_back(std::move(localt));
    get_parent()->queue_transactions(tls, msg);
 +  dout(30) << __func__ << " missing after" << get_parent()->get_log().get_missing().get_items() << dendl;
+   if (op.at_version != eversion_t()) {
+     // dummy rollforward transaction doesn't get at_version (and doesn't advance it)
+     get_parent()->op_applied(op.at_version);
+   }
  }
  
  void ECBackend::handle_sub_read(
 
        new OnComplete{this, rep_tid, get_osdmap()->get_epoch()});
        int r = osd->store->queue_transaction(ch, std::move(t), NULL);
        assert(r == 0);
+       op_applied(info.last_update);
      });
 +
 +  calc_trim_to();
  }
  
  void PrimaryLogPG::cancel_log_updates()
 
      append_log(logv, trim_to, roll_forward_to, t, transaction_applied);
    }
  
+   void op_applied(const eversion_t &applied_version) override;
+ 
    bool should_send_op(
      pg_shard_t peer,
 -    const hobject_t &hoid) override {
 -    if (peer == get_primary())
 -      return true;
 -    assert(peer_info.count(peer));
 -    bool should_send =
 -      hoid.pool != (int64_t)info.pgid.pool() ||
 -      hoid <= last_backfill_started ||
 -      hoid <= peer_info[peer].last_backfill;
 -    if (!should_send)
 -      assert(is_backfill_targets(peer));
 -    return should_send;
 -  }
 +    const hobject_t &hoid) override;
  
    bool pg_is_undersized() const override {
      return is_undersized();