]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
optimize clone write path if object-map is enabled
authorxinxin shu <xinxin.shu@intel.com>
Tue, 27 Oct 2015 03:34:25 +0000 (11:34 +0800)
committerxinxin shu <xinxin.shu@intel.com>
Fri, 6 Nov 2015 01:02:00 +0000 (09:02 +0800)
Fixes : #13500

Signed-off-by: xinxin shu <xinxin.shu@intel.com>
src/librbd/AioRequest.cc
src/librbd/AioRequest.h

index b6fc1f918a6a1fb28157b1a128f52340bbf2e2ba..74c000ce2db3dee761a54a995539ef7d0186ed24 100644 (file)
@@ -324,22 +324,7 @@ namespace librbd {
       ldout(m_ictx->cct, 20) << "WRITE_CHECK_GUARD" << dendl;
 
       if (r == -ENOENT) {
-        bool has_parent;
-        {
-         RWLock::RLocker snap_locker(m_ictx->snap_lock);
-         RWLock::RLocker parent_locker(m_ictx->parent_lock);
-          has_parent = compute_parent_extents();
-        }
-
-       // If parent still exists, overlap might also have changed.
-       if (has_parent) {
-          send_copyup();
-       } else {
-          // parent may have disappeared -- send original write again
-         ldout(m_ictx->cct, 20) << "should_complete(" << this
-                                << "): parent overlap now 0" << dendl;
-          send_write();
-       }
+        handle_write_guard();
        finished = false;
        break;
       } else if (r < 0) {
@@ -395,6 +380,7 @@ namespace librbd {
   void AbstractWrite::send_pre() {
     assert(m_ictx->owner_lock.is_locked());
 
+    m_object_exist = m_ictx->object_map.object_may_exist(m_object_no);
     bool write = false;
     {
       RWLock::RLocker snap_lock(m_ictx->snap_lock);
@@ -464,19 +450,15 @@ namespace librbd {
 
   void AbstractWrite::send_write() {
     ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid << " "
-                          << m_object_off << "~" << m_object_len << dendl;
+                          << m_object_off << "~" << m_object_len 
+                           << " object exist " << m_object_exist << dendl;
 
-    m_state = LIBRBD_AIO_WRITE_FLAT;
-    guard_write();
-    add_write_ops(&m_write);
-    assert(m_write.size() != 0);
-
-    librados::AioCompletion *rados_completion =
-      librados::Rados::aio_create_completion(this, NULL, rados_req_cb);
-    int r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write,
-                                        m_snap_seq, m_snaps);
-    assert(r == 0);
-    rados_completion->release();
+    if (!m_object_exist && has_parent()) {
+      m_state = LIBRBD_AIO_WRITE_GUARD;
+      handle_write_guard();
+    } else {
+      send_write_op(true);
+    }
   }
 
   void AbstractWrite::send_copyup()
@@ -504,6 +486,39 @@ namespace librbd {
       m_ictx->copyup_list_lock.Unlock();
     }
   }
+  void AbstractWrite::send_write_op(bool write_guard)
+  {
+    m_state = LIBRBD_AIO_WRITE_FLAT;
+    if (write_guard)
+      guard_write();
+    add_write_ops(&m_write);
+    assert(m_write.size() != 0);
+
+    librados::AioCompletion *rados_completion =
+      librados::Rados::aio_create_completion(this, NULL, rados_req_cb);
+    int r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write,
+                                        m_snap_seq, m_snaps);
+    assert(r == 0);
+    rados_completion->release();
+  }
+  void AbstractWrite::handle_write_guard()
+  {
+    bool has_parent;
+    {
+      RWLock::RLocker snap_locker(m_ictx->snap_lock);
+      RWLock::RLocker parent_locker(m_ictx->parent_lock);
+      has_parent = compute_parent_extents();
+    }
+    // If parent still exists, overlap might also have changed.
+    if (has_parent) {
+      send_copyup();
+    } else {
+      // parent may have disappeared -- send original write again
+      ldout(m_ictx->cct, 20) << "should_complete(" << this
+        << "): parent overlap now 0" << dendl;
+      send_write();
+    }
+  }
 
   void AioWrite::add_write_ops(librados::ObjectWriteOperation *wr) {
     if (m_ictx->enable_alloc_hint && !m_ictx->object_map.object_may_exist(m_object_no))
@@ -523,4 +538,9 @@ namespace librbd {
       AbstractWrite::guard_write();
     }
   }
+  void AioRemove::send_write() {
+    ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid << " "
+                          << m_object_off << "~" << m_object_len << dendl;
+    send_write_op(true);
+  }
 }
index 885cbce887684aa7369fde771e119b26fea7e61a..2032aef0ba80cdf8fa076dbda3f28820308bdbdb 100644 (file)
@@ -128,7 +128,6 @@ namespace librbd {
     virtual bool should_complete(int r);
     virtual void send();
 
-  private:
     /**
      * Writes go through the following state machine to deal with
      * layering and the object map:
@@ -163,6 +162,7 @@ namespace librbd {
      * The write starts in _WRITE_GUARD or _FLAT depending on whether or not
      * there is a parent overlap.
      */
+  protected:
     enum write_state_d {
       LIBRBD_AIO_WRITE_GUARD,
       LIBRBD_AIO_WRITE_COPYUP,
@@ -172,11 +172,11 @@ namespace librbd {
       LIBRBD_AIO_WRITE_ERROR
     };
 
-  protected:
     write_state_d m_state;
     librados::ObjectWriteOperation m_write;
     uint64_t m_snap_seq;
     std::vector<librados::snap_t> m_snaps;
+    bool m_object_exist;
 
     virtual void add_write_ops(librados::ObjectWriteOperation *wr) = 0;
     virtual const char* get_write_type() const = 0;
@@ -185,11 +185,13 @@ namespace librbd {
     virtual bool post_object_map_update() {
       return false;
     }
+    virtual void send_write();
+    virtual void send_write_op(bool write_guard);
+    virtual void handle_write_guard();
 
   private:
     void send_pre();
     bool send_post();
-    void send_write();
     void send_copyup();
   };
 
@@ -264,6 +266,7 @@ namespace librbd {
     }
 
     virtual void guard_write();
+    virtual void send_write();
 
   private:
     uint8_t m_object_state;