Skip to content

Commit

Permalink
Merge pull request ceph#11103 from liewegas/wip-clone-range
Browse files Browse the repository at this point in the history
ceph_test_objectstore: test clone_range and fix a few bugs
liewegas authored Sep 20, 2016
2 parents 2896d42 + 60ae186 commit cbe2700
Showing 3 changed files with 98 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/os/ObjectStore.h
Original file line number Diff line number Diff line change
@@ -1338,6 +1338,11 @@ class ObjectStore {
* The data portion of the destination object receives a copy of a
* portion of the data from the source object. None of the other
* three parts of an object is copied from the source.
*
* The destination object size may be extended to the dstoff + len.
*
* The source range *must* overlap with the source object data. If it does
* not the result is undefined.
*/
void clone_range(const coll_t& cid, const ghobject_t& oid, ghobject_t noid,
uint64_t srcoff, uint64_t srclen, uint64_t dstoff) {
6 changes: 4 additions & 2 deletions src/os/memstore/MemStore.cc
Original file line number Diff line number Diff line change
@@ -1496,8 +1496,10 @@ int BufferlistObject::write(uint64_t offset, const bufferlist &src)
if (get_size() >= offset) {
newdata.substr_of(data, 0, offset);
} else {
newdata.substr_of(data, 0, get_size());
newdata.append(offset - get_size());
if (get_size()) {
newdata.substr_of(data, 0, get_size());
}
newdata.append_zero(offset - get_size());
}

newdata.append(src);
90 changes: 89 additions & 1 deletion src/test/objectstore/store_test.cc
Original file line number Diff line number Diff line change
@@ -3319,6 +3319,92 @@ class SyntheticWorkloadState {
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) {
@@ -5203,7 +5291,7 @@ int main(int argc, char **argv) {
g_ceph_context->_conf->set_val("filestore_op_thread_timeout", "1000");
g_ceph_context->_conf->set_val("filestore_op_thread_suicide_timeout", "10000");
g_ceph_context->_conf->set_val("filestore_debug_disable_sharded_check", "true");
g_ceph_context->_conf->set_val("filestore_fiemap", "true");
//g_ceph_context->_conf->set_val("filestore_fiemap", "true");
g_ceph_context->_conf->set_val("bluestore_fsck_on_mount", "true");
g_ceph_context->_conf->set_val("bluestore_fsck_on_umount", "true");
g_ceph_context->_conf->set_val("bluestore_debug_misc", "true");

0 comments on commit cbe2700

Please sign in to comment.