From: Yehuda Sadeh Date: Tue, 13 Jan 2015 21:31:39 +0000 (-0800) Subject: rgw: fix memory leak X-Git-Tag: v0.92~12^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=24aec123fb9acf081eb1bbc893183f802d8b1ec2;p=ceph.git rgw: fix memory leak We were iterating on both completion_objs, and completions assuming that they follow each other. They don't do it. While at it, index completions by id, so that we could update the completed objs correctly. Signed-off-by: Yehuda Sadeh --- diff --git a/src/cls/rgw/cls_rgw_client.cc b/src/cls/rgw/cls_rgw_client.cc index 1f7ff4fc05e6..fa33dac24be2 100644 --- a/src/cls/rgw/cls_rgw_client.cc +++ b/src/cls/rgw/cls_rgw_client.cc @@ -45,7 +45,7 @@ void BucketIndexAioManager::do_completion(int id) { map::iterator iter = pendings.find(id); assert(iter != pendings.end()); - completions.push_back(iter->second); + completions[id] = iter->second; pendings.erase(iter); // If the caller needs a list of finished objects, store them @@ -70,16 +70,18 @@ bool BucketIndexAioManager::wait_for_completions(int valid_ret_code, cond.Wait(lock); // Clear the completed AIOs - list::iterator iter = completions.begin(); - map::iterator liter = completion_objs.begin(); - for (; iter != completions.end() && liter != completion_objs.end(); ++iter, ++liter) { - int r = (*iter)->get_return_value(); - if (objs && r == 0) { - (*objs)[liter->first] = liter->second; + map::iterator iter = completions.begin(); + for (; iter != completions.end(); ++iter) { + int r = iter->second->get_return_value(); + if (objs && r == 0) { /* update list of successfully completed objs */ + map::iterator liter = completion_objs.find(iter->first); + if (liter != completion_objs.end()) { + (*objs)[liter->first] = liter->second; + } } if (ret_code && (r < 0 && r != valid_ret_code)) (*ret_code) = r; - (*iter)->release(); + iter->second->release(); } if (num_completions) (*num_completions) = completions.size(); diff --git a/src/cls/rgw/cls_rgw_client.h b/src/cls/rgw/cls_rgw_client.h index c54b3330b508..e0c527094b73 100644 --- a/src/cls/rgw/cls_rgw_client.h +++ b/src/cls/rgw/cls_rgw_client.h @@ -30,7 +30,7 @@ struct BucketIndexAioArg : public RefCountedObject { class BucketIndexAioManager { private: map pendings; - list completions; + map completions; map pending_objs; map completion_objs; int next; @@ -60,11 +60,9 @@ private: * @param oid - the object id associated with the object, if it is NULL, we don't * track the object id per callback. */ - void add_pending(int id, librados::AioCompletion* completion, string *oid = NULL) { + void add_pending(int id, librados::AioCompletion* completion, const string& oid) { pendings[id] = completion; - if (oid) { - pending_objs[id] = *oid; - } + pending_objs[id] = oid; } public: /* @@ -100,7 +98,7 @@ public: librados::AioCompletion *c = librados::Rados::aio_create_completion((void*)arg, NULL, bucket_index_op_completion_cb); int r = io_ctx.aio_operate(oid, c, (librados::ObjectReadOperation*)op, NULL); if (r >= 0) { - add_pending(arg->id, c); + add_pending(arg->id, c, oid); } return r; } @@ -114,7 +112,7 @@ public: librados::AioCompletion *c = librados::Rados::aio_create_completion((void*)arg, NULL, bucket_index_op_completion_cb); int r = io_ctx.aio_operate(oid, c, (librados::ObjectWriteOperation*)op); if (r >= 0) { - add_pending(arg->id, c); + add_pending(arg->id, c, oid); } return r; } @@ -241,7 +239,8 @@ public: int num_completions, r = 0; map objs; - while (manager.wait_for_completions(valid_ret_code(), &num_completions, &r, &objs)) { + map *pobjs = (need_multiple_rounds() ? &objs : NULL); + while (manager.wait_for_completions(valid_ret_code(), &num_completions, &r, pobjs)) { if (r >= 0 && ret >= 0) { for(int i = 0; i < num_completions && iter != objs_container.end(); ++i, ++iter) { int issue_ret = issue_op(iter->first, iter->second);