]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add compare_and_write/aio_compare_and_write API
authorwangzhengyong <wangzhengyong@cmss.chinamobile.com>
Mon, 12 Jun 2017 13:18:29 +0000 (21:18 +0800)
committerJason Dillaman <dillaman@redhat.com>
Wed, 26 Jul 2017 12:00:06 +0000 (08:00 -0400)
Signed-off-by: Zhengyong Wang <wangzhengyong@cmss.chinamobile.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/io/AioCompletion.cc
src/librbd/librbd.cc
src/tracing/librbd.tp

index dca8f42370413a6c0b56f5afcea611a1e85d1a21..9a21c4af5daaaac8756b2988b0a526bf7b07b1a0 100644 (file)
@@ -701,6 +701,11 @@ CEPH_RBD_API ssize_t rbd_write2(rbd_image_t image, uint64_t ofs, size_t len,
 CEPH_RBD_API int rbd_discard(rbd_image_t image, uint64_t ofs, uint64_t len);
 CEPH_RBD_API ssize_t rbd_writesame(rbd_image_t image, uint64_t ofs, size_t len,
                                    const char *buf, size_t data_len, int op_flags);
+CEPH_RBD_API ssize_t rbd_compare_and_write(rbd_image_t image, uint64_t ofs,
+                                           size_t len, const char *cmp_buf,
+                                           const char *buf, uint64_t *mismatch_off,
+                                           int op_flags);
+
 CEPH_RBD_API int rbd_aio_write(rbd_image_t image, uint64_t off, size_t len,
                                const char *buf, rbd_completion_t c);
 
@@ -726,6 +731,11 @@ CEPH_RBD_API int rbd_aio_discard(rbd_image_t image, uint64_t off, uint64_t len,
 CEPH_RBD_API int rbd_aio_writesame(rbd_image_t image, uint64_t off, size_t len,
                                    const char *buf, size_t data_len,
                                    rbd_completion_t c, int op_flags);
+CEPH_RBD_API ssize_t rbd_aio_compare_and_write(rbd_image_t image,
+                                               uint64_t off, size_t len,
+                                               const char *cmp_buf, const char *buf,
+                                               rbd_completion_t c, uint64_t *mismatch_off,
+                                               int op_flags);
 
 CEPH_RBD_API int rbd_aio_create_completion(void *cb_arg,
                                            rbd_callback_t complete_cb,
index b8e74569205318816553eeb00b53c22e68f3a638..bbf4270bc245d7b13bd1eb4a5700acc3eccf7054 100644 (file)
@@ -376,6 +376,8 @@ public:
   ssize_t write2(uint64_t ofs, size_t len, ceph::bufferlist& bl, int op_flags);
   int discard(uint64_t ofs, uint64_t len);
   ssize_t writesame(uint64_t ofs, size_t len, ceph::bufferlist &bl, int op_flags);
+  ssize_t compare_and_write(uint64_t ofs, size_t len, ceph::bufferlist &cmp_bl,
+                            ceph::bufferlist& bl, uint64_t *mismatch_off, int op_flags);
 
   int aio_write(uint64_t off, size_t len, ceph::bufferlist& bl, RBD::AioCompletion *c);
   /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
@@ -383,6 +385,9 @@ public:
                  RBD::AioCompletion *c, int op_flags);
   int aio_writesame(uint64_t off, size_t len, ceph::bufferlist& bl,
                     RBD::AioCompletion *c, int op_flags);
+  int aio_compare_and_write(uint64_t off, size_t len, ceph::bufferlist& cmp_bl,
+                            ceph::bufferlist& bl, RBD::AioCompletion *c,
+                            uint64_t *mismatch_off, int op_flags);
   /**
    * read async from image
    *
index cc40e8ffbe1af53ad7a9a3e958ebe6b7eafa8239..1dc6280959c2e261c7505374088da5bc98adec52 100644 (file)
@@ -74,6 +74,8 @@ void AioCompletion::complete() {
     ictx->perfcounter->tinc(l_librbd_aio_flush_latency, elapsed); break;
   case AIO_TYPE_WRITESAME:
     ictx->perfcounter->tinc(l_librbd_ws_latency, elapsed); break;
+  case AIO_TYPE_COMPARE_AND_WRITE:
+    ictx->perfcounter->tinc(l_librbd_cmp_latency, elapsed); break;
   default:
     lderr(cct) << "completed invalid aio_type: " << aio_type << dendl;
     break;
index 1d5920fccb3087ee81f6472c48effb0c000472db..542dd28ab38d1c9a079299920fcd85bf07676358 100644 (file)
@@ -1636,6 +1636,29 @@ namespace librbd {
     return r;
   }
 
+  ssize_t Image::compare_and_write(uint64_t ofs, size_t len,
+                                   ceph::bufferlist &cmp_bl, ceph::bufferlist& bl,
+                                   uint64_t *mismatch_off, int op_flags)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    tracepoint(librbd, compare_and_write_enter, ictx, ictx->name.c_str(),
+               ictx->snap_name.c_str(),
+               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);
+      return -EINVAL;
+    }
+
+    int r = ictx->io_work_queue->compare_and_write(ofs, len, bufferlist{cmp_bl},
+                                                   bufferlist{bl}, mismatch_off,
+                                                   op_flags);
+
+    tracepoint(librbd, compare_and_write_exit, r);
+
+    return r;
+  }
   int Image::aio_write(uint64_t off, size_t len, bufferlist& bl,
                       RBD::AioCompletion *c)
   {
@@ -1745,6 +1768,30 @@ namespace librbd {
     return 0;
   }
 
+  int Image::aio_compare_and_write(uint64_t off, size_t len,
+                                   ceph::bufferlist& cmp_bl, ceph::bufferlist& bl,
+                                   RBD::AioCompletion *c, uint64_t *mismatch_off,
+                                   int op_flags)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    tracepoint(librbd, aio_compare_and_write_enter, ictx, ictx->name.c_str(),
+               ictx->snap_name.c_str(),
+               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);
+      return -EINVAL;
+    }
+
+    ictx->io_work_queue->aio_compare_and_write(get_aio_completion(c), off, len,
+                                               bufferlist{cmp_bl}, bufferlist{bl},
+                                               mismatch_off, op_flags, false);
+
+    tracepoint(librbd, aio_compare_and_write_exit, 0);
+
+    return 0;
+  }
 
   int Image::invalidate_cache()
   {
@@ -3547,6 +3594,30 @@ extern "C" ssize_t rbd_writesame(rbd_image_t image, uint64_t ofs, size_t len,
   return r;
 }
 
+extern "C" ssize_t rbd_compare_and_write(rbd_image_t image,
+                                         uint64_t ofs, size_t len,
+                                         const char *cmp_buf,
+                                         const char *buf,
+                                         uint64_t *mismatch_off,
+                                         int op_flags)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  tracepoint(librbd, compare_and_write_enter, ictx, ictx->name.c_str(),
+             ictx->snap_name.c_str(), ictx->read_only, ofs,
+             len, cmp_buf, buf, op_flags);
+
+  bufferlist cmp_bl;
+  cmp_bl.push_back(create_write_raw(ictx, cmp_buf, len));
+  bufferlist bl;
+  bl.push_back(create_write_raw(ictx, buf, len));
+
+  int r = ictx->io_work_queue->compare_and_write(ofs, len, std::move(cmp_bl),
+                                                 std::move(bl), mismatch_off,
+                                                 op_flags);
+  tracepoint(librbd, compare_and_write_exit, r);
+  return r;
+}
+
 extern "C" int rbd_aio_create_completion(void *cb_arg,
                                         rbd_callback_t complete_cb,
                                         rbd_completion_t *c)
@@ -3745,6 +3816,29 @@ extern "C" int rbd_aio_writesame(rbd_image_t image, uint64_t off, size_t len,
   return 0;
 }
 
+extern "C" ssize_t rbd_aio_compare_and_write(rbd_image_t image, uint64_t off,
+                                             size_t len, const char *cmp_buf,
+                                             const char *buf, 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;
+  tracepoint(librbd, aio_compare_and_write_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(),
+             ictx->read_only, off, len, cmp_buf, buf, comp->pc, op_flags);
+
+  bufferlist cmp_bl;
+  cmp_bl.push_back(create_write_raw(ictx, cmp_buf, len));
+  bufferlist bl;
+  bl.push_back(create_write_raw(ictx, buf, len));
+  ictx->io_work_queue->aio_compare_and_write(get_aio_completion(comp), off, 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;
index f8c77142a784254f59686992bc3a013ac7709623..5b8d3966131448848a13f1e7bd661ac46d2be18f 100644 (file)
@@ -204,6 +204,37 @@ TRACEPOINT_EVENT(librbd, writesame_exit,
     )
 )
 
+TRACEPOINT_EVENT(librbd, compare_and_write_enter,
+    TP_ARGS(
+        void*, imagectx,
+        const char*, name,
+        const char*, snap_name,
+        char, read_only,
+        uint64_t, off,
+        size_t, len,
+        const char*, cmp_buf,
+        const char*, buf,
+       int, op_flags),
+    TP_FIELDS(
+        ctf_integer_hex(void*, imagectx, imagectx)
+        ctf_string(name, name)
+        ctf_string(snap_name, snap_name)
+        ctf_integer(char, read_only, read_only)
+        ctf_integer(uint64_t, off, off)
+        ceph_ctf_sequence(unsigned char, cmp_buf, cmp_buf, size_t, len)
+        ceph_ctf_sequence(unsigned char, buf, buf, size_t, len)
+        ctf_integer(int, op_flags, op_flags)
+    )
+)
+
+TRACEPOINT_EVENT(librbd, compare_and_write_exit,
+    TP_ARGS(
+        ssize_t, retval),
+    TP_FIELDS(
+        ctf_integer(ssize_t, retval, retval)
+    )
+)
+
 TRACEPOINT_EVENT(librbd, open_image_by_id_enter,
     TP_ARGS(
         void*, imagectx,
@@ -1159,6 +1190,40 @@ TRACEPOINT_EVENT(librbd, aio_writesame_exit,
     )
 )
 
+TRACEPOINT_EVENT(librbd, aio_compare_and_write_enter,
+    TP_ARGS(
+        void*, imagectx,
+        const char*, name,
+        const char*, snap_name,
+        char, read_only,
+        uint64_t, off,
+        size_t, len,
+        const char*, cmp_buf,
+        const char*, buf,
+        const void*, completion,
+             int, op_flags),
+    TP_FIELDS(
+        ctf_integer_hex(void*, imagectx, imagectx)
+        ctf_string(name, name)
+        ctf_string(snap_name, snap_name)
+        ctf_integer(char, read_only, read_only)
+        ctf_integer(uint64_t, off, off)
+        ctf_integer(size_t, len, len)
+        ceph_ctf_sequence(unsigned char, cmp_buf, cmp_buf, size_t, len)
+        ceph_ctf_sequence(unsigned char, buf, buf, size_t, len)
+        ctf_integer_hex(const void*, completion, completion)
+        ctf_integer(int, op_flags, op_flags)
+    )
+)
+TRACEPOINT_EVENT(librbd, aio_compare_and_write_exit,
+    TP_ARGS(
+        int, retval),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+    )
+)
+
+
 TRACEPOINT_EVENT(librbd, clone_enter,
     TP_ARGS(
         const char*, parent_pool_name,