- map_write函数分析
image.png
代码语言:javascript复制ObjectCacher::BufferHead *ObjectCacher::Object::map_write(ObjectExtent &ex,
ceph_tid_t tid)
{
if (oc->m_object_lock) {
assert(this->lock.is_wlocked());
}
BufferHead *final = 0;
ldout(oc->cct, 10) << "map_write oex " << ex.oid
<< " " << ex.offset << "~" << ex.length << dendl;
loff_t cur = ex.offset;
loff_t left = ex.length;
map<loff_t, BufferHead*>::const_iterator p = data_lower_bound(ex.offset);
while (left > 0) {
loff_t max = left;
// at end ?
if (p == data.end()) {
if (final == NULL) {
final = new BufferHead(this);
replace_journal_tid(final, tid);
final->set_start( cur );
final->set_length( max );
oc->bh_add(this, final);
ldout(oc->cct, 10) << "map_write adding trailing bh " << *final << dendl;
} else {
oc->bh_stat_sub(final);
final->set_length(final->length() max);
oc->bh_stat_add(final);
}
left -= max;
cur = max;
continue;
}
ldout(oc->cct, 10) << "cur is " << cur << ", p is " << *p->second << dendl;
//oc->verify_stats();
if (p->first <= cur) {
BufferHead *bh = p->second;
ldout(oc->cct, 10) << "map_write bh " << *bh << " intersected" << dendl;
if (p->first < cur) {
assert(final == 0);
if (cur max >= bh->end()) {
// we want right bit (one splice)
final = split(bh, cur); // just split it, take right half.
maybe_rebuild_buffer(bh);
replace_journal_tid(final, tid);
p;
assert(p->second == final);
} else {
// we want middle bit (two splices)
final = split(bh, cur);
maybe_rebuild_buffer(bh);
p;
assert(p->second == final);
auto right = split(final, cur max);
maybe_rebuild_buffer(right);
replace_journal_tid(final, tid);
}
} else {
assert(p->first == cur);
if (bh->length() <= max) {
// whole bufferhead, piece of cake.
} else {
// we want left bit (one splice)
auto right = split(bh, cur max); // just split
maybe_rebuild_buffer(right);
}
if (final) {
oc->mark_dirty(bh);
oc->mark_dirty(final);
--p; // move iterator back to final
assert(p->second == final);
replace_journal_tid(bh, tid);
merge_left(final, bh);
} else {
final = bh;
replace_journal_tid(final, tid);
}
}
// keep going.
loff_t lenfromcur = final->end() - cur;
cur = lenfromcur;
left -= lenfromcur;
p;
continue;
} else {
// gap!
loff_t next = p->first;
loff_t glen = MIN(next - cur, max);
ldout(oc->cct, 10) << "map_write gap " << cur << "~" << glen << dendl;
if (final) {
oc->bh_stat_sub(final);
final->set_length(final->length() glen);
oc->bh_stat_add(final);
} else {
final = new BufferHead(this);
replace_journal_tid(final, tid);
final->set_start( cur );
final->set_length( glen );
oc->bh_add(this, final);
}
cur = glen;
left -= glen;
continue; // more?
}
}
// set version
assert(final);
assert(final->get_journal_tid() == tid);
ldout(oc->cct, 10) << "map_write final is " << *final << dendl;
return final;
}