ReplicatedPG::new_repop() returns a pointer to RepGather with two refcounts,
one is held by ReplicatedPG::repop_queue, the other is supposed to be
held by the caller of this function. but it's caller
ReplicatedPG::submit_log_entries() assigns it to a
boost::intrusive_ptr<RepGather>() directly, why by default add_ref() in
its constructor. this makes the refcount 3. that's why we have a leak of
RepGather in `ReplicatedPG::new_repop(ObcLockManager&&,
boost::optional<std::function<void ()>>&&)`.
Fixes: http://tracker.ceph.com/issues/16801
Signed-off-by: Kefu Chai <kchai@redhat.com>
return repop;
}
-ReplicatedPG::RepGather *ReplicatedPG::new_repop(
+boost::intrusive_ptr<ReplicatedPG::RepGather> ReplicatedPG::new_repop(
ObcLockManager &&manager,
boost::optional<std::function<void(void)> > &&on_complete)
{
repop->start = ceph_clock_now(cct);
repop_queue.push_back(&repop->queue_item);
- repop->get();
osd->logger->inc(l_osd_op_wip);
- return repop;
+ return boost::intrusive_ptr<RepGather>(repop);
}
void ReplicatedPG::remove_repop(RepGather *repop)
OpContext *ctx,
ObjectContextRef obc,
ceph_tid_t rep_tid);
- RepGather *new_repop(
+ boost::intrusive_ptr<RepGather> new_repop(
ObcLockManager &&manager,
boost::optional<std::function<void(void)> > &&on_complete);
void remove_repop(RepGather *repop);