From: Casey Bodley Date: Wed, 21 Dec 2016 19:32:04 +0000 (-0500) Subject: rgw: RGWMetaSyncShardCR drops stack refs on destruction X-Git-Tag: v11.2.0~6^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9e2d19238735b0c6503fd61627a601174edaaaac;p=ceph.git rgw: RGWMetaSyncShardCR drops stack refs on destruction if the coroutine is canceled before collect_children() can clean up all of its child stacks, those stack refs will leak. store these stacks as boost::intrusive_ptr so the ref is dropped automatically on destruction Fixes: http://tracker.ceph.com/issues/18300 Signed-off-by: Casey Bodley (cherry picked from commit 060fe72faf6a483a36d481207c6624c46a414231) --- diff --git a/src/rgw/rgw_sync.cc b/src/rgw/rgw_sync.cc index c44305edf33c..590b3f9eb39e 100644 --- a/src/rgw/rgw_sync.cc +++ b/src/rgw/rgw_sync.cc @@ -1269,7 +1269,9 @@ class RGWMetaSyncShardCR : public RGWCoroutine { bool *reset_backoff; - map stack_to_pos; + // hold a reference to the cr stack while it's in the map + using StackRef = boost::intrusive_ptr; + map stack_to_pos; map pos_to_prev; bool can_adjust_marker = false; @@ -1331,7 +1333,7 @@ public: int child_ret; RGWCoroutinesStack *child; while (collect_next(&child_ret, &child)) { - map::iterator iter = stack_to_pos.find(child); + auto iter = stack_to_pos.find(child); if (iter == stack_to_pos.end()) { /* some other stack that we don't care about */ continue; @@ -1371,8 +1373,6 @@ public: ldout(sync_env->cct, 0) << *this << ": adjusting marker pos=" << sync_marker.marker << dendl; stack_to_pos.erase(iter); - - child->put(); } } @@ -1443,8 +1443,7 @@ public: // fetch remote and write locally yield { RGWCoroutinesStack *stack = spawn(new RGWMetaSyncSingleEntryCR(sync_env, iter->first, iter->first, MDLOG_STATUS_COMPLETE, marker_tracker), false); - stack->get(); - + // stack_to_pos holds a reference to the stack stack_to_pos[stack] = iter->first; pos_to_prev[iter->first] = marker; } @@ -1592,8 +1591,7 @@ public: yield { RGWCoroutinesStack *stack = spawn(new RGWMetaSyncSingleEntryCR(sync_env, raw_key, log_iter->id, mdlog_entry.log_data.status, marker_tracker), false); assert(stack); - stack->get(); - + // stack_to_pos holds a reference to the stack stack_to_pos[stack] = log_iter->id; pos_to_prev[log_iter->id] = marker; }