From 46c200a0f470f4acd9714c60e141f85334018d25 Mon Sep 17 00:00:00 2001 From: xinxin shu Date: Tue, 27 Oct 2015 11:34:25 +0800 Subject: [PATCH] optimize clone write path if object-map is enabled Fixes : #13500 Signed-off-by: xinxin shu --- src/librbd/AioRequest.cc | 41 ++++++++++++++++++++++++++++------------ src/librbd/AioRequest.h | 8 +++++--- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/librbd/AioRequest.cc b/src/librbd/AioRequest.cc index b6fc1f918a6a1f..8405b42dc405ab 100644 --- a/src/librbd/AioRequest.cc +++ b/src/librbd/AioRequest.cc @@ -395,6 +395,7 @@ namespace librbd { void AbstractWrite::send_pre() { assert(m_ictx->owner_lock.is_locked()); + m_object_exist = m_ictx->object_map.object_may_exist(m_object_no); bool write = false; { RWLock::RLocker snap_lock(m_ictx->snap_lock); @@ -464,19 +465,16 @@ namespace librbd { void AbstractWrite::send_write() { ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid << " " - << m_object_off << "~" << m_object_len << dendl; - - m_state = LIBRBD_AIO_WRITE_FLAT; - guard_write(); - add_write_ops(&m_write); - assert(m_write.size() != 0); + << m_object_off << "~" << m_object_len + << " object exist " << m_object_exist << dendl; - librados::AioCompletion *rados_completion = - librados::Rados::aio_create_completion(this, NULL, rados_req_cb); - int r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write, - m_snap_seq, m_snaps); - assert(r == 0); - rados_completion->release(); + if (m_object_exist) { + m_state = LIBRBD_AIO_WRITE_FLAT; + send_write_op(); + } else { + m_state = LIBRBD_AIO_WRITE_GUARD; + complete(-ENOENT); + } } void AbstractWrite::send_copyup() @@ -504,6 +502,18 @@ namespace librbd { m_ictx->copyup_list_lock.Unlock(); } } + void AbstractWrite::send_write_op() + { + add_write_ops(&m_write); + assert(m_write.size() != 0); + + librados::AioCompletion *rados_completion = + librados::Rados::aio_create_completion(this, NULL, rados_req_cb); + int r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write, + m_snap_seq, m_snaps); + assert(r == 0); + rados_completion->release(); + } void AioWrite::add_write_ops(librados::ObjectWriteOperation *wr) { if (m_ictx->enable_alloc_hint && !m_ictx->object_map.object_may_exist(m_object_no)) @@ -523,4 +533,11 @@ namespace librbd { AbstractWrite::guard_write(); } } + void AioRemove::send_write() { + ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid << " " + << m_object_off << "~" << m_object_len << dendl; + m_state = LIBRBD_AIO_WRITE_FLAT; + guard_write(); + send_write_op(); + } } diff --git a/src/librbd/AioRequest.h b/src/librbd/AioRequest.h index 885cbce887684a..9021f50ab6af25 100644 --- a/src/librbd/AioRequest.h +++ b/src/librbd/AioRequest.h @@ -128,7 +128,6 @@ namespace librbd { virtual bool should_complete(int r); virtual void send(); - private: /** * Writes go through the following state machine to deal with * layering and the object map: @@ -163,6 +162,7 @@ namespace librbd { * The write starts in _WRITE_GUARD or _FLAT depending on whether or not * there is a parent overlap. */ + protected: enum write_state_d { LIBRBD_AIO_WRITE_GUARD, LIBRBD_AIO_WRITE_COPYUP, @@ -172,11 +172,11 @@ namespace librbd { LIBRBD_AIO_WRITE_ERROR }; - protected: write_state_d m_state; librados::ObjectWriteOperation m_write; uint64_t m_snap_seq; std::vector m_snaps; + bool m_object_exist; virtual void add_write_ops(librados::ObjectWriteOperation *wr) = 0; virtual const char* get_write_type() const = 0; @@ -185,11 +185,12 @@ namespace librbd { virtual bool post_object_map_update() { return false; } + virtual void send_write(); + virtual void send_write_op(); private: void send_pre(); bool send_post(); - void send_write(); void send_copyup(); }; @@ -264,6 +265,7 @@ namespace librbd { } virtual void guard_write(); + virtual void send_write(); private: uint8_t m_object_state;