}
void finish(int r) override {
- fill_extent_ctx->complete(r);
+ if (r == -ENOENT) {
+ osd_op.rval = 0;
+ read_bl.clear();
+ delete fill_extent_ctx;
+ } else {
+ fill_extent_ctx->complete(r);
+ }
fill_extent_ctx = nullptr;
if (osd_op.rval >= 0) {
dout(20) << __func__ << dendl;
ceph_osd_op& op = osd_op.op;
- if (pool.info.require_rollback()) {
+ if (!ctx->obs->exists || ctx->obs->oi.is_whiteout()) {
+ dout(20) << __func__ << " object DNE" << dendl;
+ return finish_extent_cmp(osd_op, {});
+ } else if (pool.info.require_rollback()) {
// If there is a data digest and it is possible we are reading
// entire object, pass the digest.
auto& oi = ctx->new_obs.oi;
int result = do_osd_ops(ctx, read_ops);
if (result < 0) {
- derr << "do_extent_cmp do_osd_ops failed " << result << dendl;
+ derr << __func__ << " failed " << result << dendl;
return result;
}
return finish_extent_cmp(osd_op, read_op.outdata);
ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4));
}
+TEST_F(LibRadosIoPP, CmpExtDNEPP) {
+ bufferlist bl;
+ bl.append(std::string(4, '\0'));
+
+ bufferlist new_bl;
+ new_bl.append("CEPH");
+ ObjectWriteOperation write;
+ write.cmpext(0, bl, nullptr);
+ write.write(0, new_bl);
+ ASSERT_EQ(0, ioctx.operate("foo", &write));
+
+ ObjectReadOperation read;
+ read.read(0, bl.length(), NULL, NULL);
+ ASSERT_EQ(0, ioctx.operate("foo", &read, &bl));
+ ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4));
+}
+
TEST_F(LibRadosIoPP, CmpExtMismatchPP) {
bufferlist bl;
bl.append("ceph");
ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4));
}
+TEST_F(LibRadosIoECPP, CmpExtDNEPP) {
+ bufferlist bl;
+ bl.append(std::string(4, '\0'));
+
+ bufferlist new_bl;
+ new_bl.append("CEPH");
+ ObjectWriteOperation write;
+ write.cmpext(0, bl, nullptr);
+ write.write_full(new_bl);
+ ASSERT_EQ(0, ioctx.operate("foo", &write));
+
+ ObjectReadOperation read;
+ read.read(0, bl.length(), NULL, NULL);
+ ASSERT_EQ(0, ioctx.operate("foo", &read, &bl));
+ ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4));
+}
+
TEST_F(LibRadosIoECPP, CmpExtMismatchPP) {
bufferlist bl;
bl.append("ceph");