From: wangzhengyong Date: Mon, 12 Jun 2017 13:16:14 +0000 (+0800) Subject: librbd: handle compare_and_write imagerequest in ImageRequestWQ X-Git-Tag: v12.1.2~106^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ead121bf9eee65c85a3fdef698c46395f183111e;p=ceph.git librbd: handle compare_and_write imagerequest in ImageRequestWQ Signed-off-by: Zhengyong Wang --- diff --git a/src/librbd/io/ImageRequest.cc b/src/librbd/io/ImageRequest.cc index 86ea5536addd..434c208eefd1 100644 --- a/src/librbd/io/ImageRequest.cc +++ b/src/librbd/io/ImageRequest.cc @@ -150,6 +150,18 @@ ImageRequest* ImageRequest::create_writesame_request( std::move(bl), op_flags, parent_trace); } +template +ImageRequest* ImageRequest::create_compare_and_write_request( + I &image_ctx, AioCompletion *c, Extents &&image_extents, + bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset, + int op_flags, const ZTracer::Trace &parent_trace) { + return new ImageCompareAndWriteRequest(image_ctx, c, + std::move(image_extents), + std::move(cmp_bl), + std::move(bl), mismatch_offset, + op_flags, parent_trace); +} + template void ImageRequest::aio_read(I *ictx, AioCompletion *c, Extents &&image_extents, diff --git a/src/librbd/io/ImageRequest.h b/src/librbd/io/ImageRequest.h index 93538f6e3e72..9d707a3f8f5f 100644 --- a/src/librbd/io/ImageRequest.h +++ b/src/librbd/io/ImageRequest.h @@ -57,6 +57,10 @@ public: uint64_t off, uint64_t len, bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace); + static ImageRequest* create_compare_and_write_request( + ImageCtxT &image_ctx, AioCompletion *c, Extents &&image_extents, + bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset, + int op_flags, const ZTracer::Trace &parent_trace); static void aio_read(ImageCtxT *ictx, AioCompletion *c, Extents &&image_extents, ReadResult &&read_result, diff --git a/src/librbd/io/ImageRequestWQ.cc b/src/librbd/io/ImageRequestWQ.cc index e80e90088d2a..4cc8e0148dd1 100644 --- a/src/librbd/io/ImageRequestWQ.cc +++ b/src/librbd/io/ImageRequestWQ.cc @@ -163,6 +163,37 @@ ssize_t ImageRequestWQ::writesame(uint64_t off, uint64_t len, return len; } +template +ssize_t ImageRequestWQ::compare_and_write(uint64_t off, uint64_t len, + bufferlist &&cmp_bl, + bufferlist &&bl, + uint64_t *mismatch_off, + int op_flags){ + CephContext *cct = m_image_ctx.cct; + ldout(cct, 20) << "compare_and_write ictx=" << &m_image_ctx << ", off=" + << off << ", " << "len = " << len << dendl; + + m_image_ctx.snap_lock.get_read(); + int r = clip_io(util::get_image_ctx(&m_image_ctx), off, &len); + m_image_ctx.snap_lock.put_read(); + if (r < 0) { + lderr(cct) << "invalid IO request: " << cpp_strerror(r) << dendl; + return r; + } + + C_SaferCond cond; + AioCompletion *c = AioCompletion::create(&cond); + aio_compare_and_write(c, off, len, std::move(cmp_bl), std::move(bl), + mismatch_off, op_flags, false); + + r = cond.wait(); + if (r < 0) { + return r; + } + + return len; +} + template void ImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len, ReadResult &&read_result, int op_flags, @@ -347,6 +378,48 @@ void ImageRequestWQ::aio_writesame(AioCompletion *c, uint64_t off, trace.event("finish"); } +template +void ImageRequestWQ::aio_compare_and_write(AioCompletion *c, + uint64_t off, uint64_t len, + bufferlist &&cmp_bl, + bufferlist &&bl, + uint64_t *mismatch_off, + int op_flags, bool native_async) { + CephContext *cct = m_image_ctx.cct; + ZTracer::Trace trace; + if (cct->_conf->rbd_blkin_trace_all) { + trace.init("wq: compare_and_write", &m_image_ctx.trace_endpoint); + trace.event("init"); + } + + c->init_time(util::get_image_ctx(&m_image_ctx), AIO_TYPE_COMPARE_AND_WRITE); + ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " + << "completion=" << c << ", off=" << off << ", " + << "len=" << len << dendl; + + if (native_async && m_image_ctx.event_socket.is_valid()) { + c->set_event_notify(true); + } + + if (!start_in_flight_io(c)) { + return; + } + + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + if (m_image_ctx.non_blocking_aio || writes_blocked()) { + queue(ImageRequest::create_compare_and_write_request( + m_image_ctx, c, {{off, len}}, std::move(cmp_bl), std::move(bl), + mismatch_off, op_flags, trace)); + } else { + c->start_op(); + ImageRequest::aio_compare_and_write(&m_image_ctx, c, {{off, len}}, + std::move(cmp_bl), std::move(bl), + mismatch_off, op_flags, trace); + finish_in_flight_io(); + } + trace.event("finish"); +} + template void ImageRequestWQ::shut_down(Context *on_shutdown) { assert(m_image_ctx.owner_lock.is_locked()); diff --git a/src/librbd/io/ImageRequestWQ.h b/src/librbd/io/ImageRequestWQ.h index 64f1790f7527..ad51b0f2c9f6 100644 --- a/src/librbd/io/ImageRequestWQ.h +++ b/src/librbd/io/ImageRequestWQ.h @@ -34,6 +34,9 @@ public: ssize_t write(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags); ssize_t discard(uint64_t off, uint64_t len, bool skip_partial_discard); ssize_t writesame(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags); + ssize_t compare_and_write(uint64_t off, uint64_t len, + bufferlist &&cmp_bl, bufferlist &&bl, + uint64_t *mismatch_off, int op_flags); void aio_read(AioCompletion *c, uint64_t off, uint64_t len, ReadResult &&read_result, int op_flags, bool native_async=true); @@ -44,6 +47,10 @@ public: void aio_flush(AioCompletion *c, bool native_async=true); void aio_writesame(AioCompletion *c, uint64_t off, uint64_t len, bufferlist &&bl, int op_flags, bool native_async=true); + void aio_compare_and_write(AioCompletion *c, uint64_t off, + uint64_t len, bufferlist &&cmp_bl, + bufferlist &&bl, uint64_t *mismatch_off, + int op_flags, bool native_async=true); using ThreadPool::PointerWQ >::drain; diff --git a/src/librbd/io/Types.h b/src/librbd/io/Types.h index 006b22298423..2b69d7bbcf03 100644 --- a/src/librbd/io/Types.h +++ b/src/librbd/io/Types.h @@ -21,6 +21,7 @@ typedef enum { AIO_TYPE_DISCARD, AIO_TYPE_FLUSH, AIO_TYPE_WRITESAME, + AIO_TYPE_COMPARE_AND_WRITE, } aio_type_t; enum Direction {