From 308aecc9e35d4a86e042e1a9592ea116509d2b04 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 26 Nov 2008 10:19:08 -0800 Subject: [PATCH] objectcacher: do callbacks _last_ to avoid a use-after-free The callback may call back into release_set, so do not assume any pointers will remain valid after the callback. --- src/osdc/ObjectCacher.cc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index f9db7ef2fecad..f3aebeeb249ea 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -625,13 +625,6 @@ void ObjectCacher::bh_write_ack(object_t oid, loff_t start, size_t length, tid_t assert(ob->last_ack_tid < tid); ob->last_ack_tid = tid; - // is the entire object set now clean? - if (flush_set_callback && - dirty_tx_by_ino[ob->get_ino()] == 0) { - flush_set_callback(flush_set_callback_arg, ob->get_ino()); - dirty_tx_by_ino.erase(ob->get_ino()); - } - // waiters? if (ob->waitfor_ack.count(tid)) { list ls; @@ -639,6 +632,13 @@ void ObjectCacher::bh_write_ack(object_t oid, loff_t start, size_t length, tid_t ob->waitfor_ack.erase(tid); finish_contexts(ls); } + + // is the entire object set now clean? + if (flush_set_callback && + dirty_tx_by_ino[ob->get_ino()] == 0) { + flush_set_callback(flush_set_callback_arg, ob->get_ino()); + dirty_tx_by_ino.erase(ob->get_ino()); + } } //lock.Unlock(); } @@ -662,6 +662,14 @@ void ObjectCacher::bh_write_commit(object_t oid, loff_t start, size_t length, ti // update last_commit. ob->last_commit_tid = tid; + // waiters? + if (ob->waitfor_commit.count(tid)) { + list ls; + ls.splice(ls.begin(), ob->waitfor_commit[tid]); + ob->waitfor_commit.erase(tid); + finish_contexts(ls); + } + // is the entire object set now clean and fully committed? if (commit_set_callback && ob->last_commit_tid == ob->last_write_tid) { @@ -671,14 +679,6 @@ void ObjectCacher::bh_write_commit(object_t oid, loff_t start, size_t length, ti commit_set_callback(flush_set_callback_arg, ob->get_ino()); } } - - // waiters? - if (ob->waitfor_commit.count(tid)) { - list ls; - ls.splice(ls.begin(), ob->waitfor_commit[tid]); - ob->waitfor_commit.erase(tid); - finish_contexts(ls); - } } // lock.Unlock(); -- 2.39.5