]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: cmpext operator should ignore -ENOENT on read 16622/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 27 Jul 2017 11:48:59 +0000 (07:48 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 28 Jul 2017 23:07:13 +0000 (19:07 -0400)
The operator already handles the case where the object is truncated. If
an RBD user performs a read + cmpext/write of a sparse image, the read
of the missing object would return a zeroed buffer. Using that zeroed
buffer for the cmpext test would fail since it wasn't ignoring the
-ENOENT read failure.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/osd/PrimaryLogPG.cc
src/test/librados/io.cc

index e94d8db1c8cf2d915cb02624030c14f7bf298d95..dbacb3c63c0f30bb34772f2d45ccf10138d4a0d6 100644 (file)
@@ -4694,7 +4694,13 @@ struct C_ExtentCmpRead : public Context {
   }
 
   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) {
@@ -4708,7 +4714,10 @@ int PrimaryLogPG::do_extent_cmp(OpContext *ctx, OSDOp& osd_op)
   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;
@@ -4745,7 +4754,7 @@ int PrimaryLogPG::do_extent_cmp(OpContext *ctx, OSDOp& osd_op)
 
   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);
index 347af5d288567ea36cf51f35a1c3e95a29b67448..5094f756987af0c29a89650802b14e3881eb57a8 100644 (file)
@@ -1230,6 +1230,23 @@ TEST_F(LibRadosIoPP, CmpExtPP) {
   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");
@@ -1270,6 +1287,23 @@ TEST_F(LibRadosIoECPP, CmpExtPP) {
   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");