diff options
author | Dan Mick <dan.mick@inktank.com> | 2012-12-05 17:39:17 -0800 |
---|---|---|
committer | Dan Mick <dan.mick@inktank.com> | 2012-12-05 17:39:17 -0800 |
commit | 7f906b5afd5f28a3df93c31ea738e8dca8ce7992 (patch) | |
tree | 8388ae07f6f41cd0b884156125c3400fc07d8d03 | |
parent | 930bb55006aff45f717462b95690d6d0d0fb8150 (diff) | |
parent | a55700cc0aea0ff79e55c6bf78e9757b81fe9425 (diff) | |
download | ceph-7f906b5afd5f28a3df93c31ea738e8dca8ce7992.tar.gz |
Merge branch 'next'
Pull in fixes for 3567 and 3524
-rw-r--r-- | src/librbd/AioCompletion.cc | 9 | ||||
-rw-r--r-- | src/librbd/AioRequest.cc | 44 | ||||
-rw-r--r-- | src/osdc/Striper.cc | 2 |
3 files changed, 44 insertions, 11 deletions
diff --git a/src/librbd/AioCompletion.cc b/src/librbd/AioCompletion.cc index 082a08eb651..86b5b504ebd 100644 --- a/src/librbd/AioCompletion.cc +++ b/src/librbd/AioCompletion.cc @@ -88,10 +88,11 @@ namespace librbd { if (m_req->m_ext_map.empty()) m_req->m_ext_map[m_req->m_object_off] = m_req->data().length(); - m_completion->destriper.add_partial_sparse_result(m_cct, - m_req->data(), - m_req->m_ext_map, m_req->m_object_off, - m_req->m_buffer_extents); + m_completion->lock.Lock(); + m_completion->destriper.add_partial_sparse_result( + m_cct, m_req->data(), m_req->m_ext_map, m_req->m_object_off, + m_req->m_buffer_extents); + m_completion->lock.Unlock(); r = m_req->m_object_len; } m_completion->complete_request(m_cct, r); diff --git a/src/librbd/AioRequest.cc b/src/librbd/AioRequest.cc index 63424e397fc..b9a76e48e0a 100644 --- a/src/librbd/AioRequest.cc +++ b/src/librbd/AioRequest.cc @@ -157,15 +157,47 @@ namespace librbd { ldout(m_ictx->cct, 20) << "WRITE_CHECK_GUARD" << dendl; if (r == -ENOENT) { + Mutex::Locker l(m_ictx->snap_lock); Mutex::Locker l2(m_ictx->parent_lock); - // copyup the entire object up to the overlap point - ldout(m_ictx->cct, 20) << "reading from parent " << m_object_image_extents << dendl; - assert(m_object_image_extents.size()); - - m_state = LIBRBD_AIO_WRITE_COPYUP; - read_from_parent(m_object_image_extents); + /* + * Parent may have disappeared; if so, recover by using + * send_copyup() to send the original write req (the copyup + * operation itself will be a no-op, since someone must have + * populated the child object while we weren't looking). + * Move to WRITE_FLAT state as we'll be done with the + * operation once the null copyup completes. + */ + + if (m_ictx->parent == NULL) { + ldout(m_ictx->cct, 20) << "parent is gone; do null copyup " << dendl; + m_state = LIBRBD_AIO_WRITE_FLAT; + send_copyup(); + finished = false; + break; + } + + // If parent still exists, overlap might also have changed. + uint64_t newlen = m_ictx->prune_parent_extents( + m_object_image_extents, m_ictx->parent_md.overlap); + + // copyup the entire object up to the overlap point, if any + if (newlen != 0) { + ldout(m_ictx->cct, 20) << "should_complete(" << this << ") overlap " + << m_ictx->parent_md.overlap << " newlen " + << newlen << " image_extents" + << m_object_image_extents << dendl; + + m_state = LIBRBD_AIO_WRITE_COPYUP; + read_from_parent(m_object_image_extents); + } else { + ldout(m_ictx->cct, 20) << "should_complete(" << this + << "): parent overlap now 0" << dendl; + m_object_image_extents.clear(); + m_state = LIBRBD_AIO_WRITE_FLAT; + send_copyup(); + } finished = false; break; } diff --git a/src/osdc/Striper.cc b/src/osdc/Striper.cc index 26e2b917bb7..7b5a402893f 100644 --- a/src/osdc/Striper.cc +++ b/src/osdc/Striper.cc @@ -284,7 +284,7 @@ void Striper::StripedReadResult::assemble_result(CephContext *cct, bufferlist& b size_t len = p->second.first.length(); if (len < p->second.second) { if (zero_tail || bl.length()) { - bufferptr bp(p->second.second - p->second.first.length()); + bufferptr bp(p->second.second - len); bp.zero(); bl.push_front(bp); bl.claim_prepend(p->second.first); |