]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: whole-object discards should copyup when snapshots exist
authorJason Dillaman <dillaman@redhat.com>
Wed, 20 May 2015 19:04:54 +0000 (15:04 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 5 Jun 2015 16:24:19 +0000 (12:24 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/AioRequest.cc
src/librbd/AioRequest.h

index 3e7fdf98b106e712888793e9cc64be9126fa0a3e..7339b7f93d72979d49f2dedd61f79e197440dcd9 100644 (file)
@@ -393,35 +393,42 @@ namespace librbd {
 
   void AbstractWrite::send_pre() {
     assert(m_ictx->owner_lock.is_locked());
-    RWLock::RLocker snap_lock(m_ictx->snap_lock);
-    if (!m_ictx->object_map.enabled()) {
-      send_write();
-      return;
-    }
-
-    // should have been flushed prior to releasing lock
-    assert(m_ictx->image_watcher->is_lock_owner());
-
-    ldout(m_ictx->cct, 20) << "send_pre " << this << " " << m_oid << " "
-                          << m_object_off << "~" << m_object_len << dendl;
-    m_state = LIBRBD_AIO_WRITE_PRE;
-
-    uint8_t new_state;
-    boost::optional<uint8_t> current_state;
-    pre_object_map_update(&new_state);
 
+    bool write = false;
+    {
+      RWLock::RLocker snap_lock(m_ictx->snap_lock);
+      if (!m_ictx->object_map.enabled()) {
+        write = true;
+      } else {
+        // should have been flushed prior to releasing lock
+        assert(m_ictx->image_watcher->is_lock_owner());
+
+        ldout(m_ictx->cct, 20) << "send_pre " << this << " " << m_oid << " "
+                              << m_object_off << "~" << m_object_len << dendl;
+        m_state = LIBRBD_AIO_WRITE_PRE;
+
+        uint8_t new_state;
+        boost::optional<uint8_t> current_state;
+        pre_object_map_update(&new_state);
+
+        RWLock::WLocker object_map_locker(m_ictx->object_map_lock);
+        if (m_ictx->object_map[m_object_no] != new_state) {
+          FunctionContext *ctx = new FunctionContext(
+            boost::bind(&AioRequest::complete, this, _1));
+          bool updated = m_ictx->object_map.aio_update(m_object_no, new_state,
+                                                       current_state, ctx);
+          assert(updated);
+        } else {
+          write = true;
+        }
+      }
+    }
 
-    RWLock::WLocker object_map_locker(m_ictx->object_map_lock);
-    if (m_ictx->object_map[m_object_no] == new_state) {
+    // avoid possible recursive lock attempts
+    if (write) {
+      // no object map update required
       send_write();
-      return;
     }
-
-    FunctionContext *ctx = new FunctionContext(
-      boost::bind(&AioRequest::complete, this, _1));
-    bool updated = m_ictx->object_map.aio_update(m_object_no, new_state,
-                                                 current_state, ctx);
-    assert(updated);
   }
 
   bool AbstractWrite::send_post() {
@@ -502,4 +509,12 @@ namespace librbd {
     wr->write(m_object_off, m_write_data);
     wr->set_op_flags2(m_op_flags);
   }
+
+  void AioRemove::guard_write() {
+    // do nothing to disable write guard only if deep-copyup not required
+    RWLock::RLocker snap_locker(m_ictx->snap_lock);
+    if (!m_ictx->snaps.empty()) {
+      AbstractWrite::guard_write();
+    }
+  }
 }
index 24c89ce8beb2ec9eb29efc0ff405b085cf3fe30a..885cbce887684aa7369fde771e119b26fea7e61a 100644 (file)
@@ -263,9 +263,7 @@ namespace librbd {
       return true;
     }
 
-    virtual void guard_write() {
-      // do nothing to disable write guard
-    }
+    virtual void guard_write();
 
   private:
     uint8_t m_object_state;