summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Dillaman <dillaman@redhat.com>2016-05-17 00:08:35 +0200
committerJason Dillaman <dillaman@redhat.com>2016-05-18 17:02:29 +0200
commit0a8a6126ea35344e85af7eb64ffc490938edba51 (patch)
tree664d8f4f1fb5654c6b3214622565b265ea57c6f5 /src
parentjournal: close, advance, and open object set ordering (diff)
downloadceph-0a8a6126ea35344e85af7eb64ffc490938edba51.tar.xz
ceph-0a8a6126ea35344e85af7eb64ffc490938edba51.zip
journal: helper method to detect newer tags
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/journal/JournalMetadata.cc70
-rw-r--r--src/journal/JournalMetadata.h2
-rw-r--r--src/test/journal/test_JournalMetadata.cc29
3 files changed, 101 insertions, 0 deletions
diff --git a/src/journal/JournalMetadata.cc b/src/journal/JournalMetadata.cc
index a05aa5a907c..c24a96aa0ef 100644
--- a/src/journal/JournalMetadata.cc
+++ b/src/journal/JournalMetadata.cc
@@ -336,6 +336,66 @@ struct C_FlushCommitPosition : public Context {
}
};
+struct C_AssertActiveTag : public Context {
+ CephContext *cct;
+ librados::IoCtx &ioctx;
+ const std::string &oid;
+ AsyncOpTracker &async_op_tracker;
+ std::string client_id;
+ uint64_t tag_tid;
+ Context *on_finish;
+
+ bufferlist out_bl;
+
+ C_AssertActiveTag(CephContext *cct, librados::IoCtx &ioctx,
+ const std::string &oid, AsyncOpTracker &async_op_tracker,
+ const std::string &client_id, uint64_t tag_tid,
+ Context *on_finish)
+ : cct(cct), ioctx(ioctx), oid(oid), async_op_tracker(async_op_tracker),
+ client_id(client_id), tag_tid(tag_tid), on_finish(on_finish) {
+ async_op_tracker.start_op();
+ }
+ virtual ~C_AssertActiveTag() {
+ async_op_tracker.finish_op();
+ }
+
+ void send() {
+ ldout(cct, 20) << "C_AssertActiveTag: " << __func__ << dendl;
+
+ librados::ObjectReadOperation op;
+ client::tag_list_start(&op, tag_tid, 2, client_id, boost::none);
+
+ librados::AioCompletion *comp = librados::Rados::aio_create_completion(
+ this, nullptr, &utils::rados_state_callback<
+ C_AssertActiveTag, &C_AssertActiveTag::handle_send>);
+
+ int r = ioctx.aio_operate(oid, comp, &op, &out_bl);
+ assert(r == 0);
+ comp->release();
+ }
+
+ void handle_send(int r) {
+ ldout(cct, 20) << "C_AssertActiveTag: " << __func__ << ": r=" << r << dendl;
+
+ std::set<cls::journal::Tag> tags;
+ if (r == 0) {
+ bufferlist::iterator it = out_bl.begin();
+ r = client::tag_list_finish(&it, &tags);
+ }
+
+ // NOTE: since 0 is treated as an uninitialized list filter, we need to
+ // load to entries and look at the last tid
+ if (r == 0 && !tags.empty() && tags.rbegin()->tid > tag_tid) {
+ r = -ESTALE;
+ }
+ complete(r);
+ }
+
+ virtual void finish(int r) {
+ on_finish->complete(r);
+ }
+};
+
} // anonymous namespace
JournalMetadata::JournalMetadata(ContextWQ *work_queue, SafeTimer *timer,
@@ -564,6 +624,16 @@ void JournalMetadata::set_active_set(uint64_t object_set, Context *on_finish) {
m_active_set = object_set;
}
+void JournalMetadata::assert_active_tag(uint64_t tag_tid, Context *on_finish) {
+ Mutex::Locker locker(m_lock);
+
+ C_AssertActiveTag *ctx = new C_AssertActiveTag(m_cct, m_ioctx, m_oid,
+ m_async_op_tracker,
+ m_client_id, tag_tid,
+ on_finish);
+ ctx->send();
+}
+
void JournalMetadata::flush_commit_position() {
ldout(m_cct, 20) << __func__ << dendl;
diff --git a/src/journal/JournalMetadata.h b/src/journal/JournalMetadata.h
index 9d19af69f10..db30cf15951 100644
--- a/src/journal/JournalMetadata.h
+++ b/src/journal/JournalMetadata.h
@@ -117,6 +117,8 @@ public:
return m_active_set;
}
+ void assert_active_tag(uint64_t tag_tid, Context *on_finish);
+
void flush_commit_position();
void flush_commit_position(Context *on_safe);
void get_commit_position(ObjectSetPosition *commit_position) const {
diff --git a/src/test/journal/test_JournalMetadata.cc b/src/test/journal/test_JournalMetadata.cc
index b0bb41c844c..b8f559365f8 100644
--- a/src/test/journal/test_JournalMetadata.cc
+++ b/src/test/journal/test_JournalMetadata.cc
@@ -115,3 +115,32 @@ TEST_F(TestJournalMetadata, UpdateActiveObject) {
ASSERT_EQ(123U, metadata1->get_active_set());
}
+
+TEST_F(TestJournalMetadata, AssertActiveTag) {
+ std::string oid = get_temp_oid();
+
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid, "client1", ""));
+
+ journal::JournalMetadataPtr metadata = create_metadata(oid, "client1");
+ ASSERT_EQ(0, init_metadata(metadata));
+ ASSERT_TRUE(wait_for_update(metadata));
+
+ C_SaferCond ctx1;
+ cls::journal::Tag tag1;
+ metadata->allocate_tag(cls::journal::Tag::TAG_CLASS_NEW, {}, &tag1, &ctx1);
+ ASSERT_EQ(0, ctx1.wait());
+
+ C_SaferCond ctx2;
+ metadata->assert_active_tag(tag1.tid, &ctx2);
+ ASSERT_EQ(0, ctx2.wait());
+
+ C_SaferCond ctx3;
+ cls::journal::Tag tag2;
+ metadata->allocate_tag(tag1.tag_class, {}, &tag2, &ctx3);
+ ASSERT_EQ(0, ctx3.wait());
+
+ C_SaferCond ctx4;
+ metadata->assert_active_tag(tag1.tid, &ctx4);
+ ASSERT_EQ(-ESTALE, ctx4.wait());
+}