]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
objectcacher: do callbacks _last_ to avoid a use-after-free
authorSage Weil <sage@newdream.net>
Wed, 26 Nov 2008 18:19:08 +0000 (10:19 -0800)
committerSage Weil <sage@newdream.net>
Wed, 26 Nov 2008 18:37:22 +0000 (10:37 -0800)
The callback may call back into release_set, so do not assume any pointers
will remain valid after the callback.

src/osdc/ObjectCacher.cc

index f9db7ef2fecadefe0f5006da0a2d69923ec4b7c5..f3aebeeb249ea96eb53c0680d2820b4b7baed2ff 100644 (file)
@@ -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<Context*> 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<Context*> 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<Context*> ls;
-      ls.splice(ls.begin(), ob->waitfor_commit[tid]);
-      ob->waitfor_commit.erase(tid);
-      finish_contexts(ls);
-    }
   }
 
   //  lock.Unlock();