* - m_max_end
* - end
* - start
+ * returns:
+ * - std::nullopt if the range is blocked
+ * - otherwise, the number of objects in the selected range
*/
-bool PgScrubber::select_range()
+std::optional<uint64_t> PgScrubber::select_range()
{
m_be->new_chunk();
// we'll be requeued by whatever made us unavailable for scrub
dout(10) << __func__ << ": scrub blocked somewhere in range "
<< "[" << m_start << ", " << candidate_end << ")" << dendl;
- return false;
+ return std::nullopt;
}
m_end = candidate_end;
// debug: be 'blocked' if told so by the 'pg scrub_debug block' asok command
if (m_debug_blockrange > 0) {
m_debug_blockrange--;
- return false;
+ return std::nullopt;
}
- return true;
+ return objects.size();
}
void PgScrubber::select_range_n_notify()
// the next chunk to handle is not blocked
dout(20) << __func__ << ": selection OK" << dendl;
m_osds->queue_scrub_chunk_free(m_pg, Scrub::scrub_prio_t::low_priority);
-
} else {
// we will wait for the objects range to become available for scrubbing
dout(10) << __func__ << ": selected chunk is busy" << dendl;
}
}
+uint64_t PgScrubber::get_scrub_cost(uint64_t num_chunk_objects)
+{
+ const auto& conf = m_pg->get_cct()->_conf;
+ if (op_queue_type_t::WeightedPriorityQueue == m_osds->osd->osd_op_queue_type()) {
+ // if the osd_op_queue is WPQ, we will use the default osd_scrub_cost value
+ return conf->osd_scrub_cost;
+ }
+ uint64_t cost = 0;
+ double scrub_metadata_cost = m_osds->get_cost_per_io();
+ if (m_is_deep) {
+ auto pg_avg_object_size = m_pg->get_average_object_size();
+ cost = conf->osd_scrub_event_cost + (num_chunk_objects
+ * (scrub_metadata_cost + pg_avg_object_size));
+ dout(20) << fmt::format("{} : deep-scrub cost = {}", __func__, cost) << dendl;
+ return cost;
+ } else {
+ cost = conf->osd_scrub_event_cost + (num_chunk_objects * scrub_metadata_cost);
+ dout(20) << fmt::format("{} : shallow-scrub cost = {}", __func__, cost) << dendl;
+ return cost;
+ }
+}
+
bool PgScrubber::write_blocked_by_scrub(const hobject_t& soid)
{
if (soid < m_start || soid >= m_end) {
/// Returns epoch of current osdmap
epoch_t get_osdmap_epoch() const { return get_osdmap()->get_epoch(); }
+ uint64_t get_scrub_cost(uint64_t num_chunk_objects);
+
// collected statistics
int m_shallow_errors{0};
int m_deep_errors{0};
* - handling some head/clones issues
*
* The selected range is set directly into 'm_start' and 'm_end'
+ *
+ * Returns std::nullopt if the range is busy otherwise returns the
+ * number of objects in the range.
*/
- bool select_range();
+ std::optional<uint64_t> select_range();
std::list<Context*> m_callbacks;