]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: expose rados_{read|write}_op_assert_version() in C
authorKim Vandry <vandry@TZoNE.ORG>
Sat, 31 Jan 2015 06:00:31 +0000 (15:00 +0900)
committerKim Vandry <vandry@TZoNE.ORG>
Sat, 31 Jan 2015 06:00:31 +0000 (15:00 +0900)
Previously, assert_version was only available in the C++ interface.

Signed-off-by: Kim Vandry <vandry@TZoNE.ORG>
src/include/rados/librados.h
src/librados/librados.cc
src/test/librados/c_read_operations.cc
src/test/librados/c_write_operations.cc

index 67113dd3471813fac86aa9a380a581f3bbb6e576..745aa978f9f25d13a8cbbc12e8f0bc365460bcd3 100644 (file)
@@ -261,6 +261,8 @@ struct rados_cluster_stat_t {
  * - Object map key/value pairs: rados_write_op_omap_set(),
  *   rados_write_op_omap_rm_keys(), rados_write_op_omap_clear(),
  *   rados_write_op_omap_cmp()
+ * - Object properties: rados_write_op_assert_exists(),
+ *   rados_write_op_assert_version()
  * - Creating objects: rados_write_op_create()
  * - IO on objects: rados_write_op_append(), rados_write_op_write(), rados_write_op_zero
  *   rados_write_op_write_full(), rados_write_op_remove, rados_write_op_truncate(),
@@ -281,7 +283,8 @@ typedef void *rados_write_op_t;
  * - Object map key/value pairs: rados_read_op_omap_get_vals(),
  *   rados_read_op_omap_get_keys(), rados_read_op_omap_get_vals_by_keys(),
  *   rados_read_op_omap_cmp()
- * - Object properties: rados_read_op_stat(), rados_read_op_assert_exists()
+ * - Object properties: rados_read_op_stat(), rados_read_op_assert_exists(),
+ *   rados_read_op_assert_version()
  * - IO on objects: rados_read_op_read()
  * - Custom operations: rados_read_op_exec(), rados_read_op_exec_user_buf()
  * - Request properties: rados_read_op_set_flags()
@@ -2204,6 +2207,21 @@ CEPH_RADOS_API void rados_write_op_set_flags(rados_write_op_t write_op,
  */
 CEPH_RADOS_API void rados_write_op_assert_exists(rados_write_op_t write_op);
 
+/**
+ * Ensure that the object exists and that its internal version
+ * number is equal to "ver" before writing. "ver" should be a
+ * version number previously obtained with rados_get_last_version().
+ * - If the object's version is greater than the asserted version
+ *   then rados_write_op_operate will return -ERANGE instead of
+ *   executing the op.
+ * - If the object's version is less than the asserted version
+ *   then rados_write_op_operate will return -EOVERFLOW instead
+ *   of executing the op.
+ * @param write_op operation to add this action to
+ * @param ver object version number
+ */
+CEPH_RADOS_API void rados_write_op_assert_version(rados_write_op_t write_op, uint64_t ver);
+
 /**
  * Ensure that given xattr satisfies comparison.
  * If the comparison is not satisfied, the return code of the
@@ -2448,6 +2466,21 @@ CEPH_RADOS_API void rados_read_op_set_flags(rados_read_op_t read_op, int flags);
  */
 CEPH_RADOS_API void rados_read_op_assert_exists(rados_read_op_t read_op);
 
+/**
+ * Ensure that the object exists and that its internal version
+ * number is equal to "ver" before reading. "ver" should be a
+ * version number previously obtained with rados_get_last_version().
+ * - If the object's version is greater than the asserted version
+ *   then rados_read_op_operate will return -ERANGE instead of
+ *   executing the op.
+ * - If the object's version is less than the asserted version
+ *   then rados_read_op_operate will return -EOVERFLOW instead
+ *   of executing the op.
+ * @param read_op operation to add this action to
+ * @param ver object version number
+ */
+CEPH_RADOS_API void rados_read_op_assert_version(rados_read_op_t write_op, uint64_t ver);
+
 /**
  * Ensure that the an xattr satisfies a comparison
  * If the comparison is not satisfied, the return code of the
index bdcc4c3736938804a2f65c56c6e53c82297e8bb6..2cdb8b4fdaba505af25016bf22975824a79afaee 100644 (file)
@@ -4125,6 +4125,13 @@ extern "C" void rados_write_op_set_flags(rados_write_op_t write_op, int flags)
   tracepoint(librados, rados_write_op_set_flags_exit);
 }
 
+extern "C" void rados_write_op_assert_version(rados_write_op_t write_op, uint64_t ver)
+{
+  tracepoint(librados, rados_write_op_assert_version_enter, write_op);
+  ((::ObjectOperation *)write_op)->assert_version(ver);
+  tracepoint(librados, rados_write_op_assert_version_exit);
+}
+
 extern "C" void rados_write_op_assert_exists(rados_write_op_t write_op)
 {
   tracepoint(librados, rados_write_op_assert_exists_enter, write_op);
@@ -4380,6 +4387,13 @@ extern "C" void rados_read_op_set_flags(rados_read_op_t read_op, int flags)
   tracepoint(librados, rados_read_op_set_flags_exit);
 }
 
+extern "C" void rados_read_op_assert_version(rados_read_op_t read_op, uint64_t ver)
+{
+  tracepoint(librados, rados_read_op_assert_version_enter, read_op);
+  ((::ObjectOperation *)read_op)->assert_version(ver);
+  tracepoint(librados, rados_read_op_assert_version_exit);
+}
+
 extern "C" void rados_read_op_assert_exists(rados_read_op_t read_op)
 {
   tracepoint(librados, rados_read_op_assert_exists_enter, read_op);
index da5f93783ff36d60bcdf5d8878aae11e288446e3..9b577471bab7d01fd400c1bb70981a2399d562f6 100644 (file)
@@ -170,6 +170,31 @@ TEST_F(CReadOpsTest, AssertExists) {
   remove_object();
 }
 
+TEST_F(CReadOpsTest, AssertVersion) {
+  write_object();
+  // Write to the object a second time to guarantee that its
+  // version number is greater than 0
+  write_object();
+  uint64_t v = rados_get_last_version(ioctx);
+
+  rados_read_op_t op = rados_create_read_op();
+  rados_read_op_assert_version(op, v+1);
+  ASSERT_EQ(-EOVERFLOW, rados_read_op_operate(op, ioctx, obj, 0));
+  rados_release_read_op(op);
+
+  op = rados_create_read_op();
+  rados_read_op_assert_version(op, v-1);
+  ASSERT_EQ(-ERANGE, rados_read_op_operate(op, ioctx, obj, 0));
+  rados_release_read_op(op);
+
+  op = rados_create_read_op();
+  rados_read_op_assert_version(op, v);
+  ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
+  rados_release_read_op(op);
+
+  remove_object();
+}
+
 TEST_F(CReadOpsTest, CmpXattr) {
   write_object();
 
index 7e1dc73df764eb49855fd462a462bae75e911b24..37c7450888d13a8ecab0cefe0c0b8211f8bf5867 100644 (file)
@@ -1,5 +1,6 @@
 // Tests for the C API coverage of atomic write operations
 
+#include <errno.h>
 #include "include/rados/librados.h"
 #include "test/librados/test.h"
 #include "gtest/gtest.h"
@@ -41,6 +42,51 @@ TEST(LibRadosCWriteOps, assertExists) {
   ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
 }
 
+TEST(LibRadosCWriteOps, WriteOpAssertVersion) {
+  rados_t cluster;
+  rados_ioctx_t ioctx;
+  std::string pool_name = get_temp_pool_name();
+  ASSERT_EQ("", create_one_pool(pool_name, &cluster));
+  rados_ioctx_create(cluster, pool_name.c_str(), &ioctx);
+
+  rados_write_op_t op = rados_create_write_op();
+  ASSERT_TRUE(op);
+  rados_write_op_create(op, LIBRADOS_CREATE_EXCLUSIVE, NULL);
+  ASSERT_EQ(0, rados_write_op_operate(op, ioctx, "test", NULL, 0));
+  rados_release_write_op(op);
+
+  // Write to the object a second time to guarantee that its
+  // version number is greater than 0
+  op = rados_create_write_op();
+  ASSERT_TRUE(op);
+  rados_write_op_write_full(op, "hi", 2);
+  ASSERT_EQ(0, rados_write_op_operate(op, ioctx, "test", NULL, 0));
+  rados_release_write_op(op);
+
+  uint64_t v = rados_get_last_version(ioctx);
+
+  op = rados_create_write_op();
+  ASSERT_TRUE(op);
+  rados_write_op_assert_version(op, v+1);
+  ASSERT_EQ(-EOVERFLOW, rados_write_op_operate(op, ioctx, "test", NULL, 0));
+  rados_release_write_op(op);
+
+  op = rados_create_write_op();
+  ASSERT_TRUE(op);
+  rados_write_op_assert_version(op, v-1);
+  ASSERT_EQ(-ERANGE, rados_write_op_operate(op, ioctx, "test", NULL, 0));
+  rados_release_write_op(op);
+
+  op = rados_create_write_op();
+  ASSERT_TRUE(op);
+  rados_write_op_assert_version(op, v);
+  ASSERT_EQ(0, rados_write_op_operate(op, ioctx, "test", NULL, 0));
+  rados_release_write_op(op);
+
+  rados_ioctx_destroy(ioctx);
+  ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
+}
+
 TEST(LibRadosCWriteOps, Xattrs) {
   rados_t cluster;
   rados_ioctx_t ioctx;