]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cls/refcount: ENOENT when put on non-existent object
authorSage Weil <sage@redhat.com>
Tue, 16 Dec 2014 00:11:05 +0000 (16:11 -0800)
committerSage Weil <sage@redhat.com>
Tue, 16 Dec 2014 00:11:05 +0000 (16:11 -0800)
If we get ENOENT, do not that that to mean an implicit reference count of
1.  That means that if you put a non-existent object, we should get
ENOENT instead of doing a useless delete on the OSD.

Note that this changes the get behavior slightly, too: doing a get on a
non-existent object will now fail with ENOENT instead of implicitly
creating it.

Stumbled across this from #10262.

Signed-off-by: Sage Weil <sage@redhat.com>
src/cls/refcount/cls_refcount.cc
src/test/cls_refcount/test_cls_refcount.cc

index 5e8edeb887af8fa83de2100d3c1f61d723361092..c97460f65cd7f25ccab6ef98e5b80684d51a35c9 100644 (file)
@@ -53,7 +53,7 @@ static int read_refcount(cls_method_context_t hctx, bool implicit_ref, obj_refco
   bufferlist bl;
   objr->refs.clear();
   int ret = cls_cxx_getxattr(hctx, REFCOUNT_ATTR, &bl);
-  if (ret == -ENOENT || ret == -ENODATA) {
+  if (ret == -ENODATA) {
     if (implicit_ref) {
       objr->refs[wildcard_tag] = true;
     }
index 79d9c9420619a159869123f164c315446d83f131..a585b9a9d12fae5a1262f92680739f650b267fad 100644 (file)
@@ -27,10 +27,17 @@ TEST(cls_rgw, test_implicit) /* test refcount using implicit referencing of newl
 
   /* add chains */
   string oid = "obj";
+  string oldtag = "oldtag";
+  string newtag = "newtag";
 
 
-  /* create object */
+  /* get on a missing object will fail */
+  librados::ObjectWriteOperation *op = new_op();
+  cls_refcount_get(*op, newtag, true);
+  ASSERT_EQ(-ENOENT, ioctx.operate(oid, op));
+  delete op;
 
+  /* create object */
   ASSERT_EQ(0, ioctx.create(oid, true));
 
   /* read reference, should return a single wildcard entry */
@@ -46,11 +53,7 @@ TEST(cls_rgw, test_implicit) /* test refcount using implicit referencing of newl
   ASSERT_EQ(wildcard_tag, tag);
 
   /* take another reference, verify */
-
-  string oldtag = "oldtag";
-  string newtag = "newtag";
-
-  librados::ObjectWriteOperation *op = new_op();
+  op = new_op();
   cls_refcount_get(*op, newtag, true);
   ASSERT_EQ(0, ioctx.operate(oid, op));
 
@@ -109,6 +112,41 @@ TEST(cls_rgw, test_implicit) /* test refcount using implicit referencing of newl
   ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
 }
 
+
+TEST(cls_rgw, test_put_snap) {
+  librados::Rados rados;
+  librados::IoCtx ioctx;
+  string pool_name = get_temp_pool_name();
+
+  /* create pool */
+  ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
+  ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+
+  bufferlist bl;
+  bl.append("hi there");
+  ASSERT_EQ(0, ioctx.write("foo", bl, bl.length(), 0));
+  ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
+  ASSERT_EQ(0, ioctx.remove("foo"));
+
+  sleep(2);
+
+  ASSERT_EQ(0, ioctx.snap_create("snapbar"));
+
+  librados::ObjectWriteOperation *op = new_op();
+  op->create(false);
+  cls_refcount_put(*op, "notag", true);
+  ASSERT_EQ(-ENOENT, ioctx.operate("foo", op));
+
+  EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
+  EXPECT_EQ(0, ioctx.snap_remove("snapbar"));
+
+  delete op;
+
+  /* remove pool */
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
+}
+
 TEST(cls_rgw, test_explicit) /* test refcount using implicit referencing of newly created objects */
 {
   librados::Rados rados;