objecter: LingerOp is refcounted

this should fix Bug #2050, where a linger op was used after being freed.

Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
This commit is contained in:
Yehuda Sadeh 2012-02-10 14:45:27 -08:00
parent 631650b1d6
commit 6e6c34f9d6
2 changed files with 20 additions and 4 deletions

View File

@ -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<uint64_t, LingerOp*>::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);
}
}

View File

@ -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);
}