The sched_scrub() method can be called by various code path, such as
OSD::tick() or triggered by a scrub_reserve_reply message.
The sched_scrub() will check whether or not the noscrub is globally set or
set for a specified pool before really starting to schedule a scrub job.
However, if we set noscrub flag for a specified pool, there are other pools
for which scrub are still legal and thus shall be granted.
The problem here is that we may stopping a pg's scrub in an intermidate stage
due to setting of the corresponding pool's noscrub flag whithout releasing
the reservation. Which as a result shall prevent other pgs of a different
pool from going scrubbing because we have already hit the reservation limit.
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
//NOSCRUB so skip regular scrubs
if ((osd->osd->get_osdmap()->test_flag(CEPH_OSDMAP_NOSCRUB) ||
- pool.info.has_flag(pg_pool_t::FLAG_NOSCRUB)) && !time_for_deep)
+ pool.info.has_flag(pg_pool_t::FLAG_NOSCRUB)) && !time_for_deep) {
+ if (scrubber.reserved) {
+ // cancel scrub if it is still in scheduling,
+ // so pgs from other pools where scrub are still legal
+ // have a chance to go ahead with scrubbing.
+ clear_scrub_reserved();
+ scrub_unreserve_replicas();
+ }
return false;
+ }
}
if (cct->_conf->osd_scrub_auto_repair