<< dendl;
C_AioRead<I> *req_comp = new C_AioRead<I>(aio_comp);
- AioObjectRead<I> *req = new AioObjectRead<I>(get_image_ctx(&image_ctx),
- extent.oid.name,
- extent.objectno,
- extent.offset,
- extent.length,
- extent.buffer_extents,
- snap_id, true, req_comp,
- m_op_flags);
+ AioObjectRead<I> *req = AioObjectRead<I>::create(
+ &image_ctx, extent.oid.name, extent.objectno, extent.offset,
+ extent.length, extent.buffer_extents, snap_id, true, req_comp,
+ m_op_flags);
req_comp->set_req(req);
if (image_ctx.object_cacher) {
ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
<< " from " << p->buffer_extents << dendl;
C_AioRequest *req_comp = new C_AioRequest(aio_comp);
- AioObjectRequest<> *request = create_object_request(*p, snapc, req_comp);
+ AioObjectRequestHandle *request = create_object_request(*p, snapc,
+ req_comp);
// if journaling, stash the request for later; otherwise send
if (request != NULL) {
}
template <typename I>
-AioObjectRequest<> *AioImageWrite<I>::create_object_request(
+AioObjectRequestHandle *AioImageWrite<I>::create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) {
I &image_ctx = this->m_image_ctx;
bufferlist bl;
assemble_extent(object_extent, &bl);
- AioObjectWrite *req = new AioObjectWrite(get_image_ctx(&image_ctx),
- object_extent.oid.name,
- object_extent.objectno,
- object_extent.offset, bl,
- snapc, on_finish);
- req->set_op_flags(m_op_flags);
+ AioObjectRequest<I> *req = AioObjectRequest<I>::create_write(
+ &image_ctx, object_extent.oid.name, object_extent.objectno,
+ object_extent.offset, bl, snapc, on_finish, m_op_flags);
return req;
}
}
template <typename I>
-AioObjectRequest<> *AioImageDiscard<I>::create_object_request(
+AioObjectRequestHandle *AioImageDiscard<I>::create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) {
I &image_ctx = this->m_image_ctx;
- AioObjectRequest<> *req;
+ AioObjectRequest<I> *req;
if (object_extent.length == image_ctx.layout.object_size) {
- req = new AioObjectRemove(get_image_ctx(&image_ctx),
- object_extent.oid.name,
- object_extent.objectno, snapc, on_finish);
+ req = AioObjectRequest<I>::create_remove(
+ &image_ctx, object_extent.oid.name, object_extent.objectno, snapc,
+ on_finish);
} else if (object_extent.offset + object_extent.length ==
image_ctx.layout.object_size) {
- req = new AioObjectTruncate(get_image_ctx(&image_ctx),
- object_extent.oid.name,
- object_extent.objectno, object_extent.offset,
- snapc, on_finish);
+ req = AioObjectRequest<I>::create_truncate(
+ &image_ctx, object_extent.oid.name, object_extent.objectno,
+ object_extent.offset, snapc, on_finish);
} else {
- req = new AioObjectZero(get_image_ctx(&image_ctx),
- object_extent.oid.name,
- object_extent.objectno, object_extent.offset,
- object_extent.length, snapc, on_finish);
+ req = AioObjectRequest<I>::create_zero(
+ &image_ctx, object_extent.oid.name, object_extent.objectno,
+ object_extent.offset, object_extent.length, snapc, on_finish);
}
return req;
}
namespace librbd {
class AioCompletion;
-template <typename I> class AioObjectRequest;
+class AioObjectRequestHandle;
class ImageCtx;
template <typename ImageCtxT = ImageCtx>
void fail(int r);
protected:
- typedef std::list<AioObjectRequest<ImageCtx> *> AioObjectRequests;
+ typedef std::list<AioObjectRequestHandle *> AioObjectRequests;
ImageCtxT &m_image_ctx;
AioCompletion *m_aio_comp;
virtual void send_object_requests(const ObjectExtents &object_extents,
const ::SnapContext &snapc,
AioObjectRequests *aio_object_requests);
- virtual AioObjectRequest<ImageCtx> *create_object_request(
+ virtual AioObjectRequestHandle *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) = 0;
virtual void send_object_requests(const ObjectExtents &object_extents,
const ::SnapContext &snapc,
AioObjectRequests *aio_object_requests);
- virtual AioObjectRequest<ImageCtx> *create_object_request(
+ virtual AioObjectRequestHandle *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish);
virtual void send_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid);
- virtual AioObjectRequest<ImageCtx> *create_object_request(
+ virtual AioObjectRequestHandle *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish);
namespace librbd {
+template <typename I>
+AioObjectRequest<I>*
+AioObjectRequest<I>::create_remove(I *ictx, const std::string &oid,
+ uint64_t object_no,
+ const ::SnapContext &snapc,
+ Context *completion) {
+ return new AioObjectRemove(util::get_image_ctx(ictx), oid, object_no, snapc,
+ completion);
+}
+
+template <typename I>
+AioObjectRequest<I>*
+AioObjectRequest<I>::create_truncate(I *ictx, const std::string &oid,
+ uint64_t object_no, uint64_t object_off,
+ const ::SnapContext &snapc,
+ Context *completion) {
+ return new AioObjectTruncate(util::get_image_ctx(ictx), oid, object_no,
+ object_off, snapc, completion);
+}
+
+template <typename I>
+AioObjectRequest<I>*
+AioObjectRequest<I>::create_write(I *ictx, const std::string &oid,
+ uint64_t object_no, uint64_t object_off,
+ const ceph::bufferlist &data,
+ const ::SnapContext &snapc,
+ Context *completion, int op_flags) {
+ return new AioObjectWrite(util::get_image_ctx(ictx), oid, object_no,
+ object_off, data, snapc, completion, op_flags);
+}
+
+template <typename I>
+AioObjectRequest<I>*
+AioObjectRequest<I>::create_zero(I *ictx, const std::string &oid,
+ uint64_t object_no, uint64_t object_off,
+ uint64_t object_len,
+ const ::SnapContext &snapc,
+ Context *completion) {
+ return new AioObjectZero(util::get_image_ctx(ictx), oid, object_no,
+ object_off, object_len, snapc, completion);
+}
+
template <typename I>
AioObjectRequest<I>::AioObjectRequest(ImageCtx *ictx, const std::string &oid,
uint64_t objectno, uint64_t off,
/** read **/
template <typename I>
-AioObjectRead<I>::AioObjectRead(ImageCtx *ictx, const std::string &oid,
+AioObjectRead<I>::AioObjectRead(I *ictx, const std::string &oid,
uint64_t objectno, uint64_t offset,
uint64_t len,
vector<pair<uint64_t,uint64_t> >& be,
librados::snap_t snap_id, bool sparse,
Context *completion, int op_flags)
- : AioObjectRequest<I>(ictx, oid, objectno, offset, len, snap_id, completion,
- false),
+ : AioObjectRequest<I>(util::get_image_ctx(ictx), oid, objectno, offset, len,
+ snap_id, completion, false),
m_buffer_extents(be), m_tried_parent(false), m_sparse(sparse),
m_op_flags(op_flags), m_parent_completion(NULL),
m_state(LIBRBD_AIO_READ_FLAT) {
namespace librbd {
struct AioCompletion;
+class AioObjectRemove;
+class AioObjectTruncate;
+class AioObjectWrite;
+class AioObjectZero;
struct ImageCtx;
class CopyupRequest;
+struct AioObjectRequestHandle {
+ virtual ~AioObjectRequestHandle() {
+ }
+
+ virtual void complete(int r) = 0;
+ virtual void send() = 0;
+};
+
/**
* This class represents an I/O operation to a single RBD data object.
* Its subclasses encapsulate logic for dealing with special cases
* for I/O due to layering.
*/
template <typename ImageCtxT = ImageCtx>
-class AioObjectRequest {
+class AioObjectRequest : public AioObjectRequestHandle {
public:
+ typedef std::vector<std::pair<uint64_t, uint64_t> > Extents;
+
+ static AioObjectRequest* create_remove(ImageCtxT *ictx,
+ const std::string &oid,
+ uint64_t object_no,
+ const ::SnapContext &snapc,
+ Context *completion);
+ static AioObjectRequest* create_truncate(ImageCtxT *ictx,
+ const std::string &oid,
+ uint64_t object_no,
+ uint64_t object_off,
+ const ::SnapContext &snapc,
+ Context *completion);
+ static AioObjectRequest* create_write(ImageCtxT *ictx, const std::string &oid,
+ uint64_t object_no,
+ uint64_t object_off,
+ const ceph::bufferlist &data,
+ const ::SnapContext &snapc,
+ Context *completion, int op_flags);
+ static AioObjectRequest* create_zero(ImageCtxT *ictx, const std::string &oid,
+ uint64_t object_no, uint64_t object_off,
+ uint64_t object_len,
+ const ::SnapContext &snapc,
+ Context *completion);
+
AioObjectRequest(ImageCtx *ictx, const std::string &oid,
uint64_t objectno, uint64_t off, uint64_t len,
librados::snap_t snap_id,
uint64_t m_object_no, m_object_off, m_object_len;
librados::snap_t m_snap_id;
Context *m_completion;
- std::vector<std::pair<uint64_t,uint64_t> > m_parent_extents;
+ Extents m_parent_extents;
bool m_hide_enoent;
};
typedef std::vector<std::pair<uint64_t, uint64_t> > Extents;
typedef std::map<uint64_t, uint64_t> ExtentMap;
- AioObjectRead(ImageCtx *ictx, const std::string &oid,
+ static AioObjectRead* create(ImageCtxT *ictx, const std::string &oid,
+ uint64_t objectno, uint64_t offset,
+ uint64_t len, Extents &buffer_extents,
+ librados::snap_t snap_id, bool sparse,
+ Context *completion, int op_flags) {
+ return new AioObjectRead(ictx, oid, objectno, offset, len, buffer_extents,
+ snap_id, sparse, completion, op_flags);
+ }
+
+ AioObjectRead(ImageCtxT *ictx, const std::string &oid,
uint64_t objectno, uint64_t offset, uint64_t len,
Extents& buffer_extents, librados::snap_t snap_id, bool sparse,
Context *completion, int op_flags);
public:
AioObjectWrite(ImageCtx *ictx, const std::string &oid, uint64_t object_no,
uint64_t object_off, const ceph::bufferlist &data,
- const ::SnapContext &snapc, Context *completion)
+ const ::SnapContext &snapc, Context *completion,
+ int op_flags)
: AbstractAioObjectWrite(ictx, oid, object_no, object_off, data.length(),
snapc, completion, false),
- m_write_data(data), m_op_flags(0) {
+ m_write_data(data), m_op_flags(op_flags) {
}
- void set_op_flags(int op_flags) {
- m_op_flags = op_flags;
- }
protected:
virtual void add_write_ops(librados::ObjectWriteOperation *wr);
namespace librbd {
-template <typename I> class AioObjectRequest;
+struct AioObjectRequestHandle;
class ImageCtx;
namespace journal { template <typename> class Replay; }
static const std::string LOCAL_MIRROR_UUID;
static const std::string ORPHAN_MIRROR_UUID;
- typedef std::list<AioObjectRequest<ImageCtx> *> AioObjectRequests;
+ typedef std::list<AioObjectRequestHandle *> AioObjectRequests;
Journal(ImageCtxT &image_ctx);
~Journal();
request_sent = true;
AioObjectWrite *req = new AioObjectWrite(image_ctx, oid, object_no, off,
- bl, snapc, this);
+ bl, snapc, this, 0);
req->send();
}
};
journal_tid));
} else {
AioObjectWrite *req = new AioObjectWrite(m_ictx, oid.name, object_no,
- off, bl, snapc, req_comp);
+ off, bl, snapc, req_comp, 0);
req->send();
}
return ++m_tid;
bufferlist bl;
string oid = image_ctx.get_object_name(m_object_no);
AioObjectWrite *req = new AioObjectWrite(&image_ctx, oid, m_object_no, 0,
- bl, m_snapc, this);
+ bl, m_snapc, this, 0);
if (!req->has_parent()) {
// stop early if the parent went away - it just means
// another flatten finished first or the image was resized
namespace librbd {
-template <typename I> struct AioObjectRequest;
+struct AioObjectRequestHandle;
struct ImageCtx;
struct MockJournal {
- typedef std::list<AioObjectRequest<ImageCtx> *> AioObjectRequests;
+ typedef std::list<AioObjectRequestHandle *> AioObjectRequests;
static MockJournal *s_instance;
static MockJournal *get_instance() {