From 6e6c34f9d6132720cc3808facb62f58bdecc0580 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 10 Feb 2012 14:45:27 -0800 Subject: [PATCH] objecter: LingerOp is refcounted this should fix Bug #2050, where a linger op was used after being freed. Signed-off-by: Yehuda Sadeh --- src/osdc/Objecter.cc | 6 +++++- src/osdc/Objecter.h | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index a05d460475c..dce0bf95b09 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -305,7 +305,7 @@ void Objecter::unregister_linger(uint64_t linger_id) LingerOp *info = iter->second; info->session_item.remove_myself(); linger_ops.erase(iter); - delete info; + info->put(); logger->set(l_osdc_linger_active, linger_ops.size()); } } @@ -616,6 +616,7 @@ void Objecter::C_Linger_Map_Latest::finish(int r) } objecter->unregister_linger(op->linger_id); } + op->put(); } void Objecter::op_check_for_latest_map(Op *op) @@ -627,6 +628,7 @@ void Objecter::op_check_for_latest_map(Op *op) void Objecter::linger_check_for_latest_map(LingerOp *op) { + op->get(); check_latest_map_lingers[op->linger_id] = op; monc->is_latest_map("osdmap", osdmap->get_epoch(), new C_Linger_Map_Latest(this, op->linger_id)); @@ -646,6 +648,8 @@ void Objecter::linger_cancel_map_check(LingerOp *op) map::iterator iter = check_latest_map_lingers.find(op->linger_id); if (iter != check_latest_map_lingers.end()) { + LingerOp *op = iter->second; + op->put(); check_latest_map_lingers.erase(iter); } } diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 92177ab813a..8a124f7d6c7 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -636,7 +636,7 @@ public: // -- lingering ops -- - struct LingerOp { + struct LingerOp : public RefCountedObject { uint64_t linger_id; object_t oid; object_locator_t oloc; @@ -665,12 +665,19 @@ public: // no copy! const LingerOp &operator=(const LingerOp& r); LingerOp(const LingerOp& o); + private: + ~LingerOp() {} }; struct C_Linger_Ack : public Context { Objecter *objecter; LingerOp *info; - C_Linger_Ack(Objecter *o, LingerOp *l) : objecter(o), info(l) {} + C_Linger_Ack(Objecter *o, LingerOp *l) : objecter(o), info(l) { + info->get(); + } + ~C_Linger_Ack() { + info->put(); + } void finish(int r) { objecter->_linger_ack(info, r); } @@ -679,7 +686,12 @@ public: struct C_Linger_Commit : public Context { Objecter *objecter; LingerOp *info; - C_Linger_Commit(Objecter *o, LingerOp *l) : objecter(o), info(l) {} + C_Linger_Commit(Objecter *o, LingerOp *l) : objecter(o), info(l) { + info->get(); + } + ~C_Linger_Commit() { + info->put(); + } void finish(int r) { objecter->_linger_commit(info, r); }