]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph_test_rados: also send sparse_read in ReadOp
authorKefu Chai <kchai@redhat.com>
Wed, 26 Aug 2015 07:41:13 +0000 (15:41 +0800)
committerKefu Chai <kchai@redhat.com>
Tue, 1 Sep 2015 05:49:22 +0000 (13:49 +0800)
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/test/osd/Object.cc
src/test/osd/Object.h
src/test/osd/RadosModel.h

index 37d09c3cf5669e0938b28876ace256d70108a2b3..f2bc9db401f5ed8531f9c43ead637c22f6dcf2c2 100644 (file)
@@ -183,3 +183,41 @@ bool ObjectDesc::check(bufferlist &to_check) {
   }
   return true;
 }
+
+bool ObjectDesc::check_sparse(const std::map<uint64_t, uint64_t>& extents,
+                             bufferlist &to_check) {
+  auto i = begin();
+  auto p = to_check.begin();
+  uint64_t pos = 0;
+  for (auto extent : extents) {
+    const uint64_t start = extent.first;
+    const uint64_t end = start + extent.second;
+    for (; pos < end; ++i, ++pos) {
+      if (i.end()) {
+       std::cout << "reached end of iterator first" << std::endl;
+       return false;
+      }
+      if (pos < start) {
+       // check the hole
+       if (*i != '\0') {
+         std::cout << "incorrect buffer at pos " << pos << std::endl;
+         return false;
+       }
+      } else {
+       // then the extent
+       if (*i != *p) {
+         std::cout << "incorrect buffer at pos " << pos << std::endl;
+         return false;
+       }
+       ++p;
+      }
+    }
+  }
+  uint64_t size = layers.empty() ? 0 :
+    most_recent_gen()->get_length(most_recent());
+  if (pos != size) {
+    std::cout << "only read " << pos << " out of size " << size << std::endl;
+    return false;
+  }
+  return true;
+}
index bffb397cfb667af5d564fcd05430938b7ae52c32..feeefebe8dd99782542a3f95aae42897321349fb 100644 (file)
@@ -358,6 +358,8 @@ public:
   // takes ownership of gen
   void update(ContentsGenerator *gen, const ContDesc &next);
   bool check(bufferlist &to_check);
+  bool check_sparse(const std::map<uint64_t, uint64_t>& extends,
+                   bufferlist &to_check);
   const ContDesc &most_recent();
   ContentsGenerator *most_recent_gen() {
     return layers.begin()->first.get();
index 9097c7a0b7c32afa0c2be61ae66736c2e00f51b4..dddaa9dec4aeb44788ad6c2f0e8c99d452339c73 100644 (file)
@@ -992,6 +992,8 @@ public:
 
   vector<bufferlist> results;
   vector<int> retvals;
+  vector<std::map<uint64_t, uint64_t>> extent_results;
+  vector<bool> is_sparse_read;
   uint64_t waiting_on;
 
   map<string, bufferlist> attrs;
@@ -1016,10 +1018,32 @@ public:
       balance_reads(balance_reads),
       results(3),
       retvals(3),
+      extent_results(3),
+      is_sparse_read(3, false),
       waiting_on(0),
       attrretval(0)
   {}
-               
+
+  void _do_read(librados::ObjectReadOperation& read_op, int index) {
+    uint64_t len = 0;
+    if (old_value.has_contents())
+      len = old_value.most_recent_gen()->get_length(old_value.most_recent());
+    if (rand() % 2) {
+      is_sparse_read[index] = false;
+      read_op.read(0,
+                  len,
+                  &results[index],
+                  &retvals[index]);
+    } else {
+      is_sparse_read[index] = true;
+      read_op.sparse_read(0,
+                         len,
+                         &extent_results[index],
+                         &results[index],
+                         &retvals[index]);
+    }
+  }
+
   void _begin()
   {
     context->state_lock.Lock();
@@ -1065,13 +1089,7 @@ public:
     if (snap >= 0) {
       context->io_ctx.snap_set_read(context->snaps[snap]);
     }
-
-    op.read(0,
-           !old_value.has_contents() ? 0 :
-           old_value.most_recent_gen()->get_length(old_value.most_recent()),
-           &results[0],
-           &retvals[0]);
-
+    _do_read(op, 0);
     for (map<string, ContDesc>::iterator i = old_value.attrs.begin();
         i != old_value.attrs.end();
         ++i) {
@@ -1103,12 +1121,7 @@ public:
     // OSD's read behavior in some scenarios
     for (uint32_t i = 1; i < 3; ++i) {
       librados::ObjectReadOperation pipeline_op;
-
-      pipeline_op.read(0,
-                       !old_value.has_contents() ? 0 :
-                       old_value.most_recent_gen()->get_length(old_value.most_recent()),
-                       &results[i],
-                       &retvals[i]);
+      _do_read(pipeline_op, i);
       assert(!context->io_ctx.aio_operate(context->prefix+oid, completions[i], &pipeline_op, 0));
       waiting_on++;
     }
@@ -1182,11 +1195,17 @@ public:
               << ", expected " << old_value.most_recent() << std::endl;
          context->errors++;
        }
-        for (vector<bufferlist>::iterator it = results.begin();
-             it != results.end(); ++it) {
-         if (!old_value.check(*it)) {
-           cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl;
-           context->errors++;
+        for (unsigned i = 0; i < results.size(); i++) {
+         if (is_sparse_read[i]) {
+           if (!old_value.check_sparse(extent_results[i], results[i])) {
+             cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl;
+             context->errors++;
+           }
+         } else {
+           if (!old_value.check(results[i])) {
+             cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl;
+             context->errors++;
+           }
          }
        }
        if (context->errors) assert(0);