]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph_test_objectstore: exercise clone_range from synthetic
authorSage Weil <sage@redhat.com>
Thu, 15 Sep 2016 21:15:25 +0000 (17:15 -0400)
committerSage Weil <sage@redhat.com>
Tue, 20 Sep 2016 22:35:55 +0000 (18:35 -0400)
Signed-off-by: Sage Weil <sage@redhat.com>
src/test/objectstore/store_test.cc

index 2cb11783a985f4ade46dad0bbec5219db702b846..109faff49e8853cb01a680561cb668b768601d54 100644 (file)
@@ -3319,6 +3319,92 @@ public:
     return status;
   }
 
+  int clone_range() {
+    Mutex::Locker locker(lock);
+    EnterExit ee("clone_range");
+    if (!can_unlink())
+      return -ENOENT;
+    if (!can_create())
+      return -ENOSPC;
+    wait_for_ready();
+
+    ghobject_t old_obj;
+    int max = 20;
+    do {
+      old_obj = get_uniform_random_object();
+    } while (--max && !contents[old_obj].data.length());
+    bufferlist &srcdata = contents[old_obj].data;
+    if (srcdata.length() == 0) {
+      return 0;
+    }
+    available_objects.erase(old_obj);
+    ghobject_t new_obj = get_uniform_random_object();
+    available_objects.erase(new_obj);
+
+    boost::uniform_int<> u1(0, max_object_len - max_write_len);
+    boost::uniform_int<> u2(0, max_write_len);
+    uint64_t srcoff = u1(*rng);
+    uint64_t dstoff = u1(*rng);
+    uint64_t len = u2(*rng);
+    if (write_alignment) {
+      srcoff = ROUND_UP_TO(srcoff, write_alignment);
+      dstoff = ROUND_UP_TO(dstoff, write_alignment);
+      len = ROUND_UP_TO(len, write_alignment);
+    }
+
+    if (srcoff > srcdata.length() - 1) {
+      srcoff = srcdata.length() - 1;
+    }
+    if (srcoff + len > srcdata.length()) {
+      len = srcdata.length() - srcoff;
+    }
+    if (0)
+      cout << __func__ << " from " << srcoff << "~" << len
+        << " (size " << srcdata.length() << ") to "
+        << dstoff << "~" << len << std::endl;
+
+    ObjectStore::Transaction t;
+    t.clone_range(cid, old_obj, new_obj, srcoff, len, dstoff);
+    ++in_flight;
+    in_flight_objects.insert(old_obj);
+
+    bufferlist bl;
+    if (srcoff < srcdata.length()) {
+      if (srcoff + len > srcdata.length()) {
+       bl.substr_of(srcdata, srcoff, srcdata.length() - srcoff);
+      } else {
+       bl.substr_of(srcdata, srcoff, len);
+      }
+    }
+
+    // *copy* the data buffer, since we may modify it later.
+    {
+      bufferlist t;
+      t.append(bl.c_str(), bl.length());
+      t.swap(bl);
+    }
+
+    bufferlist& dstdata = contents[new_obj].data;
+    if (dstdata.length() <= dstoff) {
+      if (bl.length() > 0) {
+        dstdata.append_zero(dstoff - dstdata.length());
+        dstdata.append(bl);
+      }
+    } else {
+      bufferlist value;
+      assert(dstdata.length() > dstoff);
+      dstdata.copy(0, dstoff, value);
+      value.append(bl);
+      if (value.length() < dstdata.length())
+        dstdata.copy(value.length(),
+                    dstdata.length() - value.length(), value);
+      value.swap(dstdata);
+    }
+
+    int status = store->queue_transaction(osr, std::move(t), new C_SyntheticOnClone(this, old_obj, new_obj));
+    return status;
+  }
+
   int setattrs() {
     Mutex::Locker locker(lock);
     EnterExit ee("setattrs");
@@ -3784,6 +3870,8 @@ void doSyntheticTest(boost::scoped_ptr<ObjectStore>& store,
       test_obj.write();
     } else if (val > 500) {
       test_obj.clone();
+    } else if (val > 450) {
+      test_obj.clone_range();
     } else if (val > 300) {
       test_obj.stash();
     } else if (val > 100) {