From: xinxin shu Date: Tue, 27 Oct 2015 03:34:25 +0000 (+0800) Subject: optimize clone write path if object-map is enabled X-Git-Tag: v10.0.1~120^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=40dcfe2f83c21be5e12cfb157b2995ea18a10950;p=ceph.git optimize clone write path if object-map is enabled Fixes : #13500 Signed-off-by: xinxin shu --- diff --git a/src/librbd/AioRequest.cc b/src/librbd/AioRequest.cc index b6fc1f918a6a..74c000ce2db3 100644 --- a/src/librbd/AioRequest.cc +++ b/src/librbd/AioRequest.cc @@ -324,22 +324,7 @@ namespace librbd { ldout(m_ictx->cct, 20) << "WRITE_CHECK_GUARD" << dendl; if (r == -ENOENT) { - bool has_parent; - { - RWLock::RLocker snap_locker(m_ictx->snap_lock); - RWLock::RLocker parent_locker(m_ictx->parent_lock); - has_parent = compute_parent_extents(); - } - - // If parent still exists, overlap might also have changed. - if (has_parent) { - send_copyup(); - } else { - // parent may have disappeared -- send original write again - ldout(m_ictx->cct, 20) << "should_complete(" << this - << "): parent overlap now 0" << dendl; - send_write(); - } + handle_write_guard(); finished = false; break; } else if (r < 0) { @@ -395,6 +380,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 +450,15 @@ namespace librbd { void AbstractWrite::send_write() { ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid << " " - << m_object_off << "~" << m_object_len << dendl; + << m_object_off << "~" << m_object_len + << " object exist " << m_object_exist << dendl; - m_state = LIBRBD_AIO_WRITE_FLAT; - guard_write(); - 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(); + if (!m_object_exist && has_parent()) { + m_state = LIBRBD_AIO_WRITE_GUARD; + handle_write_guard(); + } else { + send_write_op(true); + } } void AbstractWrite::send_copyup() @@ -504,6 +486,39 @@ namespace librbd { m_ictx->copyup_list_lock.Unlock(); } } + void AbstractWrite::send_write_op(bool write_guard) + { + m_state = LIBRBD_AIO_WRITE_FLAT; + if (write_guard) + guard_write(); + 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 AbstractWrite::handle_write_guard() + { + bool has_parent; + { + RWLock::RLocker snap_locker(m_ictx->snap_lock); + RWLock::RLocker parent_locker(m_ictx->parent_lock); + has_parent = compute_parent_extents(); + } + // If parent still exists, overlap might also have changed. + if (has_parent) { + send_copyup(); + } else { + // parent may have disappeared -- send original write again + ldout(m_ictx->cct, 20) << "should_complete(" << this + << "): parent overlap now 0" << dendl; + send_write(); + } + } 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 +538,9 @@ 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; + send_write_op(true); + } } diff --git a/src/librbd/AioRequest.h b/src/librbd/AioRequest.h index 885cbce88768..2032aef0ba80 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,13 @@ namespace librbd { virtual bool post_object_map_update() { return false; } + virtual void send_write(); + virtual void send_write_op(bool write_guard); + virtual void handle_write_guard(); private: void send_pre(); bool send_post(); - void send_write(); void send_copyup(); }; @@ -264,6 +266,7 @@ namespace librbd { } virtual void guard_write(); + virtual void send_write(); private: uint8_t m_object_state;