]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: only update image flags when holding exclusive lock
authorJason Dillaman <dillaman@redhat.com>
Tue, 23 Jun 2015 15:14:51 +0000 (11:14 -0400)
committerJason Dillaman <dillaman@redhat.com>
Sun, 19 Jul 2015 17:44:16 +0000 (13:44 -0400)
It was possible for a client to open an image while another client
was shrinking an image.  This would result in the former invalidating
the object map on-disk if it openned the image between updating the
image header and resizing the object map.

Fixes: #11791
Backport: hammer
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit eb81a6a7e391327ac993fd406443b206a7f7bffc)

src/librbd/ObjectMap.cc

index 8099a9103847ac459f2f162e017db2e221f42433..67ff1a20e30cfd0ee883e58baf4db7c0cc6c17e3 100644 (file)
@@ -338,13 +338,25 @@ void ObjectMap::invalidate() {
   m_image_ctx.update_flags(m_image_ctx.snap_id, RBD_FLAG_OBJECT_MAP_INVALID,
                            true);
 
+  // do not update on-disk flags if not image owner
+  if (m_image_ctx.image_watcher->is_lock_supported(m_image_ctx.snap_lock) &&
+      !m_image_ctx.image_watcher->is_lock_owner()) {
+    return;
+  }
+
   librados::ObjectWriteOperation op;
+  if (m_image_ctx.snap_id == CEPH_NOSNAP) {
+    m_image_ctx.image_watcher->assert_header_locked(&op);
+  }
   cls_client::set_flags(&op, m_image_ctx.snap_id, m_image_ctx.flags,
                         RBD_FLAG_OBJECT_MAP_INVALID);
 
   int r = m_image_ctx.md_ctx.operate(m_image_ctx.header_oid, &op);
-  if (r < 0) {
-    lderr(cct) << "failed to invalidate object map: " << cpp_strerror(r)
+  if (r == -EBUSY) {
+    ldout(cct, 5) << "skipping on-disk object map invalidation: "
+                  << "image not locked by client" << dendl;
+  } else if (r < 0) {
+    lderr(cct) << "failed to invalidate on-disk object map: " << cpp_strerror(r)
               << dendl;
   }
 }
@@ -403,6 +415,7 @@ bool ObjectMap::Request::invalidate() {
   m_image_ctx.flags |= RBD_FLAG_OBJECT_MAP_INVALID;
 
   librados::ObjectWriteOperation op;
+  m_image_ctx.image_watcher->assert_header_locked(&op);
   cls_client::set_flags(&op, CEPH_NOSNAP, m_image_ctx.flags,
                         RBD_FLAG_OBJECT_MAP_INVALID);