第一次写[0,4M],将4M数据保存到first_chunk中后即可返回,不涉及manifest等处理也不涉及写rados
HeadObjectProcessor::process(bufferlist&& data, uint64_t logical_offset) // data.length()=4M,logical_offset=0
flush = false,data_offset = 0, head_chunk_size = 4M, remaining = count = 4M,
data.splice(0, count, &head_data); // data的数据转移到head_data中,data被清空
data_offset += count; // data_offset = 4M
if (data_offset == head_chunk_size) process_first_chunk(std::move(head_data), &processor)
first_chunk = std::move(data); // head_data的数据转移到first_chunk,head_data被清空
*processor = &stripe; // chunk = ChunkProcessor(&writer, 4M); stripe = StripeProcessor(&chunk, this, 4M); 见AtomicObjectProcessor::prepare
第二次写数据[4M, 8M]
HeadObjectProcessor::process(bufferlist&& data, uint64_t logical_offset) // data.length()=4M,logical_offset=4M
flush = false, data_offset = 4M,
write_offset = data_offset // 4M
data_offset += data.length(); // 8M
processor->process(std::move(data), write_offset); // 调用 StripeProcessor::process(bufferlist&& data, uint64_t offset)
StripeProcessor::process(bufferlist&& data, uint64_t offset) // data为4M数据,offset=4M 既是从4M位置开始写data
flush = false,
// bounds=(0, 4M) 见 stripe = StripeProcessor(&chunk, this, 4M)
auto max = bounds.second - offset; // max=0
while(data.length() > max) {
// ChunkProcessor::process({}, 4M) -----> 0201
int r = Pipe::process({}, offset - bounds.first);
// -----> 0202 manifest处理 调用: ManifestObjectProcessor::next(4M, &stripe_size)
r = gen->next(offset, &stripe_size); // stripe_size = 4M
bounds.first = offset; // 4M
bounds.second = offset + stripe_size; // 8M
max = stripe_size; // 4M
}
// ChunkProcessor::process(4M, 0) -----> 0203
Pipe::process(std::move(data), offset - bounds.first);
------------------------------------------------------------- 0201
ChunkProcessor::process(bufferlist&& data, uint64_t offset) // ChunkProcessor::process({}, 4M)
uint64_t position = offset - chunk.length(); // 此时chunk为空,position = 4M,
flush = true
RadosWriter::process // 此时不需要处理直接返回
------------------------------------------------------------- 0202
int ManifestObjectProcessor::next(uint64_t offset, uint64_t *pstripe_size) // offset=4M
int r = manifest_gen.create_next(offset);
//RGWObjManifest::generator成员变量处理: ofs = max_head_size = 4M,cur_stripe = 1, cur_stripe_size = last_ofs = 4M,
//manifest成员变量处理: obj_size = 4M,end_iter.seek(4M);
// manifest->get_implicit_location(cur_part_id, cur_stripe, ofs, NULL, &cur_obj); //(0, 1, 4M, nullptr, cur_obj) ---> 020201
rgw_raw_obj stripe_obj = manifest_gen.get_cur_obj(store->getRados()); // cur_obj
r = store->getRados()->get_max_chunk_size(stripe_obj.pool, &chunk_size); // chunk_size = 4M
r = writer.set_stripe_obj(stripe_obj);
chunk = ChunkProcessor(&writer, chunk_size);
*pstripe_size = manifest_gen.cur_stripe_max_size(); // 4M
------------------------------------------------------------- 020201
RGWObjManifest::get_implicit_location(0, 1, 4M, nullptr, cur_obj) // cur_obj的名称等发生变化
oid += buf; // oid=prefix+00...001
ns = shadow_ns; // "shadow"
------------------------------------------------------------- 0203
ChunkProcessor::process(bufferlist&& data, uint64_t offset) // ChunkProcessor::process(4M, 0)
position = 4M, flush = false,
chunk.claim_append(data); // data中数据保存到chunk,清空data
while (chunk.length() >= chunk_size) { 4M >= 4M,循环一次
bufferlist bl;
chunk.splice(0, chunk_size, &bl); // chunk中数据保存到bl中,此时会清空chunk
// RadosWriter::process ---> op.write_full(data)
int r = Pipe::process(std::move(bl), position);
position += chunk_size; // 8M
}
第三次写数据[8M, 10M]
HeadObjectProcessor::process(bufferlist&& data, uint64_t logical_offset) // data.length()=2M,logical_offset=8M
flush = false, data_offset = 8M,
write_offset = data_offset // 8M
data_offset += data.length(); // 10M
processor->process(std::move(data), write_offset);
StripeProcessor::process(bufferlist&& data, uint64_t offset) // data为2M数据,offset=8M 既是从8M位置开始写data
flush = false,
// bounds=(4M, 8M)
auto max = bounds.second - offset; // max=0
while(data.length() > max) {
// ChunkProcessor::process({}, 4M)
int r = Pipe::process({}, offset - bounds.first);
// 生成一个新的manifest
r = gen->next(offset, &stripe_size); // stripe_size = 4M
bounds.first = offset; // 8M
bounds.second = offset + stripe_size; // 12M
max = stripe_size; // 4M
}
// ChunkProcessor::process(2M, 0) 由于本次只写2M数据,小于chunk_size=4M,所以本次不会写rados,数据暂时保存在chunk中
Pipe::process(std::move(data), offset - bounds.first);
RGWPutObj::execute中写数据的do...while结束,但是需要刷chunk的数据,操作如下
HeadObjectProcessor::process(bufferlist&& data, uint64_t logical_offset)
StripeProcessor::process({}, 10M)
ChunkProcessor::process({}, 2M) // flush=true, chunk.length()=2M
RadosWriter::process(2M, 0)
op.write_full(data);
截至到目前,除了first_chunk=[0,4M]的数据没有生成manifest以及写rados,其余部分均写入rados以及生成相应的manifest。
关于 first_chunk 的处理会在complete的时候梳理
AtomicObjectProcessor 10M对象的处理过程
最新推荐文章于 2022-08-06 15:11:00 发布