]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: fix the scrubber behavior on multiple preemption attempts 39145/head
authorRonen Friedman <rfriedma@redhat.com>
Thu, 28 Jan 2021 17:04:35 +0000 (19:04 +0200)
committerRonen Friedman <rfriedma@redhat.com>
Fri, 29 Jan 2021 09:51:32 +0000 (11:51 +0200)
Latest scrub code creates a time window in which a specific scrub
is marked as "preempted", but future preemptions are prohibited.
Write operations handled are then blocked but not restarted on time.

Fixes: https://tracker.ceph.com/issues/48793
Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
src/osd/pg_scrubber.cc

index 0eb513714e270799e0aaf80bc04f80fba2e1e769..526eff86c658fa32c7f3c4eeb7db5aacc42a38e5 100644 (file)
@@ -585,17 +585,21 @@ bool PgScrubber::write_blocked_by_scrub(const hobject_t& soid)
           << preemption_data.is_preemptable() << " already preempted? "
           << preemption_data.was_preempted() << dendl;
 
+  if (preemption_data.was_preempted()) {
+    // otherwise - write requests arriving while 'already preempted' is set
+    // but 'preemptable' is not - will not be allowed to continue, and will
+    // not be requeued on time.
+    return false;
+  }
+
   if (preemption_data.is_preemptable()) {
 
-    if (!preemption_data.was_preempted()) {
-      dout(10) << __func__ << " " << soid << " preempted" << dendl;
+    dout(10) << __func__ << " " << soid << " preempted" << dendl;
 
-      // signal the preemption
-      preemption_data.do_preempt();
+    // signal the preemption
+    preemption_data.do_preempt();
+    m_end = m_start;  // free the range we were scrubbing
 
-    } else {
-      dout(10) << __func__ << " " << soid << " already preempted" << dendl;
-    }
     return false;
   }
   return true;
@@ -616,6 +620,8 @@ bool PgScrubber::range_intersects_scrub(const hobject_t& start, const hobject_t&
  */
 void PgScrubber::add_delayed_scheduling()
 {
+  m_end = m_start; // not blocking any range now
+
   milliseconds sleep_time{0ms};
   if (m_needs_sleep) {
     double scrub_sleep = 1000.0 * m_osds->osd->scrub_sleep_time(m_flags.required);
@@ -1288,7 +1294,6 @@ void PgScrubber::map_from_replica(OpRequestRef op)
 
   if (m->preempted) {
     dout(10) << __func__ << " replica was preempted, setting flag" << dendl;
-    ceph_assert(preemption_data.is_preemptable());  // otherwise - how dare the replica!
     preemption_data.do_preempt();
   }