loff_t oldpos = opos;
opos = bh->end();
+ ls.splice(ls.end(), waitfor_read);
+ waitfor_read.clear();
+
if (r == -ENOENT) {
if (trust_enoent) {
ldout(cct, 10) << "bh_read_finish removing " << *bh << dendl;
for (map<loff_t, BufferHead*>::iterator bh_it = missing.begin();
bh_it != missing.end();
++bh_it) {
- bh_read(bh_it->second);
- if (success && onfinish) {
- ldout(cct, 10) << "readx missed, waiting on " << *bh_it->second
- << " off " << bh_it->first << dendl;
- bh_it->second->waitfor_read[bh_it->first].push_back( new C_RetryRead(this, rd, oset, onfinish) );
+ loff_t clean = get_stat_clean() + get_stat_rx() +
+ bh_it->second->length();
+ if (get_stat_rx() > 0 && static_cast<uint64_t>(clean) > max_size) {
+ // cache is full -- wait for rx's to complete
+ ldout(cct, 10) << "readx missed, waiting on cache to free "
+ << (clean - max_size) << " bytes" << dendl;
+ if (success) {
+ waitfor_read.push_back(new C_RetryRead(this, rd, oset, onfinish));
+ }
+ bh_remove(o, bh_it->second);
+ delete bh_it->second;
+ } else {
+ bh_read(bh_it->second);
+ if (success && onfinish) {
+ ldout(cct, 10) << "readx missed, waiting on " << *bh_it->second
+ << " off " << bh_it->first << dendl;
+ bh_it->second->waitfor_read[bh_it->first].push_back( new C_RetryRead(this, rd, oset, onfinish) );
+ }
+ bytes_not_in_cache += bh_it->second->length();
}
- bytes_not_in_cache += bh_it->second->length();
success = false;
}