]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/io/ImageRequestWQ.cc
import 15.2.5
[ceph.git] / ceph / src / librbd / io / ImageRequestWQ.cc
index 2d21418428196da2d04046c8fa9996bfcd447b04..94dd982180f27489f887560edc35547db250b9eb 100644 (file)
@@ -212,6 +212,32 @@ ssize_t ImageRequestWQ<I>::writesame(uint64_t off, uint64_t len,
   return len;
 }
 
+template <typename I>
+ssize_t ImageRequestWQ<I>::write_zeroes(uint64_t off, uint64_t len,
+                                        int zero_flags, int op_flags) {
+  auto cct = m_image_ctx.cct;
+  ldout(cct, 20) << "ictx=" << &m_image_ctx << ", off=" << off << ", "
+                 << "len = " << len << dendl;
+
+  m_image_ctx.image_lock.lock_shared();
+  int r = clip_io(util::get_image_ctx(&m_image_ctx), off, &len);
+  m_image_ctx.image_lock.unlock_shared();
+  if (r < 0) {
+    lderr(cct) << "invalid IO request: " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  C_SaferCond ctx;
+  auto aio_comp = io::AioCompletion::create(&ctx);
+  aio_write_zeroes(aio_comp, off, len, zero_flags, op_flags, false);
+
+  r = ctx.wait();
+  if (r < 0) {
+    return r;
+  }
+  return len;
+}
+
 template <typename I>
 ssize_t ImageRequestWQ<I>::compare_and_write(uint64_t off, uint64_t len,
                                              bufferlist &&cmp_bl,
@@ -486,6 +512,62 @@ void ImageRequestWQ<I>::aio_writesame(AioCompletion *c, uint64_t off,
   trace.event("finish");
 }
 
+
+template <typename I>
+void ImageRequestWQ<I>::aio_write_zeroes(io::AioCompletion *aio_comp,
+                                         uint64_t off, uint64_t len,
+                                         int zero_flags, int op_flags,
+                                         bool native_async) {
+  auto cct = m_image_ctx.cct;
+  FUNCTRACE(cct);
+  ZTracer::Trace trace;
+  if (m_image_ctx.blkin_trace_all) {
+    trace.init("io: write_zeroes", &m_image_ctx.trace_endpoint);
+    trace.event("init");
+  }
+
+  aio_comp->init_time(util::get_image_ctx(&m_image_ctx), io::AIO_TYPE_DISCARD);
+  ldout(cct, 20) << "ictx=" << &m_image_ctx << ", "
+                 << "completion=" << aio_comp << ", off=" << off << ", "
+                 << "len=" << len << dendl;
+
+  if (native_async && m_image_ctx.event_socket.is_valid()) {
+    aio_comp->set_event_notify(true);
+  }
+
+  // validate the supported flags
+  if (zero_flags != 0U) {
+    aio_comp->fail(-EINVAL);
+    return;
+  }
+
+  if (!start_in_flight_io(aio_comp)) {
+    return;
+  }
+
+  // enable partial discard (zeroing) of objects
+  uint32_t discard_granularity_bytes = 0;
+
+  auto tid = ++m_last_tid;
+
+  {
+    std::lock_guard locker{m_lock};
+    m_queued_or_blocked_io_tids.insert(tid);
+  }
+
+  auto req = ImageDispatchSpec<I>::create_discard_request(
+    m_image_ctx, aio_comp, off, len, discard_granularity_bytes, trace, tid);
+
+  std::shared_lock owner_locker{m_image_ctx.owner_lock};
+  if (m_image_ctx.non_blocking_aio || writes_blocked()) {
+    queue(req);
+  } else {
+    process_io(req, false);
+    finish_in_flight_io();
+  }
+  trace.event("finish");
+}
+
 template <typename I>
 void ImageRequestWQ<I>::aio_compare_and_write(AioCompletion *c,
                                               uint64_t off, uint64_t len,