summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-09-10 16:30:25 -0700
committerSage Weil <sage@inktank.com>2013-09-17 11:06:27 -0700
commit83f12e46308844dc7a91e141f8428799777af34d (patch)
tree7d20621d201c0b20ec79f72537c07778794d5486
parentd050596a0d6c043a51c2f28377d5ef6fc2b5e106 (diff)
downloadceph-83f12e46308844dc7a91e141f8428799777af34d.tar.gz
ceph_test_rados: submit a racing read with every COPY_FROM
Verify that the racing read completes after the COPY_FROM does (i.e., is blocked by it). Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/test/osd/RadosModel.h76
1 files changed, 55 insertions, 21 deletions
diff --git a/src/test/osd/RadosModel.h b/src/test/osd/RadosModel.h
index de897bd2325..5b8f8b57cc7 100644
--- a/src/test/osd/RadosModel.h
+++ b/src/test/osd/RadosModel.h
@@ -1404,9 +1404,11 @@ public:
ObjectDesc src_value;
librados::ObjectWriteOperation op;
librados::AioCompletion *comp;
+ librados::AioCompletion *comp_racing_read;
int snap;
- bool done;
- tid_t tid;
+ int done;
+ uint64_t version;
+ int r;
CopyFromOp(int n,
RadosTestContext *context,
const string &oid,
@@ -1415,7 +1417,7 @@ public:
: TestOp(n, context, stat),
oid(oid), oid_src(oid_src),
src_value(&context->cont_gen),
- comp(NULL), done(false), tid(0)
+ comp(NULL), done(0), version(0), r(0)
{}
void _begin()
@@ -1447,35 +1449,67 @@ public:
new TestOp::CallbackInfo(0));
comp = context->rados.aio_create_completion((void*) cb_arg, &write_callback,
NULL);
- tid = context->io_ctx.aio_operate(context->prefix+oid, comp, &op);
+ context->io_ctx.aio_operate(context->prefix+oid, comp, &op);
+
+ // queue up a racing read, too.
+ pair<TestOp*, TestOp::CallbackInfo*> *read_cb_arg =
+ new pair<TestOp*, TestOp::CallbackInfo*>(this,
+ new TestOp::CallbackInfo(1));
+ comp_racing_read = context->rados.aio_create_completion((void*) read_cb_arg, &write_callback,
+ NULL);
+ context->io_ctx.aio_stat(context->prefix+oid, comp_racing_read, NULL, NULL);
}
void _finish(CallbackInfo *info)
{
Mutex::Locker l(context->state_lock);
- done = true;
- int r;
- assert(comp->is_complete());
- cout << num << ": finishing copy_from tid " << tid << " to " << context->prefix + oid << std::endl;
- if ((r = comp->get_return_value())) {
- if (!(r == -ENOENT && src_value.deleted())) {
- cerr << "Error: oid " << oid << " copy_from " << oid_src << " returned error code "
- << r << std::endl;
+
+ // note that the read can (and atm will) come back before the
+ // write reply, but will reflect the update and the versions will
+ // match.
+
+ if (info->id == 0) {
+ // copy_from
+ assert(comp->is_complete());
+ cout << num << ": finishing copy_from to " << context->prefix + oid << std::endl;
+ if ((r = comp->get_return_value())) {
+ if (!(r == -ENOENT && src_value.deleted())) {
+ cerr << "Error: oid " << oid << " copy_from " << oid_src << " returned error code "
+ << r << std::endl;
+ }
+ } else {
+ assert(!version || comp->get_version64() == version);
+ version = comp->get_version64();
+ context->update_object_full(oid, src_value);
+ context->update_object_version(oid, comp->get_version64());
}
- } else {
- context->update_object_full(oid, src_value);
- context->update_object_version(oid, comp->get_version());
+ context->oid_in_use.erase(oid_src);
+ context->oid_not_in_use.insert(oid_src);
+ context->kick();
+ } else if (info->id == 1) {
+ // racing read
+ assert(comp_racing_read->is_complete());
+ cout << num << ": finishing copy_from racing read to " << context->prefix + oid << std::endl;
+ if ((r = comp_racing_read->get_return_value())) {
+ if (!(r == -ENOENT && src_value.deleted())) {
+ cerr << "Error: oid " << oid << " copy_from " << oid_src << " returned error code "
+ << r << std::endl;
+ }
+ } else {
+ assert(comp_racing_read->get_return_value() == 0);
+ assert(!version || comp_racing_read->get_version64() == version);
+ version = comp_racing_read->get_version64();
+ }
+ context->oid_in_use.erase(oid);
+ context->oid_not_in_use.insert(oid);
+ context->kick();
}
- context->oid_in_use.erase(oid);
- context->oid_not_in_use.insert(oid);
- context->oid_in_use.erase(oid_src);
- context->oid_not_in_use.insert(oid_src);
- context->kick();
+ ++done;
}
bool finished()
{
- return done;
+ return done == 2;
}
string getType()