From 05a5f269d06714c3e604786d9e12813a225c6071 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 1 May 2015 14:41:40 -0400 Subject: [PATCH] librbd: object map is not properly updated when deleting clean objects With the new fast diff feature flagging which objects haven't changed between snapshots, unmodified objects are now flagged with a new state code in the object map. The OBJECT_EXISTS_CLEAN state needs to be treated as if it were OBJECT_EXISTS when deleting. Signed-off-by: Jason Dillaman --- src/cls/rbd/cls_rbd.cc | 6 ++++-- src/librbd/ObjectMap.cc | 17 +++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/cls/rbd/cls_rbd.cc b/src/cls/rbd/cls_rbd.cc index 281f566f9da05..0cf5eb84d7a7a 100644 --- a/src/cls/rbd/cls_rbd.cc +++ b/src/cls/rbd/cls_rbd.cc @@ -2211,8 +2211,10 @@ int object_map_update(cls_method_context_t hctx, bufferlist *in, bufferlist *out bool updated = false; for (uint64_t object_no = start_object_no; object_no < end_object_no; ++object_no) { - if ((!current_object_state || object_map[object_no] == *current_object_state) && - object_map[object_no] != new_object_state) { + uint8_t state = object_map[object_no]; + if ((!current_object_state || state == *current_object_state || + (*current_object_state == OBJECT_EXISTS && + state == OBJECT_EXISTS_CLEAN)) && state != new_object_state) { object_map[object_no] = new_object_state; updated = true; } diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index 1b158da93bcad..48ae1f552b89c 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -459,8 +459,10 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no, CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << &m_image_ctx << " aio_update: start=" << start_object_no - << ", end=" << end_object_no << ", new_state=" - << static_cast(new_state) << dendl; + << ", end=" << end_object_no << ", " + << (current_state ? + stringify(static_cast(*current_state)) : "") + << "->" << static_cast(new_state) << dendl; if (end_object_no > m_object_map.size()) { ldout(cct, 20) << "skipping update of invalid object map" << dendl; return false; @@ -468,8 +470,10 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no, for (uint64_t object_no = start_object_no; object_no < end_object_no; ++object_no) { - if ((!current_state || m_object_map[object_no] == *current_state) && - m_object_map[object_no] != new_state) { + uint8_t state = m_object_map[object_no]; + if ((!current_state || state == *current_state || + (*current_state == OBJECT_EXISTS && state == OBJECT_EXISTS_CLEAN)) && + state != new_state) { UpdateRequest *req = new UpdateRequest(m_image_ctx, m_snap_id, start_object_no, end_object_no, new_state, current_state, @@ -638,8 +642,9 @@ void ObjectMap::UpdateRequest::send() { for (uint64_t object_no = m_start_object_no; object_no < MIN(m_end_object_no, object_map.m_object_map.size()); ++object_no) { - if (!m_current_state || - object_map.m_object_map[object_no] == *m_current_state) { + uint8_t state = object_map.m_object_map[object_no]; + if (!m_current_state || state == *m_current_state || + (*m_current_state == OBJECT_EXISTS && state == OBJECT_EXISTS_CLEAN)) { object_map.m_object_map[object_no] = m_new_state; } } -- 2.39.5