return r;
}
+version_t *librados::IoCtxImpl::get_objver_for_read(version_t *objver_p) const {
+ if (!no_version_on_read) {
+ return objver_p;
+ }
+
+ if (objver_p) {
+ *objver_p = std::numeric_limits<version_t>::max();
+ }
+ return nullptr;
+}
+
+void librados::IoCtxImpl::set_no_version_on_read(bool _val) {
+ no_version_on_read = _val;
+}
+
int librados::IoCtxImpl::operate_read(const object_t& oid,
::ObjectOperation *o,
bufferlist *pbl,
*o, snap_seq, pbl,
flags | extra_op_flags,
flags_mask,
- onack, &ver);
+ onack, get_objver_for_read(&ver));
objecter->op_submit(objecter_op);
{
Objecter::Op *objecter_op = objecter->prepare_read_op(
oid, oloc,
*o, snap_seq, pbl, flags | extra_op_flags, -1,
- oncomplete, &c->objver, nullptr, 0, &trace);
+ oncomplete, get_objver_for_read(&c->objver), nullptr, 0, &trace);
objecter->op_submit(objecter_op, &c->tid);
trace.event("rados operate read submitted");
Objecter::Op *o = objecter->prepare_read_op(
oid, oloc,
off, len, snapid, pbl, extra_op_flags,
- oncomplete, &c->objver, nullptr, 0, &trace);
+ oncomplete, get_objver_for_read(&c->objver), nullptr, 0, &trace);
objecter->op_submit(o, &c->tid);
return 0;
}
Objecter::Op *o = objecter->prepare_read_op(
oid, oloc,
off, len, snapid, &c->bl, extra_op_flags,
- oncomplete, &c->objver, nullptr, 0, &trace);
+ oncomplete, get_objver_for_read(&c->objver), nullptr, 0, &trace);
objecter->op_submit(o, &c->tid);
return 0;
}
Objecter::Op *o = objecter->prepare_read_op(
oid, oloc,
onack->m_ops, snapid, NULL, extra_op_flags, -1,
- onack, &c->objver);
+ onack, get_objver_for_read(&c->objver));
objecter->op_submit(o, &c->tid);
return 0;
}
Objecter::Op *o = objecter->prepare_cmpext_op(
oid, oloc, off, cmp_bl, snap_seq, extra_op_flags,
- onack, &c->objver);
+ onack, get_objver_for_read(&c->objver));
objecter->op_submit(o, &c->tid);
return 0;
onack->m_ops.cmpext(off, cmp_len, cmp_buf, NULL);
Objecter::Op *o = objecter->prepare_read_op(
- oid, oloc, onack->m_ops, snap_seq, NULL, extra_op_flags, -1, onack, &c->objver);
+ oid, oloc, onack->m_ops, snap_seq, NULL, extra_op_flags, -1, onack,
+ get_objver_for_read(&c->objver));
objecter->op_submit(o, &c->tid);
return 0;
}
Objecter::Op *o = objecter->prepare_stat_op(
oid, oloc,
snap_seq, psize, &onack->mtime, extra_op_flags,
- onack, &c->objver);
+ onack, get_objver_for_read(&c->objver));
objecter->op_submit(o, &c->tid);
return 0;
}
Objecter::Op *o = objecter->prepare_stat_op(
oid, oloc,
snap_seq, psize, &onack->mtime, extra_op_flags,
- onack, &c->objver);
+ onack, get_objver_for_read(&c->objver));
objecter->op_submit(o, &c->tid);
return 0;
}
ASSERT_EQ(0, cluster.conf_get(option, actual));
ASSERT_EQ(expected, actual);
}
+
+TEST_F(LibRadosMiscPP, NoVer) {
+ bufferlist bl;
+ bl.append("ceph");
+ ObjectWriteOperation write, write2;
+ ObjectReadOperation read, read2;
+
+ write.write_full(bl);
+ ASSERT_EQ(0, ioctx.operate("foo", &write));
+ uint64_t version = ioctx.get_last_version();
+
+ ioctx.set_no_version_on_read(true);
+ bl.append("moreceph");
+ write2.write_full(bl);
+ ASSERT_EQ(0, ioctx.operate("foo", &write2));
+
+ // Write versioning should still work.
+ ASSERT_EQ(++version, ioctx.get_last_version());
+
+ // Asserting the version should still work.
+ read.assert_version(version);
+ read.read(0, bl.length(), NULL, NULL);
+ ASSERT_EQ(0, ioctx.operate("foo", &read, &bl));
+
+ // However, version read should be invalid.
+ ASSERT_EQ(std::numeric_limits<version_t>::max(), ioctx.get_last_version());
+
+ // Re-enable versioning and check we can re-establish the version on a read.
+ ioctx.set_no_version_on_read(false);
+ read2.read(0, bl.length(), NULL, NULL);
+ ASSERT_EQ(0, ioctx.operate("foo", &read2, &bl));
+ ASSERT_EQ(0, memcmp(bl.c_str(), "ceph", 4));
+
+ // last version should now have been corrected.
+ ASSERT_EQ(version, ioctx.get_last_version());
+}
\ No newline at end of file