RBD 导出一个image。
do_export(librbd::Image& image, const char *path)
>image.stat(info, sizeof(info))
>open(path, O_WRONLY | O_CREAT | O_EXCL, 0644)
>new AioExportContext(throttle, image, offset, length, fd)
>image.aio_read2(offset, length, m_bufferlist, m_aio_completion,op_flags)
>submit_aio_read(ictx, off, len, NULL, &bl, get_aio_completion(c), op_flags) //提交读取任务,同写入,分阻塞与非阻塞两种
>ictx->aio_work_queue->queue(new C_AioReadWQ(ictx, off, len, buf, pbl, c,op_flags)) //非阻塞读取方式
>librbd::aio_read(ictx, off, len, buf, pbl, c, op_flags) //阻塞读取方式
>aio_read(ictx, image_extents, buf, bl, c, op_flags)
>Striper::file_to_extents(cct, ictx->format_string, &ictx->layout,p->first, len, 0, object_extents, buffer_ofs) //把要读取image的部分,映射到对应不同对象的区间上去
>AioRead *req = new AioRead(ictx, q->oid.name, q->objectno, q->offset,q->length, q->buffer_extents, snap_id, true,req_comp, op_flags)
>ictx->aio_read_from_cache(q->oid, q->objectno, &req->data(),q->length, q->offset,cache_comp, op_flags) //rbd如果开启cache,从cache中读取
>req->send() //没有开启rbd cache
> op.sparse_read(m_object_off, m_object_len, &m_ext_map, &m_read_data,NULL) //把请求信息封装到ObjectOperation(Objecter)中
OR
>op.read(m_object_off, m_object_len, &m_read_data, NULL) //
>r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &op, flags, NULL)
>io_ctx_impl->aio_operate(obj, (::ObjectOperation*)o->impl, c->pc,io_ctx_impl->snapc, 0)
>objecter->mutate(oid, oloc, *o, snap_context, ut, flags, onack, oncommit,&c->objver)
>Op *o = prepare_mutate_op(oid, oloc, op, snapc, mtime, flags, onack, oncommit, objver) //构建Op
>op_submit(o)
>_op_submit_with_budget(op, lc, ctx_budget)
>int op_budget = _take_op_budget(op)
读取image的部分数据:
1.确定要读取image的区间范围(off,len)
2.将预读的区间映射到相应的对象上
3.将联系的操作(单个对象)和到一个Op中
4.Objecter层->massenger 发送请求到服务端。