]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: simplify AioRequest constructor parameters 4233/head
authorJason Dillaman <dillaman@redhat.com>
Tue, 31 Mar 2015 16:28:11 +0000 (12:28 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 7 Apr 2015 15:26:57 +0000 (11:26 -0400)
Moved all parent overlap computation to within AioRequest so that
callers don't need to independently compute the overlap.  Also
removed the need to pass the snap_id for write operations since
it can only be CEPH_NOSNAP.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/AioRequest.cc
src/librbd/AioRequest.h
src/librbd/AsyncFlattenRequest.cc
src/librbd/AsyncTrimRequest.cc
src/librbd/LibrbdWriteback.cc
src/librbd/internal.cc

index 3bbbab9ec6e94285dcb9eae218e092182aefe917..ea1df532d1ec27862f8562d8fdc47d051a1d1bb1 100644 (file)
 
 namespace librbd {
 
-  AioRequest::AioRequest() :
-    m_ictx(NULL),
-    m_object_no(0), m_object_off(0), m_object_len(0),
-    m_snap_id(CEPH_NOSNAP), m_completion(NULL), m_parent_completion(NULL),
-    m_hide_enoent(false) {}
   AioRequest::AioRequest(ImageCtx *ictx, const std::string &oid,
                         uint64_t objectno, uint64_t off, uint64_t len,
-                        const ::SnapContext &snapc, librados::snap_t snap_id,
+                        librados::snap_t snap_id,
                         Context *completion,
-                        bool hide_enoent) :
-    m_ictx(ictx), m_oid(oid), m_object_no(objectno),
-    m_object_off(off), m_object_len(len), m_snap_id(snap_id),
-    m_completion(completion), m_parent_completion(NULL),
-    m_hide_enoent(hide_enoent) {
-    m_snaps.insert(m_snaps.end(), snapc.snaps.begin(), snapc.snaps.end());
+                        bool hide_enoent)
+    : m_ictx(ictx), m_oid(oid), m_object_no(objectno), m_object_off(off),
+      m_object_len(len), m_snap_id(snap_id), m_completion(completion),
+      m_parent_completion(NULL), m_hide_enoent(hide_enoent) {
+
+    Striper::extent_to_file(m_ictx->cct, &m_ictx->layout, m_object_no,
+                            0, m_ictx->layout.fl_object_size, m_parent_extents);
+
+    RWLock::RLocker snap_locker(m_ictx->snap_lock);
+    RWLock::RLocker parent_locker(m_ictx->parent_lock);
+    compute_parent_extents();
   }
 
   AioRequest::~AioRequest() {
@@ -60,7 +60,34 @@ namespace librbd {
     }
   }
 
-  void AioRequest::read_from_parent(vector<pair<uint64_t,uint64_t> >& image_extents,
+  bool AioRequest::compute_parent_extents() {
+    assert(m_ictx->snap_lock.is_locked());
+    assert(m_ictx->parent_lock.is_locked());
+
+    uint64_t parent_overlap;
+    int r = m_ictx->get_parent_overlap(m_snap_id, &parent_overlap);
+    if (r < 0) {
+      // NOTE: it's possible for a snapshot to be deleted while we are
+      // still reading from it
+      lderr(m_ictx->cct) << this << " compute_parent_extents: failed to "
+                         << "retrieve parent overlap: " << cpp_strerror(r)
+                         << dendl;
+      m_parent_extents.clear();
+      return false;
+    }
+
+    uint64_t object_overlap =
+      m_ictx->prune_parent_extents(m_parent_extents, parent_overlap);
+    if (object_overlap > 0) {
+      ldout(m_ictx->cct, 20) << this << " compute_parent_extents: "
+                             << "overlap " << parent_overlap << " "
+                             << "extents " << m_parent_extents << dendl;
+      return true;
+    }
+    return false;
+  }
+
+  void AioRequest::read_from_parent(const vector<pair<uint64_t,uint64_t> >& parent_extents,
                                     bool block_completion)
   {
     assert(!m_parent_completion);
@@ -74,9 +101,9 @@ namespace librbd {
 
     ldout(m_ictx->cct, 20) << "read_from_parent this = " << this
                           << " parent completion " << m_parent_completion
-                          << " extents " << image_extents
+                          << " extents " << parent_extents
                           << dendl;
-    int r = aio_read(m_ictx->parent, image_extents, NULL, &m_read_data,
+    int r = aio_read(m_ictx->parent, parent_extents, NULL, &m_read_data,
                     m_parent_completion, 0);
     if (r < 0) {
       lderr(m_ictx->cct) << "read_from_parent " << this
@@ -98,32 +125,21 @@ namespace librbd {
   AioRead::AioRead(ImageCtx *ictx, const std::string &oid,
                    uint64_t objectno, uint64_t offset, uint64_t len,
                    vector<pair<uint64_t,uint64_t> >& be,
-                   const ::SnapContext &snapc,
                    librados::snap_t snap_id, bool sparse,
                    Context *completion, int op_flags)
-    : AioRequest(ictx, oid, objectno, offset, len, snapc, snap_id, completion,
-                false),
-      m_buffer_extents(be), m_tried_parent(false),
-      m_sparse(sparse), m_op_flags(op_flags), m_state(LIBRBD_AIO_READ_FLAT) {
-    RWLock::RLocker l(m_ictx->snap_lock);
-    RWLock::RLocker l2(m_ictx->parent_lock);
-
-    Striper::extent_to_file(m_ictx->cct, &m_ictx->layout,
-                            m_object_no, 0, m_ictx->layout.fl_object_size,
-                            m_image_extents);
+    : AioRequest(ictx, oid, objectno, offset, len, snap_id, completion, false),
+      m_buffer_extents(be), m_tried_parent(false), m_sparse(sparse),
+      m_op_flags(op_flags), m_state(LIBRBD_AIO_READ_FLAT) {
 
     guard_read();
   }
 
   void AioRead::guard_read()
   {
-    assert(m_ictx->snap_lock.is_locked());
+    RWLock::RLocker snap_locker(m_ictx->snap_lock);
+    RWLock::RLocker parent_locker(m_ictx->parent_lock);
 
-    uint64_t image_overlap = 0;
-    m_ictx->get_parent_overlap(m_snap_id, &image_overlap);
-    uint64_t object_overlap =
-      m_ictx->prune_parent_extents(m_image_extents, image_overlap);
-    if (object_overlap) {
+    if (has_parent()) {
       ldout(m_ictx->cct, 20) << __func__ << " guarding read" << dendl;
       m_state = LIBRBD_AIO_READ_GUARD;
     }
@@ -131,7 +147,8 @@ namespace librbd {
 
   bool AioRead::should_complete(int r)
   {
-    ldout(m_ictx->cct, 20) << "should_complete " << this << " " << m_oid << " " << m_object_off << "~" << m_object_len
+    ldout(m_ictx->cct, 20) << "should_complete " << this << " " << m_oid << " "
+                           << m_object_off << "~" << m_object_len
                            << " r = " << r << dendl;
 
     bool finished = true;
@@ -154,25 +171,25 @@ namespace librbd {
          }
 
           // calculate reverse mapping onto the image
-          vector<pair<uint64_t,uint64_t> > image_extents;
-          Striper::extent_to_file(m_ictx->cct, &m_ictx->layout,
-                                 m_object_no, m_object_off, m_object_len,
-                                 image_extents);
-
-          uint64_t image_overlap = 0;
-          r = m_ictx->get_parent_overlap(m_snap_id, &image_overlap);
-          if (r < 0) {
-            assert(0 == "FIXME");
+          vector<pair<uint64_t,uint64_t> > parent_extents;
+          Striper::extent_to_file(m_ictx->cct, &m_ictx->layout, m_object_no,
+                                  m_object_off, m_object_len, parent_extents);
+
+          uint64_t parent_overlap = 0;
+          uint64_t object_overlap = 0;
+          r = m_ictx->get_parent_overlap(m_snap_id, &parent_overlap);
+          if (r == 0) {
+            object_overlap = m_ictx->prune_parent_extents(parent_extents,
+                                                          parent_overlap);
           }
-          uint64_t object_overlap = m_ictx->prune_parent_extents(image_extents,
-                                                                 image_overlap);
-          if (object_overlap) {
+
+          if (object_overlap > 0) {
             m_tried_parent = true;
             if (is_copy_on_read(m_ictx, m_snap_id)) {
               m_state = LIBRBD_AIO_READ_COPYUP;
            }
 
-            read_from_parent(image_extents, true);
+            read_from_parent(parent_extents, true);
             finished = false;
           }
         }
@@ -187,7 +204,8 @@ namespace librbd {
       }
       break;
     case LIBRBD_AIO_READ_COPYUP:
-      ldout(m_ictx->cct, 20) << "should_complete " << this << " READ_COPYUP" << dendl;
+      ldout(m_ictx->cct, 20) << "should_complete " << this << " READ_COPYUP"
+                             << dendl;
       // This is the extra step for copy-on-read: kick off an asynchronous copyup.
       // It is different from copy-on-write as asynchronous copyup will finish
       // by itself so state won't go back to LIBRBD_AIO_READ_GUARD.
@@ -201,25 +219,13 @@ namespace librbd {
         map<uint64_t, CopyupRequest*>::iterator it =
           m_ictx->copyup_list.find(m_object_no);
         if (it == m_ictx->copyup_list.end()) {
-          RWLock::RLocker l(m_ictx->snap_lock);
-          RWLock::RLocker l2(m_ictx->parent_lock);
-          if (m_ictx->parent == NULL) {
-            ldout(m_ictx->cct, 20) << "parent is gone; do nothing" << dendl;
-            break;
-          }
-
-          // If parent still exists, overlap might also have changed.
-          uint64_t parent_overlap;
-          r = m_ictx->get_parent_overlap(CEPH_NOSNAP, &parent_overlap);
-          assert(r == 0);
-
-          uint64_t newlen = m_ictx->prune_parent_extents(
-            m_image_extents, parent_overlap);
-          if (newlen != 0) {
+          RWLock::RLocker snap_locker(m_ictx->snap_lock);
+          RWLock::RLocker parent_locker(m_ictx->parent_lock);
+          if (compute_parent_extents()) {
             // create and kick off a CopyupRequest
             CopyupRequest *new_req = new CopyupRequest(m_ictx, m_oid,
                                                        m_object_no,
-                                                      m_image_extents);
+                                                      m_parent_extents);
             m_ictx->copyup_list[m_object_no] = new_req;
             new_req->queue_send();
           }
@@ -227,7 +233,8 @@ namespace librbd {
       }
       break;
     case LIBRBD_AIO_READ_FLAT:
-      ldout(m_ictx->cct, 20) << "should_complete " << this << " READ_FLAT" << dendl;
+      ldout(m_ictx->cct, 20) << "should_complete " << this << " READ_FLAT"
+                             << dendl;
       // The read content should be deposit in m_read_data
       break;
     default:
@@ -239,7 +246,8 @@ namespace librbd {
   }
 
   int AioRead::send() {
-    ldout(m_ictx->cct, 20) << "send " << this << " " << m_oid << " " << m_object_off << "~" << m_object_len << dendl;
+    ldout(m_ictx->cct, 20) << "send " << this << " " << m_oid << " "
+                           << m_object_off << "~" << m_object_len << dendl;
 
     // send read request to parent if the object doesn't exist locally
     if (!m_ictx->object_map.object_may_exist(m_object_no)) {
@@ -267,24 +275,16 @@ namespace librbd {
 
   /** write **/
 
-  AbstractWrite::AbstractWrite()
-    : m_state(LIBRBD_AIO_WRITE_FLAT),
-      m_parent_overlap(0),
-      m_snap_seq(0) {}
   AbstractWrite::AbstractWrite(ImageCtx *ictx, const std::string &oid,
-                              uint64_t object_no, uint64_t object_off, uint64_t len,
-                              vector<pair<uint64_t,uint64_t> >& objectx,
-                              uint64_t object_overlap,
-                              const ::SnapContext &snapc, librados::snap_t snap_id,
-                              Context *completion,
-                              bool hide_enoent)
-    : AioRequest(ictx, oid, object_no, object_off, len, snapc, snap_id, 
-                 completion, hide_enoent),
+                               uint64_t object_no, uint64_t object_off,
+                               uint64_t len, const ::SnapContext &snapc,
+                               Context *completion, bool hide_enoent)
+    : AioRequest(ictx, oid, object_no, object_off, len, CEPH_NOSNAP, completion,
+                 hide_enoent),
       m_state(LIBRBD_AIO_WRITE_FLAT), m_snap_seq(snapc.seq.val),
       m_entire_object(NULL)
   {
-    m_object_image_extents = objectx;
-    m_parent_overlap = object_overlap;
+    m_snaps.insert(m_snaps.end(), snapc.snaps.begin(), snapc.snaps.end());
   }
 
   void AbstractWrite::guard_write()
@@ -298,7 +298,8 @@ namespace librbd {
 
   bool AbstractWrite::should_complete(int r)
   {
-    ldout(m_ictx->cct, 20) << "write " << this << " " << m_oid << " " << m_object_off << "~" << m_object_len
+    ldout(m_ictx->cct, 20) << "write " << this << " " << m_oid << " "
+                           << m_object_off << "~" << m_object_len
                           << " should_complete: r = " << r << dendl;
 
     map<uint64_t, CopyupRequest*>::iterator it;
@@ -326,48 +327,18 @@ namespace librbd {
        RWLock::RLocker l(m_ictx->snap_lock);
        RWLock::RLocker l2(m_ictx->parent_lock);
 
-       /*
-        * Parent may have disappeared; if so, recover by using
-        * send_copyup() to send the original write req (the copyup
-        * operation itself will be a no-op, since someone must have
-        * populated the child object while we weren't looking).
-        * Move to WRITE_FLAT state as we'll be done with the
-        * operation once the null copyup completes.
-        */
-
-       if (m_ictx->parent == NULL) {
-         ldout(m_ictx->cct, 20) << "parent is gone; do null copyup " << dendl;
-         m_state = LIBRBD_AIO_WRITE_FLAT;
-         send_copyup();
-         finished = false;
-         break;
-       }
-
        // If parent still exists, overlap might also have changed.
-       uint64_t parent_overlap;
-        r = m_ictx->get_parent_overlap(CEPH_NOSNAP, &parent_overlap);
-        assert(r == 0);
-
-       uint64_t newlen = m_ictx->prune_parent_extents(
-         m_object_image_extents, parent_overlap);
-
-       // copyup the entire object up to the overlap point, if any
-       if (newlen != 0) {
-         ldout(m_ictx->cct, 20) << "should_complete(" << this << ") overlap "
-                                << parent_overlap << " newlen "
-                                << newlen << " image_extents"
-                                << m_object_image_extents << dendl;
-
+       if (compute_parent_extents()) {
          m_state = LIBRBD_AIO_WRITE_COPYUP;
 
-          if (is_copy_on_read(m_ictx, m_snap_id)) {
+          if (is_copy_on_read(m_ictx, CEPH_NOSNAP)) {
             m_ictx->copyup_list_lock.Lock();
             it = m_ictx->copyup_list.find(m_object_no);
             if (it == m_ictx->copyup_list.end()) {
-              // If it is not in the list, create a CopyupRequest and wait for it.
+              // If it is not in the list, create a CopyupRequest and wait
               CopyupRequest *new_req = new CopyupRequest(m_ictx, m_oid,
                                                          m_object_no,
-                                                        m_object_image_extents);
+                                                        m_parent_extents);
               // make sure to wait on this CopyupRequest
               new_req->append_request(this);
               m_ictx->copyup_list[m_object_no] = new_req;
@@ -381,12 +352,19 @@ namespace librbd {
               m_ictx->copyup_list_lock.Unlock();
             }
           } else {
-            read_from_parent(m_object_image_extents, false);
+            read_from_parent(m_parent_extents, false);
           }
        } else {
+         /*
+          * Parent may have disappeared; if so, recover by using
+          * send_copyup() to send the original write req (the copyup
+          * operation itself will be a no-op, since someone must have
+          * populated the child object while we weren't looking).
+          * Move to WRITE_FLAT state as we'll be done with the
+          * operation once the null copyup completes.
+          */
          ldout(m_ictx->cct, 20) << "should_complete(" << this
                                 << "): parent overlap now 0" << dendl;
-         m_object_image_extents.clear();
          m_state = LIBRBD_AIO_WRITE_FLAT;
          send_copyup();
        }
@@ -430,7 +408,7 @@ namespace librbd {
     case LIBRBD_AIO_WRITE_ERROR:
       assert(r < 0);
       lderr(m_ictx->cct) << "WRITE_ERROR: " << cpp_strerror(r)
-                        << dendl; 
+                        << dendl;
       break;
 
     default:
@@ -536,7 +514,8 @@ namespace librbd {
   }
 
   void AbstractWrite::send_copyup() {
-    ldout(m_ictx->cct, 20) << "send_copyup " << this << " " << m_oid << " " << m_object_off << "~" << m_object_len << dendl;
+    ldout(m_ictx->cct, 20) << "send_copyup " << this << " " << m_oid << " "
+                           << m_object_off << "~" << m_object_len << dendl;
     librados::ObjectWriteOperation op;
     if (!m_read_data.is_zero()) {
       op.exec("rbd", "copyup", m_read_data);
index eda9a84a9c0b193d4ecd2c8aed85aae359fdbf92..29bd880d7b7bb5c7a29f4360476133f58d10e1b9 100644 (file)
@@ -27,10 +27,9 @@ namespace librbd {
   class AioRequest
   {
   public:
-    AioRequest();
     AioRequest(ImageCtx *ictx, const std::string &oid,
                uint64_t objectno, uint64_t off, uint64_t len,
-               const ::SnapContext &snapc, librados::snap_t snap_id,
+               librados::snap_t snap_id,
                Context *completion, bool hide_enoent);
     virtual ~AioRequest();
 
@@ -39,8 +38,13 @@ namespace librbd {
     virtual bool should_complete(int r) = 0;
     virtual int send() = 0;
 
+    bool has_parent() const {
+      return !m_parent_extents.empty();
+    }
+
   protected:
-    void read_from_parent(vector<pair<uint64_t,uint64_t> >& image_extents,
+    bool compute_parent_extents();
+    void read_from_parent(const vector<pair<uint64_t,uint64_t> >& image_extents,
                           bool block_completion);
 
     ImageCtx *m_ictx;
@@ -48,17 +52,17 @@ namespace librbd {
     uint64_t m_object_no, m_object_off, m_object_len;
     librados::snap_t m_snap_id;
     Context *m_completion;
+    std::vector<std::pair<uint64_t,uint64_t> > m_parent_extents;
     AioCompletion *m_parent_completion;
     ceph::bufferlist m_read_data;
     bool m_hide_enoent;
-    std::vector<librados::snap_t> m_snaps;
   };
 
   class AioRead : public AioRequest {
   public:
     AioRead(ImageCtx *ictx, const std::string &oid,
            uint64_t objectno, uint64_t offset, uint64_t len,
-           vector<pair<uint64_t,uint64_t> >& be, const ::SnapContext &snapc,
+           vector<pair<uint64_t,uint64_t> >& be,
            librados::snap_t snap_id, bool sparse,
            Context *completion, int op_flags);
     virtual ~AioRead() {}
@@ -79,7 +83,6 @@ namespace librbd {
     bool m_tried_parent;
     bool m_sparse;
     int m_op_flags;
-    vector<pair<uint64_t,uint64_t> > m_image_extents;
 
     /**
      * Reads go through the following state machine to deal with
@@ -108,22 +111,14 @@ namespace librbd {
 
   class AbstractWrite : public AioRequest {
   public:
-    AbstractWrite();
-    AbstractWrite(ImageCtx *ictx, const std::string &oid,
-                 uint64_t object_no, uint64_t object_off, uint64_t len,
-                 vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
-                 const ::SnapContext &snapc,
-                 librados::snap_t snap_id,
-                 Context *completion,
-                 bool hide_enoent);
+    AbstractWrite(ImageCtx *ictx, const std::string &oid, uint64_t object_no,
+                  uint64_t object_off, uint64_t len, const ::SnapContext &snapc,
+                 Context *completion, bool hide_enoent);
     virtual ~AbstractWrite() {}
+
     virtual bool should_complete(int r);
     virtual int send();
 
-    bool has_parent() const {
-      return !m_object_image_extents.empty();
-    }
-
   private:
     /**
      * Writes go through the following state machine to deal with
@@ -134,7 +129,7 @@ namespace librbd {
      *  .  |
      *  .  \---> LIBRBD_AIO_WRITE_PRE
      *  .           |         |
-     *  . . . . . . | . . . . | . . . . . . . . . . . 
+     *  . . . . . . | . . . . | . . . . . . . . . . .
      *      .       |   -or-  |                     .
      *      .       |         |                     v
      *      .       |         \----------------> LIBRBD_AIO_WRITE_FLAT . . .
@@ -150,7 +145,7 @@ namespace librbd {
      *  .                       LIBRBD_AIO_WRITE_POST                      .
      *  .                                |                                 .
      *  .                                v                                 .
-     *  . . . . . . . . . . . . . . > <finish> < . . . . . . . . . . . . . . 
+     *  . . . . . . . . . . . . . . > <finish> < . . . . . . . . . . . . . .
      *
      * The _PRE_REMOVE/_POST_REMOVE states are skipped if the object map
      * is disabled.  The write starts in _WRITE_GUARD or _FLAT depending on
@@ -167,10 +162,9 @@ namespace librbd {
 
   protected:
     write_state_d m_state;
-    vector<pair<uint64_t,uint64_t> > m_object_image_extents;
-    uint64_t m_parent_overlap;
     librados::ObjectWriteOperation m_write;
     uint64_t m_snap_seq;
+    std::vector<librados::snap_t> m_snaps;
     ceph::bufferlist *m_entire_object;
 
     virtual void add_write_ops(librados::ObjectWriteOperation *wr) = 0;
@@ -189,16 +183,10 @@ namespace librbd {
 
   class AioWrite : public AbstractWrite {
   public:
-    AioWrite(ImageCtx *ictx, const std::string &oid,
-            uint64_t object_no, uint64_t object_off,
-            vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
-            const ceph::bufferlist &data, const ::SnapContext &snapc,
-            librados::snap_t snap_id,
-            Context *completion)
-      : AbstractWrite(ictx, oid,
-                     object_no, object_off, data.length(),
-                     objectx, object_overlap,
-                     snapc, snap_id,
+    AioWrite(ImageCtx *ictx, const std::string &oid, uint64_t object_no,
+             uint64_t object_off, const ceph::bufferlist &data,
+             const ::SnapContext &snapc, Context *completion)
+      : AbstractWrite(ictx, oid, object_no, object_off, data.length(), snapc,
                      completion, false),
        m_write_data(data), m_op_flags(0) {
     }
@@ -220,16 +208,9 @@ namespace librbd {
 
   class AioRemove : public AbstractWrite {
   public:
-    AioRemove(ImageCtx *ictx, const std::string &oid,
-             uint64_t object_no,
-             vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
-             const ::SnapContext &snapc, librados::snap_t snap_id,
-             Context *completion)
-      : AbstractWrite(ictx, oid,
-                     object_no, 0, 0,
-                     objectx, object_overlap,
-                     snapc, snap_id, completion,
-                     true),
+    AioRemove(ImageCtx *ictx, const std::string &oid, uint64_t object_no,
+             const ::SnapContext &snapc, Context *completion)
+      : AbstractWrite(ictx, oid, object_no, 0, 0, snapc, completion, true),
         m_object_state(OBJECT_NONEXISTENT) {
     }
     virtual ~AioRemove() {}
@@ -269,16 +250,11 @@ namespace librbd {
 
   class AioTruncate : public AbstractWrite {
   public:
-    AioTruncate(ImageCtx *ictx, const std::string &oid,
-               uint64_t object_no, uint64_t object_off,
-               vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
-               const ::SnapContext &snapc, librados::snap_t snap_id,
-               Context *completion)
-      : AbstractWrite(ictx, oid,
-                     object_no, object_off, 0,
-                     objectx, object_overlap,
-                     snapc, snap_id, completion,
-                     true) {
+    AioTruncate(ImageCtx *ictx, const std::string &oid, uint64_t object_no,
+                uint64_t object_off, const ::SnapContext &snapc,
+                Context *completion)
+      : AbstractWrite(ictx, oid, object_no, object_off, 0, snapc, completion,
+                      true) {
     }
     virtual ~AioTruncate() {}
 
@@ -294,16 +270,11 @@ namespace librbd {
 
   class AioZero : public AbstractWrite {
   public:
-    AioZero(ImageCtx *ictx, const std::string &oid,
-           uint64_t object_no, uint64_t object_off, uint64_t object_len,
-           vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
-           const ::SnapContext &snapc, librados::snap_t snap_id,
-           Context *completion)
-      : AbstractWrite(ictx, oid,
-                     object_no, object_off, object_len,
-                     objectx, object_overlap,
-                     snapc, snap_id, completion,
-                     true) {
+    AioZero(ImageCtx *ictx, const std::string &oid, uint64_t object_no,
+            uint64_t object_off, uint64_t object_len,
+            const ::SnapContext &snapc, Context *completion)
+      : AbstractWrite(ictx, oid, object_no, object_off, object_len, snapc,
+                      completion, true) {
     }
     virtual ~AioZero() {}
 
index 87c2655641f4adb4abb9ff3681db69c12bd3a6f3..f6a3e154f4d9d7c07fa02cedf811950d6f22c7fb 100644 (file)
@@ -38,39 +38,17 @@ public:
       return -ERESTART;
     }
 
-    RWLock::RLocker l2(m_image_ctx.snap_lock);
-    uint64_t overlap;
-    {
-      RWLock::RLocker l3(m_image_ctx.parent_lock);
+    bufferlist bl;
+    string oid = m_image_ctx.get_object_name(m_object_no);
+    AioWrite *req = new AioWrite(&m_image_ctx, oid, m_object_no, 0, bl, m_snapc,
+                                 this);
+    if (!req->has_parent()) {
       // stop early if the parent went away - it just means
-      // another flatten finished first, so this one is useless.
-      if (!m_image_ctx.parent) {
-        return 1;
-      }
-
-      // resize might have occurred while flatten is running
-      uint64_t parent_overlap;
-      int r = m_image_ctx.get_parent_overlap(CEPH_NOSNAP, &parent_overlap);
-      assert(r == 0);
-      overlap = min(m_image_ctx.size, parent_overlap);
-    }
-
-    // map child object onto the parent
-    vector<pair<uint64_t,uint64_t> > objectx;
-    Striper::extent_to_file(cct, &m_image_ctx.layout, m_object_no,
-                           0, m_object_size, objectx);
-    uint64_t object_overlap = m_image_ctx.prune_parent_extents(objectx, overlap);
-    assert(object_overlap <= m_object_size);
-    if (object_overlap == 0) {
-      // resize shrunk image while flattening
+      // another flatten finished first or the image was resized
+      delete req;
       return 1;
     }
 
-    bufferlist bl;
-    string oid = m_image_ctx.get_object_name(m_object_no);
-    AioWrite *req = new AioWrite(&m_image_ctx, oid, m_object_no, 0, objectx,
-                                 object_overlap, bl, m_snapc, CEPH_NOSNAP,
-                                 this);
     int r = req->send();
     assert(r == 0);
     return 0;
index d3dcd8118735f24f530fb85e65104d5d9358f8bf..b474124c85c2ac74805d2322153fb41414d17f24 100644 (file)
@@ -251,14 +251,9 @@ bool AsyncTrimRequest::send_clean_boundary() {
       lost_exclusive_lock = true;
     } else {
       ::SnapContext snapc;
-      uint64_t parent_overlap;
       {
         RWLock::RLocker l2(m_image_ctx.snap_lock);
         snapc = m_image_ctx.snapc;
-
-        RWLock::RLocker l3(m_image_ctx.parent_lock);
-        int r = m_image_ctx.get_parent_overlap(CEPH_NOSNAP, &parent_overlap);
-        assert(r == 0);
       }
 
       // discard the weird boundary, if any
@@ -273,21 +268,13 @@ bool AsyncTrimRequest::send_clean_boundary() {
         ldout(cct, 20) << " ex " << *p << dendl;
         Context *req_comp = new C_ContextCompletion(*completion);
 
-        // reverse map this object extent onto the parent
-        vector<pair<uint64_t,uint64_t> > objectx;
-        Striper::extent_to_file(cct, &m_image_ctx.layout, p->objectno, 0,
-                               m_image_ctx.layout.fl_object_size, objectx);
-        uint64_t object_overlap =
-         m_image_ctx.prune_parent_extents(objectx, parent_overlap);
-
         AbstractWrite *req;
         if (p->offset == 0) {
-          req = new AioRemove(&m_image_ctx, p->oid.name, p->objectno, objectx,
-                              object_overlap, snapc, CEPH_NOSNAP, req_comp);
+          req = new AioRemove(&m_image_ctx, p->oid.name, p->objectno, snapc,
+                              req_comp);
         } else {
-          req = new AioTruncate(&m_image_ctx, p->oid.name, p->objectno, p->offset,
-                                objectx, object_overlap, snapc, CEPH_NOSNAP,
-                                req_comp);
+          req = new AioTruncate(&m_image_ctx, p->oid.name, p->objectno,
+                                p->offset, snapc, req_comp);
         }
         int r = req->send();
         if (r < 0) {
index 694f2c739da67f9bdf025925579a3542c4c7df43..cd2e1de2aa8a66bc2d5a0c2d923d0fe386178412 100644 (file)
@@ -157,30 +157,14 @@ namespace librbd {
                               uint64_t trunc_size, __u32 trunc_seq,
                               Context *oncommit)
   {
-    m_ictx->snap_lock.get_read();
-    librados::snap_t snap_id = m_ictx->snap_id;
-    m_ictx->parent_lock.get_read();
-    uint64_t overlap = 0;
-    m_ictx->get_parent_overlap(snap_id, &overlap);
-    m_ictx->parent_lock.put_read();
-    m_ictx->snap_lock.put_read();
-
     uint64_t object_no = oid_to_object_no(oid.name, m_ictx->object_prefix);
     
-    // reverse map this object extent onto the parent
-    vector<pair<uint64_t,uint64_t> > objectx;
-    Striper::extent_to_file(m_ictx->cct, &m_ictx->layout,
-                         object_no, 0, m_ictx->layout.fl_object_size,
-                         objectx);
-    uint64_t object_overlap = m_ictx->prune_parent_extents(objectx, overlap);
     write_result_d *result = new write_result_d(oid.name, oncommit);
     m_writes[oid.name].push(result);
     ldout(m_ictx->cct, 20) << "write will wait for result " << result << dendl;
     C_OrderedWrite *req_comp = new C_OrderedWrite(m_ictx->cct, result, this);
-    AioWrite *req = new AioWrite(m_ictx, oid.name,
-                                object_no, off, objectx, object_overlap,
-                                bl, snapc, snap_id,
-                                req_comp);
+    AioWrite *req = new AioWrite(m_ictx, oid.name, object_no, off, bl, snapc,
+                                 req_comp);
     req->send();
     return ++m_tid;
   }
index 64879a034fb1ea0773a78ccce1aa496dc235e1a7..48c423867d24aa583d3c40940e194dccca8948a2 100644 (file)
@@ -3447,29 +3447,21 @@ reprotect_and_return_err:
     RWLock::RLocker md_locker(ictx->md_lock);
 
     uint64_t clip_len = len;
-    snapid_t snap_id;
     ::SnapContext snapc;
-    uint64_t overlap = 0;
     {
       // prevent image size from changing between computing clip and recording
       // pending async operation
       RWLock::RLocker snap_locker(ictx->snap_lock);
+      if (ictx->snap_id != CEPH_NOSNAP || ictx->read_only) {
+        return -EROFS;
+      }
+
       r = clip_io(ictx, off, &clip_len);
       if (r < 0) {
         return r;
       }
 
-      snap_id = ictx->snap_id;
       snapc = ictx->snapc;
-      ictx->parent_lock.get_read();
-      ictx->get_parent_overlap(ictx->snap_id, &overlap);
-      ictx->parent_lock.put_read();
-
-      if (snap_id != CEPH_NOSNAP || ictx->read_only) {
-        return -EROFS;
-      }
-
-      ldout(cct, 20) << "  parent overlap " << overlap << dendl;
 
       c->get();
       c->init_time(ictx, AIO_TYPE_WRITE);
@@ -3505,16 +3497,8 @@ reprotect_and_return_err:
        c->add_request();
        ictx->write_to_cache(p->oid, bl, p->length, p->offset, req_comp, op_flags);
       } else {
-       // reverse map this object extent onto the parent
-       vector<pair<uint64_t,uint64_t> > objectx;
-       Striper::extent_to_file(ictx->cct, &ictx->layout,
-                             p->objectno, 0, ictx->layout.fl_object_size,
-                             objectx);
-       uint64_t object_overlap = ictx->prune_parent_extents(objectx, overlap);
-
        AioWrite *req = new AioWrite(ictx, p->oid.name, p->objectno, p->offset,
-                                    objectx, object_overlap,
-                                    bl, snapc, snap_id, req_comp);
+                                    bl, snapc, req_comp);
        c->add_request();
 
        req->set_op_flags(op_flags);
@@ -3603,28 +3587,22 @@ reprotect_and_return_err:
     RWLock::RLocker md_locker(ictx->md_lock);
 
     uint64_t clip_len = len;
-    snapid_t snap_id;
     ::SnapContext snapc;
-    uint64_t overlap;
     {
       // prevent image size from changing between computing clip and recording
       // pending async operation
       RWLock::RLocker snap_locker(ictx->snap_lock);
+      if (ictx->snap_id != CEPH_NOSNAP || ictx->read_only) {
+        return -EROFS;
+      }
+
       r = clip_io(ictx, off, &clip_len);
       if (r < 0) {
         return r;
       }
 
       // TODO: check for snap
-      snap_id = ictx->snap_id;
       snapc = ictx->snapc;
-      ictx->parent_lock.get_read();
-      ictx->get_parent_overlap(ictx->snap_id, &overlap);
-      ictx->parent_lock.put_read();
-
-      if (snap_id != CEPH_NOSNAP || ictx->read_only) {
-        return -EROFS;
-      }
 
       c->get();
       c->init_time(ictx, AIO_TYPE_DISCARD);
@@ -3651,30 +3629,17 @@ reprotect_and_return_err:
       AbstractWrite *req;
       c->add_request();
 
-      // reverse map this object extent onto the parent
-      vector<pair<uint64_t,uint64_t> > objectx;
-      uint64_t object_overlap = 0;
-      if (off < overlap) {   // we might overlap...
-       Striper::extent_to_file(ictx->cct, &ictx->layout,
-                             p->objectno, 0, ictx->layout.fl_object_size,
-                             objectx);
-       object_overlap = ictx->prune_parent_extents(objectx, overlap);
-      }
-
       if (p->offset == 0 && p->length == ictx->layout.fl_object_size) {
-       req = new AioRemove(ictx, p->oid.name, p->objectno, objectx, object_overlap,
-                           snapc, snap_id, req_comp);
+       req = new AioRemove(ictx, p->oid.name, p->objectno, snapc, req_comp);
       } else if (p->offset + p->length == ictx->layout.fl_object_size) {
-       req = new AioTruncate(ictx, p->oid.name, p->objectno, p->offset, objectx, object_overlap,
-                             snapc, snap_id, req_comp);
+       req = new AioTruncate(ictx, p->oid.name, p->objectno, p->offset, snapc,
+                              req_comp);
       } else {
        if(ictx->cct->_conf->rbd_skip_partial_discard) {
          continue;
-       } else {
-         req = new AioZero(ictx, p->oid.name, p->objectno, p->offset, p->length,
-                           objectx, object_overlap,
-                           snapc, snap_id, req_comp);
        }
+       req = new AioZero(ictx, p->oid.name, p->objectno, p->offset, p->length,
+                         snapc, req_comp);
       }
 
       r = req->send();
@@ -3791,7 +3756,6 @@ reprotect_and_return_err:
     }
 
     snap_t snap_id;
-    ::SnapContext snapc;
     map<object_t,vector<ObjectExtent> > object_extents;
     uint64_t buffer_ofs = 0;
     {
@@ -3799,7 +3763,6 @@ reprotect_and_return_err:
       // pending async operation
       RWLock::RLocker snap_locker(ictx->snap_lock);
       snap_id = ictx->snap_id;
-      snapc = ictx->snapc;
 
       // map
       for (vector<pair<uint64_t,uint64_t> >::const_iterator p =
@@ -3828,16 +3791,18 @@ reprotect_and_return_err:
     c->read_buf_len = buffer_ofs;
     c->read_bl = pbl;
 
-    for (map<object_t,vector<ObjectExtent> >::iterator p = object_extents.begin(); p != object_extents.end(); ++p) {
-      for (vector<ObjectExtent>::iterator q = p->second.begin(); q != p->second.end(); ++q) {
-       ldout(ictx->cct, 20) << " oid " << q->oid << " " << q->offset << "~" << q->length
-                            << " from " << q->buffer_extents << dendl;
+    for (map<object_t,vector<ObjectExtent> >::iterator p = object_extents.begin();
+         p != object_extents.end(); ++p) {
+      for (vector<ObjectExtent>::iterator q = p->second.begin();
+           q != p->second.end(); ++q) {
+       ldout(ictx->cct, 20) << " oid " << q->oid << " " << q->offset << "~"
+                             << q->length << " from " << q->buffer_extents
+                             << dendl;
 
        C_AioRead *req_comp = new C_AioRead(ictx->cct, c);
-       AioRead *req = new AioRead(ictx, q->oid.name, 
-                                  q->objectno, q->offset, q->length,
-                                  q->buffer_extents, snapc,
-                                  snap_id, true, req_comp, op_flags);
+       AioRead *req = new AioRead(ictx, q->oid.name, q->objectno, q->offset,
+                                   q->length, q->buffer_extents, snap_id, true,
+                                   req_comp, op_flags);
        req_comp->set_req(req);
        c->add_request();