]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: fix dirty_info check for advance/activate paths
authorSage Weil <sage.weil@dreamhost.com>
Sun, 29 Apr 2012 03:57:02 +0000 (20:57 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Sun, 29 Apr 2012 03:57:02 +0000 (20:57 -0700)
Previously we would check and write dirty_info *without the pg lock* after
doing the advance and activate map calls.  This was unlikely to race with
anything because the queues were drained, but definitely not right.

Instead, do the write in activate_map, or explicitly if activate_map is
not called (so that we record our progress after handling maps when we are
not up).

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
src/osd/OSD.cc

index 203ac047ddfe7758f75f36c60be08d87ece01f75..93e8d19e37ae8a39fb14e77258e797331edab3dc 100644 (file)
@@ -3284,6 +3284,17 @@ void OSD::handle_osd_map(MOSDMap *m)
       
     // yay!
     activate_map(t, fin->contexts);
+  } else {
+    // write updated pg state to store
+    for (hash_map<pg_t,PG*>::iterator i = pg_map.begin();
+        i != pg_map.end();
+        i++) {
+      PG *pg = i->second;
+      pg->lock_with_map_lock_held();
+      if (pg->dirty_info)
+       pg->write_info(t);
+      pg->unlock();
+    }
   }
 
   bool do_shutdown = false;
@@ -3338,15 +3349,6 @@ void OSD::handle_osd_map(MOSDMap *m)
   // process waiters
   take_waiters(waiting_for_osdmap);
 
-  // write updated pg state to store
-  for (hash_map<pg_t,PG*>::iterator i = pg_map.begin();
-       i != pg_map.end();
-       i++) {
-    PG *pg = i->second;
-    if (pg->dirty_info)
-      pg->write_info(t);
-  }
-
   // note in the superblock that we were clean thru the prior epoch
   if (boot_epoch && boot_epoch >= superblock.mounted) {
     superblock.mounted = boot_epoch;
@@ -3606,6 +3608,9 @@ void OSD::activate_map(ObjectStore::Transaction& t, list<Context*>& tfin)
 
     PG::RecoveryCtx rctx(&query_map, &info_map, &notify_list, &tfin, &t);
     pg->handle_activate_map(&rctx);
+
+    if (pg->dirty_info)
+      pg->write_info(t);
     
     pg->unlock();
   }