CEPH_OSD_OP_FLAG_FADVISE_DONTNEED = 0x20,/* data will not be accessed in the near future */
CEPH_OSD_OP_FLAG_FADVISE_NOCACHE = 0x40, /* data will be accessed only once by this client */
CEPH_OSD_OP_FLAG_WITH_REFERENCE = 0x80, /* need reference couting */
+ CEPH_OSD_OP_FLAG_BYPASS_CLEAN_CACHE = 0x100, /* bypass ObjectStore cache, mainly for deep-scrub */
};
#define EOLDSNAPC 85 /* ORDERSNAP flag set; writer has old snapc*/
uint32_t offset,
uint32_t length,
BlueStore::ready_regions_t& res,
- interval_set<uint32_t>& res_intervals)
+ interval_set<uint32_t>& res_intervals,
+ int flags)
{
res.clear();
res_intervals.clear();
++i) {
Buffer *b = i->second.get();
ceph_assert(b->end() > offset);
- if (b->is_writing() || b->is_clean()) {
+
+ bool val = false;
+ if (flags & BYPASS_CLEAN_CACHE)
+ val = b->is_writing();
+ else
+ val = b->is_writing() || b->is_clean();
+ if (val) {
if (b->offset < offset) {
uint32_t skip = offset - b->offset;
uint32_t l = min(length, b->length - skip);
{
FUNCTRACE(cct);
int r = 0;
+ int read_cache_policy = 0; // do not bypass clean or dirty cache
dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
<< " size 0x" << o->onode.size << " (" << std::dec
ready_regions_t ready_regions;
+ // for deep-scrub, we only read dirty cache and bypass clean cache in
+ // order to read underlying block device in case there are silent disk errors.
+ if (op_flags & CEPH_OSD_OP_FLAG_BYPASS_CLEAN_CACHE) {
+ dout(20) << __func__ << " will bypass cache and do direct read" << dendl;
+ read_cache_policy = BufferSpace::BYPASS_CLEAN_CACHE;
+ }
+
// build blob-wise list to of stuff read (that isn't cached)
blobs2read_t blobs2read;
unsigned left = length;
ready_regions_t cache_res;
interval_set<uint32_t> cache_interval;
bptr->shared_blob->bc.read(
- bptr->shared_blob->get_cache(), b_off, b_len, cache_res, cache_interval);
+ bptr->shared_blob->get_cache(), b_off, b_len, cache_res, cache_interval,
+ read_cache_policy);
dout(20) << __func__ << " blob " << *bptr << std::hex
<< " need 0x" << b_off << "~" << b_len
<< " cache has 0x" << cache_interval
/// map logical extent range (object) onto buffers
struct BufferSpace {
+ enum {
+ BYPASS_CLEAN_CACHE = 0x1, // bypass clean cache
+ };
+
typedef boost::intrusive::list<
Buffer,
boost::intrusive::member_hook<
void read(Cache* cache, uint32_t offset, uint32_t length,
BlueStore::ready_regions_t& res,
- interval_set<uint32_t>& res_intervals);
+ interval_set<uint32_t>& res_intervals,
+ int flags = 0);
void truncate(Cache* cache, uint32_t offset) {
discard(cache, offset, (uint32_t)-1 - offset);