]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: allow updates to snapshot object maps
authorJason Dillaman <dillaman@redhat.com>
Tue, 21 Apr 2015 14:15:58 +0000 (10:15 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 7 May 2015 02:07:46 +0000 (22:07 -0400)
The modified copyup behavior will need to update snapshot object
maps when performing a copyup since the object will now exist within
all snapshots of the image.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/ObjectMap.cc
src/librbd/ObjectMap.h

index 48ae1f552b89c786a69f1137b142db502c283746..d34339b0441c1755a62b7fa32f0242a3ae3c208b 100644 (file)
@@ -474,17 +474,25 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_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,
-                                             on_finish);
-      req->send();
+      aio_update(m_snap_id, start_object_no, end_object_no, new_state,
+                 current_state, on_finish);
       return true;
     }
   }
   return false;
 }
 
+void ObjectMap::aio_update(uint64_t snap_id, uint64_t start_object_no,
+                           uint64_t end_object_no, uint8_t new_state,
+                           const boost::optional<uint8_t> &current_state,
+                           Context *on_finish) {
+  UpdateRequest *req = new UpdateRequest(m_image_ctx, snap_id,
+                                         start_object_no, end_object_no,
+                                         new_state, current_state,
+                                         on_finish);
+  req->send();
+}
+
 void ObjectMap::invalidate(uint64_t snap_id) {
   assert(m_image_ctx.snap_lock.is_wlocked());
   assert(m_image_ctx.object_map_lock.is_wlocked());
@@ -627,25 +635,32 @@ void ObjectMap::ResizeRequest::finish(ObjectMap *object_map) {
 }
 
 void ObjectMap::UpdateRequest::send() {
-  assert(m_image_ctx.object_map_lock.is_wlocked());
+  assert(m_image_ctx.object_map_lock.is_locked());
   CephContext *cct = m_image_ctx.cct;
 
   // safe to update in-memory state first without handling rollback since any
   // failures will invalidate the object map
-  ldout(cct, 20) << &m_image_ctx << " updating object map: ["
+  ldout(cct, 20) << &m_image_ctx << " updating object map"
+                 << (m_snap_id != CEPH_NOSNAP ?
+                       " snap " + stringify(m_snap_id) : std::string())
+                 << ": ["
                 << m_start_object_no << "," << m_end_object_no << ") = "
                 << (m_current_state ?
                       stringify(static_cast<uint32_t>(*m_current_state)) : "")
                 << "->" << static_cast<uint32_t>(m_new_state)
                 << dendl;
+
   ObjectMap& object_map = m_image_ctx.object_map;
-  for (uint64_t object_no = m_start_object_no;
-       object_no < MIN(m_end_object_no, object_map.m_object_map.size());
-       ++object_no) {
-    uint8_t state = object_map.m_object_map[object_no];
-    if (!m_current_state || state == *m_current_state ||
+  if (m_snap_id == object_map.m_snap_id) {
+    assert(m_image_ctx.object_map_lock.is_wlocked());
+    for (uint64_t object_no = m_start_object_no;
+         object_no < MIN(m_end_object_no, object_map.m_object_map.size());
+         ++object_no) {
+      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;
+        object_map.m_object_map[object_no] = m_new_state;
+      }
     }
   }
 
index 56b0c72f55177dc24e74b6acf4dfa61863048bdd..94c48dfb0b87b9e8b30771424d0b5c5071899c47 100644 (file)
@@ -46,6 +46,11 @@ public:
                  const boost::optional<uint8_t> &current_state,
                  Context *on_finish);
 
+  void aio_update(uint64_t snap_id, uint64_t start_object_no,
+                  uint64_t end_object_no, uint8_t new_state,
+                  const boost::optional<uint8_t> &current_state,
+                  Context *on_finish);
+
   void refresh(uint64_t snap_id);
   void rollback(uint64_t snap_id);
   void snapshot_add(uint64_t snap_id);