]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
test/librados_test_stub: reimplement cmpext()
authorIlya Dryomov <idryomov@gmail.com>
Wed, 20 Feb 2019 10:37:07 +0000 (11:37 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 20 Feb 2019 14:20:28 +0000 (15:20 +0100)
cmpext is a read operation.  As such, it shouldn't be creating objects
or extending them and it should accept snapshots.

The compare code is completely broken, resulting in false positives
(i.e. failures to detect mismatches) in many cases.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/test/librados_test_stub/TestMemIoCtxImpl.cc

index 9e160015ff066833b67e54a324f9704b7b734406..05aefe76fcf1ce7eec476606c7bda53bf820b7d7 100644 (file)
@@ -20,6 +20,17 @@ static void to_vector(const interval_set<uint64_t> &set,
   }
 }
 
+// see PrimaryLogPG::finish_extent_cmp()
+static int cmpext_compare(const bufferlist &bl, const bufferlist &read_bl) {
+  for (uint64_t idx = 0; idx < bl.length(); ++idx) {
+    char read_byte = (idx < read_bl.length() ? read_bl[idx] : 0);
+    if (bl[idx] != read_byte) {
+      return -MAX_ERRNO - idx;
+    }
+  }
+  return 0;
+}
+
 namespace librados {
 
 TestMemIoCtxImpl::TestMemIoCtxImpl() {
@@ -640,32 +651,30 @@ int TestMemIoCtxImpl::writesame(const std::string& oid, bufferlist& bl, size_t l
 
 int TestMemIoCtxImpl::cmpext(const std::string& oid, uint64_t off,
                              bufferlist& cmp_bl) {
-  if (get_snap_read() != CEPH_NOSNAP) {
-    return -EROFS;
-  } else if (m_client->is_blacklisted()) {
+  if (m_client->is_blacklisted()) {
     return -EBLACKLISTED;
   }
 
-  if (cmp_bl.length() == 0) {
-    return -EINVAL;
-  }
+  bufferlist read_bl;
+  uint64_t len = cmp_bl.length();
 
   TestMemCluster::SharedFile file;
   {
-    RWLock::WLocker l(m_pool->file_lock);
-    file = get_file(oid, true, get_snap_context());
+    RWLock::RLocker l(m_pool->file_lock);
+    file = get_file(oid, false, get_snap_context());
+    if (file == NULL) {
+      return cmpext_compare(cmp_bl, read_bl);
+    }
   }
 
   RWLock::RLocker l(file->lock);
-  size_t len = cmp_bl.length();
-  ensure_minimum_length(off + len, &file->data);
-  if (len > 0 && off <= len) {
-    for (uint64_t p = off; p < len; p++)  {
-      if (file->data[p] != cmp_bl[p])
-        return -MAX_ERRNO - p;
-    }
+  if (off >= file->data.length()) {
+    len = 0;
+  } else if (off + len > file->data.length()) {
+    len = file->data.length() - off;
   }
-  return 0;
+  read_bl.substr_of(file->data, off, len);
+  return cmpext_compare(cmp_bl, read_bl);
 }
 
 int TestMemIoCtxImpl::xattr_get(const std::string& oid,