]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: fix scrub reschedule bug 41971/head
authorwanwencong <wanwc@chinatelecom.cn>
Thu, 25 Feb 2021 09:07:41 +0000 (17:07 +0800)
committerMykola Golub <mgolub@suse.com>
Tue, 22 Jun 2021 10:56:37 +0000 (13:56 +0300)
not all element can be visited during reschedule traverse

Fixes: https://tracker.ceph.com/issues/49487
Signed-off-by: wencong wan <wanwc@chinatelecom.cn>
(cherry picked from commit d7561a6e58fc8043b77648a2cdd5d12bb637f92b)

src/osd/OSD.cc
src/osd/OSD.h

index bd726f627a8c6a631f8afcbb97c99bc390c60e16..f580fb6f5645280c7357ade9585e2e64677f1340 100644 (file)
@@ -7660,20 +7660,26 @@ void OSD::sched_scrub()
 void OSD::resched_all_scrubs()
 {
   dout(10) << __func__ << ": start" << dendl;
-  OSDService::ScrubJob scrub_job;
-  if (service.first_scrub_stamp(&scrub_job)) {
-    do {
-      dout(20) << __func__ << ": examine " << scrub_job.pgid << dendl;
-
-      PGRef pg = _lookup_lock_pg(scrub_job.pgid);
+  const vector<spg_t> pgs = [this] {
+    vector<spg_t> pgs;
+    OSDService::ScrubJob job;
+    if (service.first_scrub_stamp(&job)) {
+      do {
+        pgs.push_back(job.pgid);
+      } while (service.next_scrub_stamp(job, &job));
+    }
+    return pgs;
+  }();
+  for (auto& pgid : pgs) {
+      dout(20) << __func__ << ": examine " << pgid << dendl;
+      PGRef pg = _lookup_lock_pg(pgid);
       if (!pg)
        continue;
       if (!pg->m_planned_scrub.must_scrub && !pg->m_planned_scrub.need_auto) {
-        dout(15) << __func__ << ": reschedule " << scrub_job.pgid << dendl;
+        dout(15) << __func__ << ": reschedule " << pgid << dendl;
         pg->on_info_history_change();
       }
       pg->unlock();
-    } while (service.next_scrub_stamp(scrub_job, &scrub_job));
   }
   dout(10) << __func__ << ": done" << dendl;
 }
index f55658c3bb167532a759f9675d05e9bdcbb886e3..ed1fbcff1d4b9bcf41f3683a76e325b26962731b 100644 (file)
@@ -319,10 +319,7 @@ public:
     std::lock_guard l(sched_scrub_lock);
     if (sched_scrub_pg.empty())
       return false;
-    std::set<ScrubJob>::const_iterator iter = sched_scrub_pg.lower_bound(next);
-    if (iter == sched_scrub_pg.cend())
-      return false;
-    ++iter;
+    std::set<ScrubJob>::const_iterator iter = sched_scrub_pg.upper_bound(next);
     if (iter == sched_scrub_pg.cend())
       return false;
     *out = *iter;