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 發送請求到服務端。