]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/Journal.cc
import ceph quincy 17.2.6
[ceph.git] / ceph / src / librbd / Journal.cc
index 0cd38b22adaa9ee29b0f3bc17f82ebbc0c3e3e06..8ddce2e8f7d4f4b476d5886d2135c38007b988f1 100644 (file)
@@ -792,6 +792,49 @@ uint64_t Journal<I>::append_write_event(uint64_t offset, size_t length,
                           length, flush_entry, 0);
 }
 
+template <typename I>
+uint64_t Journal<I>::append_compare_and_write_event(uint64_t offset,
+                                                    size_t length,
+                                                    const bufferlist &cmp_bl,
+                                                    const bufferlist &write_bl,
+                                                    bool flush_entry) {
+  ceph_assert(
+    m_max_append_size > journal::AioCompareAndWriteEvent::get_fixed_size());
+  uint64_t max_compare_and_write_data_size =
+    m_max_append_size - journal::AioCompareAndWriteEvent::get_fixed_size();
+  // we need double the size because we store cmp and write buffers
+  max_compare_and_write_data_size /= 2;
+
+  // ensure that the compare and write event fits within the journal entry
+  Bufferlists bufferlists;
+  uint64_t bytes_remaining = length;
+  uint64_t event_offset = 0;
+  do {
+    uint64_t event_length = std::min(bytes_remaining,
+                                     max_compare_and_write_data_size);
+
+    bufferlist event_cmp_bl;
+    event_cmp_bl.substr_of(cmp_bl, event_offset, event_length);
+    bufferlist event_write_bl;
+    event_write_bl.substr_of(write_bl, event_offset, event_length);
+    journal::EventEntry event_entry(
+      journal::AioCompareAndWriteEvent(offset + event_offset,
+                                       event_length,
+                                       event_cmp_bl,
+                                       event_write_bl),
+      ceph_clock_now());
+
+    bufferlists.emplace_back();
+    encode(event_entry, bufferlists.back());
+
+    event_offset += event_length;
+    bytes_remaining -= event_length;
+  } while (bytes_remaining > 0);
+
+  return append_io_events(journal::EVENT_TYPE_AIO_COMPARE_AND_WRITE,
+                          bufferlists, offset, length, flush_entry, -EILSEQ);
+}
+
 template <typename I>
 uint64_t Journal<I>::append_io_event(journal::EventEntry &&event_entry,
                                      uint64_t offset, size_t length,