]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: journal replay should no-op out-of-bounds IO
authorJason Dillaman <dillaman@redhat.com>
Tue, 15 May 2018 19:55:04 +0000 (15:55 -0400)
committerJason Dillaman <dillaman@redhat.com>
Sat, 19 May 2018 12:17:14 +0000 (08:17 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 9a1fcef5edbfdfc77293c4b60c9e038db49abf1f)

src/librbd/journal/Replay.cc
src/librbd/journal/Replay.h

index 2f33ab5e915ff630c74688f852383816b4567fc2..bd4942ad2f6b2f123488eb56703c5ba52bdaaf91 100644 (file)
@@ -350,9 +350,12 @@ void Replay<I>::handle_event(const journal::AioDiscardEvent &event,
     return;
   }
 
-  io::ImageRequest<I>::aio_discard(&m_image_ctx, aio_comp,
-                                   {{event.offset, event.length}},
-                                   event.skip_partial_discard, {});
+  if (!clipped_io(event.offset, aio_comp)) {
+    io::ImageRequest<I>::aio_discard(&m_image_ctx, aio_comp,
+                                     {{event.offset, event.length}},
+                                     event.skip_partial_discard, {});
+  }
+
   if (flush_required) {
     m_lock.Lock();
     auto flush_comp = create_aio_flush_completion(nullptr);
@@ -381,9 +384,12 @@ void Replay<I>::handle_event(const journal::AioWriteEvent &event,
     return;
   }
 
-  io::ImageRequest<I>::aio_write(&m_image_ctx, aio_comp,
-                                 {{event.offset, event.length}},
-                                 std::move(data), 0, {});
+  if (!clipped_io(event.offset, aio_comp)) {
+    io::ImageRequest<I>::aio_write(&m_image_ctx, aio_comp,
+                                   {{event.offset, event.length}},
+                                   std::move(data), 0, {});
+  }
+
   if (flush_required) {
     m_lock.Lock();
     auto flush_comp = create_aio_flush_completion(nullptr);
@@ -431,9 +437,12 @@ void Replay<I>::handle_event(const journal::AioWriteSameEvent &event,
     return;
   }
 
-  io::ImageRequest<I>::aio_writesame(&m_image_ctx, aio_comp,
-                                     {{event.offset, event.length}},
-                                     std::move(data), 0, {});
+  if (!clipped_io(event.offset, aio_comp)) {
+    io::ImageRequest<I>::aio_writesame(&m_image_ctx, aio_comp,
+                                       {{event.offset, event.length}},
+                                       std::move(data), 0, {});
+  }
+
   if (flush_required) {
     m_lock.Lock();
     auto flush_comp = create_aio_flush_completion(nullptr);
@@ -459,11 +468,15 @@ void Replay<I>::handle_event(const journal::AioWriteSameEvent &event,
                                                io::AIO_TYPE_COMPARE_AND_WRITE,
                                                &flush_required,
                                                {-EILSEQ});
-  io::ImageRequest<I>::aio_compare_and_write(&m_image_ctx, aio_comp,
-                                             {{event.offset, event.length}},
-                                             std::move(cmp_data),
-                                             std::move(write_data),
-                                             nullptr, 0, {});
+
+  if (!clipped_io(event.offset, aio_comp)) {
+    io::ImageRequest<I>::aio_compare_and_write(&m_image_ctx, aio_comp,
+                                               {{event.offset, event.length}},
+                                               std::move(cmp_data),
+                                               std::move(write_data),
+                                               nullptr, 0, {});
+  }
+
   if (flush_required) {
     m_lock.Lock();
     auto flush_comp = create_aio_flush_completion(nullptr);
@@ -1126,6 +1139,29 @@ io::AioCompletion *Replay<I>::create_aio_flush_completion(Context *on_safe) {
   return aio_comp;
 }
 
+template <typename I>
+bool Replay<I>::clipped_io(uint64_t image_offset, io::AioCompletion *aio_comp) {
+  CephContext *cct = m_image_ctx.cct;
+
+  m_image_ctx.snap_lock.get_read();
+  size_t image_size = m_image_ctx.size;
+  m_image_ctx.snap_lock.put_read();
+
+  if (image_offset >= image_size) {
+    // rbd-mirror image sync might race an IO event w/ associated resize between
+    // the point the peer is registered and the sync point is created, so no-op
+    // IO events beyond the current image extents since under normal conditions
+    // it wouldn't have been recorded in the journal
+    ldout(cct, 5) << ": no-op IO event beyond image size" << dendl;
+    aio_comp->get();
+    aio_comp->unblock();
+    aio_comp->put();
+    return true;
+  }
+
+  return false;
+}
+
 } // namespace journal
 } // namespace librbd
 
index 4a4260cb9f00d8d30c5b464bb2c5620fa444f9cd..3851ab49d2cddb22c61b9187b04824b3336e4837 100644 (file)
@@ -193,6 +193,8 @@ private:
   io::AioCompletion *create_aio_flush_completion(Context *on_safe);
   void handle_aio_completion(io::AioCompletion *aio_comp);
 
+  bool clipped_io(uint64_t image_offset, io::AioCompletion *aio_comp);
+
 };
 
 } // namespace journal