]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: ignore info racing with PGRemove
authorSage Weil <sage@newdream.net>
Fri, 7 Aug 2009 22:34:24 +0000 (15:34 -0700)
committerSage Weil <sage@newdream.net>
Mon, 10 Aug 2009 20:14:31 +0000 (13:14 -0700)
We may get multiple infos during peering, because we explicitly
query priors AND osds with existing pg data send them (thus we
may get 2).

The second info can race with a PGRemove.  When we get it, we have
to realize it's not _new_ stray content.. it's old content we're
already purging.

src/TODO
src/osd/OSD.cc
src/osd/PG.cc
src/osd/PG.h

index 866b1feb359224de2dae90c2b779b03d88f6bfd0..bc9418a21fabf10e337b23dbef20a5d442b7a129 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -138,6 +138,7 @@ btrfs
 - ioctl to pull out data csum?
 
 osd
+- remove needs to be in a work queue!
 - what to do with lost objects.. continue peering?
 - segregate backlog from log ondisk?
 - preserve pg logs on disk for longer period
index fce332b6517ce8b5e86e71a619c2ba118b46e7cc..d4e65cd0ae50596fa54f28771c91628e87ecfd5d 100644 (file)
@@ -2934,9 +2934,13 @@ void OSD::handle_pg_notify(MOSDPGNotify *m)
     // stray?
     bool acting = pg->is_acting(from);
     if (!acting) {
-      dout(10) << *pg << " osd" << from << " has stray content: " << *it << dendl;
-      pg->stray_set.insert(from);
-      pg->state_clear(PG_STATE_CLEAN);
+      if (pg->stray_purged.count(from)) {
+       dout(10) << *pg << " osd" << from << " sent racing info " << *it << "; already purging/purged" << dendl;
+      } else {
+       dout(10) << *pg << " osd" << from << " has stray content: " << *it << dendl;
+       pg->stray_set.insert(from);
+       pg->state_clear(PG_STATE_CLEAN);
+      }
     }
 
     if (had) {
index 58bcd1357bd04400dd43f01a7cc310affacba6c3..e813da472a90f5d2f084019e6df3b76239cda616 100644 (file)
@@ -1005,6 +1005,7 @@ void PG::clear_primary_state()
   need_up_thru = false;
   peer_last_complete_ondisk.clear();
   min_last_complete_ondisk = eversion_t();
+  stray_purged.clear();
 
   finish_sync_event = 0;  // so that _finish_recvoery doesn't go off in another thread
 
@@ -1710,6 +1711,7 @@ void PG::purge_strays()
     if (osd->osdmap->is_up(*p)) {
       dout(10) << "sending PGRemove to osd" << *p << dendl;
       osd->queue_for_removal(*p, info.pgid);
+      stray_purged.insert(*p);
     } else {
       dout(10) << "not sending PGRemove to down osd" << *p << dendl;
     }
index 2566b40c70ba2232f697f6b468d3ef5162905125..8c01e2dd6ca5b233f7e3dfc5c2dca5078f1b657f 100644 (file)
@@ -699,6 +699,7 @@ public:
   map<int, Missing>    peer_missing;
   set<int>             peer_log_requested;  // logs i've requested (and start stamps)
   set<int>             peer_summary_requested;
+  set<int>             stray_purged;  // i deleted these strays; ignore racing PGInfo from them
   friend class OSD;