]> git.apps.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>
Tue, 23 Jun 2015 15:21:32 +0000 (11:21 -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>
src/librbd/ObjectMap.cc

index 1aa6d7407968ce0836de03af4842123ee5a26bf4..d45bd65fe4e2f9f7b871fb83bf88868f966c57a7 100644 (file)
@@ -517,11 +517,23 @@ void ObjectMap::invalidate(uint64_t snap_id) {
     return;
   }
 
+  // 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 (snap_id == CEPH_NOSNAP) {
+    m_image_ctx.image_watcher->assert_header_locked(&op);
+  }
   cls_client::set_flags(&op, snap_id, flags, flags);
 
   r = m_image_ctx.md_ctx.operate(m_image_ctx.header_oid, &op);
-  if (r < 0) {
+  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;
   }
@@ -595,6 +607,7 @@ bool ObjectMap::Request::invalidate() {
   m_image_ctx.flags |= flags;
 
   librados::ObjectWriteOperation op;
+  m_image_ctx.image_watcher->assert_header_locked(&op);
   cls_client::set_flags(&op, CEPH_NOSNAP, flags, flags);
 
   librados::AioCompletion *rados_completion = create_callback_completion();