From: Jason Dillaman Date: Thu, 13 Aug 2015 00:51:05 +0000 (-0400) Subject: cls_rbd: add async version of object_map_load X-Git-Tag: v10.0.2~193^2~25 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6326d0756a4969bbde1dee92d4560f87210e617c;p=ceph.git cls_rbd: add async version of object_map_load Most librbd object map interactions are moving to async state machines. The sync version must remain until the librbd image refresh operation is converted to a state machine due to the sheer volume of locks held blocking the AIO thread. Signed-off-by: Jason Dillaman --- diff --git a/src/cls/rbd/cls_rbd_client.cc b/src/cls/rbd/cls_rbd_client.cc index e4a7500aa6ad..31a31a445b13 100644 --- a/src/cls/rbd/cls_rbd_client.cc +++ b/src/cls/rbd/cls_rbd_client.cc @@ -17,6 +17,11 @@ namespace librbd { namespace { +void rados_callback(rados_completion_t c, void *arg) { + Context *ctx = reinterpret_cast(arg); + ctx->complete(rados_aio_get_return_value(c)); +} + struct C_GetChildren : public Context { librados::IoCtx *ioctx; std::string oid; @@ -59,13 +64,46 @@ struct C_GetChildren : public Context { } on_finish->complete(r); } +}; + +struct C_ObjectMapLoad : public Context { + librados::IoCtx *ioctx; + std::string oid; + ceph::BitVector<2> *object_map; + Context *on_finish; + bufferlist out_bl; + + C_ObjectMapLoad(librados::IoCtx *_ioctx, const std::string &_oid, + ceph::BitVector<2> *_object_map, Context *_on_finish) + : ioctx(_ioctx), oid(_oid), object_map(_object_map), on_finish(_on_finish) { + } + + void send() { + bufferlist in_bl; + librados::ObjectReadOperation op; + op.exec("rbd", "object_map_load", in_bl); + + librados::AioCompletion *rados_completion = + librados::Rados::aio_create_completion(this, rados_callback, NULL); + int r = ioctx->aio_operate(oid, rados_completion, &op, &out_bl); + assert(r == 0); + rados_completion->release(); + } - static void rados_callback(rados_completion_t c, void *arg) { - Context *ctx = reinterpret_cast(arg); - ctx->complete(rados_aio_get_return_value(c)); + virtual void finish(int r) { + if (r == 0) { + try { + bufferlist::iterator it = out_bl.begin(); + ::decode(*object_map, it); + } catch (const buffer::error &err) { + r = -EBADMSG; + } + } + on_finish->complete(r); } }; + } // anonymous namespace int get_immutable_metadata(librados::IoCtx *ioctx, const std::string &oid, @@ -783,6 +821,7 @@ struct C_GetChildren : public Context { int object_map_load(librados::IoCtx *ioctx, const std::string &oid, ceph::BitVector<2> *object_map) { + // TODO eliminate sync version bufferlist in; bufferlist out; int r = ioctx->exec(oid, "rbd", "object_map_load", in, out); @@ -799,6 +838,14 @@ struct C_GetChildren : public Context { return 0; } + void object_map_load(librados::IoCtx *ioctx, const std::string &oid, + ceph::BitVector<2> *object_map, Context *on_finish) + { + C_ObjectMapLoad *req = new C_ObjectMapLoad(ioctx, oid, object_map, + on_finish); + req->send(); + } + void object_map_save(librados::ObjectWriteOperation *rados_op, const ceph::BitVector<2> &object_map) { diff --git a/src/cls/rbd/cls_rbd_client.h b/src/cls/rbd/cls_rbd_client.h index 660875c08d87..98bd1cfcb1f4 100644 --- a/src/cls/rbd/cls_rbd_client.h +++ b/src/cls/rbd/cls_rbd_client.h @@ -129,6 +129,8 @@ namespace librbd { // operations on the rbd_object_map.$image_id object int object_map_load(librados::IoCtx *ioctx, const std::string &oid, ceph::BitVector<2> *object_map); + void object_map_load(librados::IoCtx *ioctx, const std::string &oid, + ceph::BitVector<2> *object_map, Context *on_finish); void object_map_save(librados::ObjectWriteOperation *rados_op, const ceph::BitVector<2> &object_map); void object_map_resize(librados::ObjectWriteOperation *rados_op,