]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/librbd.cc
import ceph quincy 17.2.6
[ceph.git] / ceph / src / librbd / librbd.cc
index 28bb2449d75208cde7f4453e53f6e0a13ead002f..2fba85ebdc07e4eac103ba7b02957ea0c1390eba 100644 (file)
@@ -2674,8 +2674,8 @@ namespace librbd {
                ictx->read_only, ofs, len, cmp_bl.length() < len ? NULL : cmp_bl.c_str(),
                bl.length() < len ? NULL : bl.c_str(), op_flags);
 
-    if (bl.length() < len) {
-      tracepoint(librbd, write_exit, -EINVAL);
+    if (bl.length() < len || cmp_bl.length() < len) {
+      tracepoint(librbd, compare_and_write_exit, -EINVAL);
       return -EINVAL;
     }
 
@@ -2825,8 +2825,8 @@ namespace librbd {
                ictx->read_only, off, len, cmp_bl.length() < len ? NULL : cmp_bl.c_str(),
                bl.length() < len ? NULL : bl.c_str(), c->pc, op_flags);
 
-    if (bl.length() < len) {
-      tracepoint(librbd, compare_and_write_exit, -EINVAL);
+    if (bl.length() < len || cmp_bl.length() < len) {
+      tracepoint(librbd, aio_compare_and_write_exit, -EINVAL);
       return -EINVAL;
     }
 
@@ -6352,6 +6352,52 @@ extern "C" ssize_t rbd_aio_compare_and_write(rbd_image_t image, uint64_t off,
   return 0;
 }
 
+extern "C" ssize_t rbd_aio_compare_and_writev(rbd_image_t image,
+                                              uint64_t off,
+                                              const struct iovec *cmp_iov,
+                                              int cmp_iovcnt,
+                                              const struct iovec *iov,
+                                              int iovcnt,
+                                              rbd_completion_t c,
+                                              uint64_t *mismatch_off,
+                                              int op_flags)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
+
+  size_t cmp_len;
+  int r = get_iovec_length(cmp_iov, cmp_iovcnt, cmp_len);
+
+  tracepoint(librbd, aio_compare_and_write_enter, ictx, ictx->name.c_str(),
+             ictx->snap_name.c_str(), ictx->read_only, off, cmp_len, NULL, NULL,
+             comp->pc, op_flags);
+  if (r != 0) {
+    tracepoint(librbd, aio_compare_and_write_exit, r);
+    return r;
+  }
+
+  size_t write_len;
+  r = get_iovec_length(iov, iovcnt, write_len);
+  if (r != 0) {
+    tracepoint(librbd, aio_compare_and_write_exit, r);
+    return r;
+  }
+  if (cmp_len != write_len) {
+    tracepoint(librbd, aio_compare_and_write_exit, -EINVAL);
+    return -EINVAL;
+  }
+
+  auto aio_completion = get_aio_completion(comp);
+  auto cmp_bl = iovec_to_bufferlist(ictx, cmp_iov, cmp_iovcnt, aio_completion);
+  auto bl = iovec_to_bufferlist(ictx, iov, iovcnt, aio_completion);
+  librbd::api::Io<>::aio_compare_and_write(*ictx, aio_completion, off, cmp_len,
+                                           std::move(cmp_bl), std::move(bl),
+                                           mismatch_off, op_flags, false);
+
+  tracepoint(librbd, aio_compare_and_write_exit, 0);
+  return 0;
+}
+
 extern "C" int rbd_invalidate_cache(rbd_image_t image)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;