From: Sage Weil Date: Tue, 16 Dec 2014 00:11:05 +0000 (-0800) Subject: cls/refcount: ENOENT when put on non-existent object X-Git-Tag: v0.92~102^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=db951aed0aca59a1bb2b21b87ada714e6769e230;p=ceph.git cls/refcount: ENOENT when put on non-existent object 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 --- diff --git a/src/cls/refcount/cls_refcount.cc b/src/cls/refcount/cls_refcount.cc index 5e8edeb887af..c97460f65cd7 100644 --- a/src/cls/refcount/cls_refcount.cc +++ b/src/cls/refcount/cls_refcount.cc @@ -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; } diff --git a/src/test/cls_refcount/test_cls_refcount.cc b/src/test/cls_refcount/test_cls_refcount.cc index 79d9c9420619..a585b9a9d12f 100644 --- a/src/test/cls_refcount/test_cls_refcount.cc +++ b/src/test/cls_refcount/test_cls_refcount.cc @@ -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;