From: Jason Dillaman Date: Wed, 20 May 2015 19:04:54 +0000 (-0400) Subject: librbd: whole-object discards should copyup when snapshots exist X-Git-Tag: v9.0.2~13^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cd0fd833ad39651afd47baf2678b80ec336465be;p=ceph.git librbd: whole-object discards should copyup when snapshots exist Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/AioRequest.cc b/src/librbd/AioRequest.cc index 3e7fdf98b106..7339b7f93d72 100644 --- a/src/librbd/AioRequest.cc +++ b/src/librbd/AioRequest.cc @@ -393,35 +393,42 @@ namespace librbd { void AbstractWrite::send_pre() { assert(m_ictx->owner_lock.is_locked()); - RWLock::RLocker snap_lock(m_ictx->snap_lock); - if (!m_ictx->object_map.enabled()) { - send_write(); - return; - } - - // should have been flushed prior to releasing lock - assert(m_ictx->image_watcher->is_lock_owner()); - - ldout(m_ictx->cct, 20) << "send_pre " << this << " " << m_oid << " " - << m_object_off << "~" << m_object_len << dendl; - m_state = LIBRBD_AIO_WRITE_PRE; - - uint8_t new_state; - boost::optional current_state; - pre_object_map_update(&new_state); + bool write = false; + { + RWLock::RLocker snap_lock(m_ictx->snap_lock); + if (!m_ictx->object_map.enabled()) { + write = true; + } else { + // should have been flushed prior to releasing lock + assert(m_ictx->image_watcher->is_lock_owner()); + + ldout(m_ictx->cct, 20) << "send_pre " << this << " " << m_oid << " " + << m_object_off << "~" << m_object_len << dendl; + m_state = LIBRBD_AIO_WRITE_PRE; + + uint8_t new_state; + boost::optional current_state; + pre_object_map_update(&new_state); + + RWLock::WLocker object_map_locker(m_ictx->object_map_lock); + if (m_ictx->object_map[m_object_no] != new_state) { + FunctionContext *ctx = new FunctionContext( + boost::bind(&AioRequest::complete, this, _1)); + bool updated = m_ictx->object_map.aio_update(m_object_no, new_state, + current_state, ctx); + assert(updated); + } else { + write = true; + } + } + } - RWLock::WLocker object_map_locker(m_ictx->object_map_lock); - if (m_ictx->object_map[m_object_no] == new_state) { + // avoid possible recursive lock attempts + if (write) { + // no object map update required send_write(); - return; } - - FunctionContext *ctx = new FunctionContext( - boost::bind(&AioRequest::complete, this, _1)); - bool updated = m_ictx->object_map.aio_update(m_object_no, new_state, - current_state, ctx); - assert(updated); } bool AbstractWrite::send_post() { @@ -502,4 +509,12 @@ namespace librbd { wr->write(m_object_off, m_write_data); wr->set_op_flags2(m_op_flags); } + + void AioRemove::guard_write() { + // do nothing to disable write guard only if deep-copyup not required + RWLock::RLocker snap_locker(m_ictx->snap_lock); + if (!m_ictx->snaps.empty()) { + AbstractWrite::guard_write(); + } + } } diff --git a/src/librbd/AioRequest.h b/src/librbd/AioRequest.h index 24c89ce8beb2..885cbce88768 100644 --- a/src/librbd/AioRequest.h +++ b/src/librbd/AioRequest.h @@ -263,9 +263,7 @@ namespace librbd { return true; } - virtual void guard_write() { - // do nothing to disable write guard - } + virtual void guard_write(); private: uint8_t m_object_state;