From 971ff26ed2f7d858fad3c6edc0c924fddf7c3eaa Mon Sep 17 00:00:00 2001 From: wangzhengyong Date: Mon, 12 Jun 2017 21:23:04 +0800 Subject: [PATCH] librbd/journal: handle compare_and_write event Signed-off-by: Zhengyong Wang --- src/include/int_types.h | 12 ++++ src/librbd/journal/Replay.cc | 50 ++++++++++++++--- src/librbd/journal/Replay.h | 17 ++++-- src/librbd/journal/Types.cc | 29 ++++++++++ src/librbd/journal/Types.h | 104 ++++++++++++++++++++++------------- 5 files changed, 161 insertions(+), 51 deletions(-) diff --git a/src/include/int_types.h b/src/include/int_types.h index 61ad797139247..56b2723f3a5c0 100644 --- a/src/include/int_types.h +++ b/src/include/int_types.h @@ -50,4 +50,16 @@ typedef __u32 __bitwise__ __be32; typedef __u64 __bitwise__ __le64; typedef __u64 __bitwise__ __be64; +#ifndef BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif + +#ifndef BOOST_MPL_LIMIT_VECTOR_SIZE +#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 // or whatever you need +#endif + +#ifndef BOOST_MPL_LIMIT_MAP_SIZE +#define BOOST_MPL_LIMIT_MAP_SIZE 30 // or whatever you need +#endif + #endif diff --git a/src/librbd/journal/Replay.cc b/src/librbd/journal/Replay.cc index 29289ac580a48..92accbc1382aa 100644 --- a/src/librbd/journal/Replay.cc +++ b/src/librbd/journal/Replay.cc @@ -341,7 +341,8 @@ void Replay::handle_event(const journal::AioDiscardEvent &event, bool flush_required; auto aio_comp = create_aio_modify_completion(on_ready, on_safe, io::AIO_TYPE_DISCARD, - &flush_required); + &flush_required, + {}); if (aio_comp == nullptr) { return; } @@ -370,7 +371,8 @@ void Replay::handle_event(const journal::AioWriteEvent &event, bool flush_required; auto aio_comp = create_aio_modify_completion(on_ready, on_safe, io::AIO_TYPE_WRITE, - &flush_required); + &flush_required, + {}); if (aio_comp == nullptr) { return; } @@ -417,7 +419,8 @@ void Replay::handle_event(const journal::AioWriteSameEvent &event, bool flush_required; auto aio_comp = create_aio_modify_completion(on_ready, on_safe, io::AIO_TYPE_WRITESAME, - &flush_required); + &flush_required, + {}); if (aio_comp == nullptr) { return; } @@ -435,6 +438,33 @@ void Replay::handle_event(const journal::AioWriteSameEvent &event, } } + template + void Replay::handle_event(const journal::AioCompareAndWriteEvent &event, + Context *on_ready, Context *on_safe) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 20) << ": AIO CompareAndWrite event" << dendl; + + bufferlist cmp_data = event.cmp_data; + bufferlist write_data = event.write_data; + bool flush_required; + auto aio_comp = create_aio_modify_completion(on_ready, on_safe, + io::AIO_TYPE_COMPARE_AND_WRITE, + &flush_required, + {-EILSEQ}); + io::ImageRequest::aio_compare_and_write(&m_image_ctx, aio_comp, + {{event.offset, event.length}}, + std::move(cmp_data), + std::move(write_data), + nullptr, 0, {}); + if (flush_required) { + m_lock.Lock(); + auto flush_comp = create_aio_flush_completion(nullptr); + m_lock.Unlock(); + + io::ImageRequest::aio_flush(&m_image_ctx, flush_comp, {}); + } +} + template void Replay::handle_event(const journal::OpFinishEvent &event, Context *on_ready, Context *on_safe) { @@ -826,7 +856,7 @@ void Replay::handle_event(const journal::UnknownEvent &event, template void Replay::handle_aio_modify_complete(Context *on_ready, Context *on_safe, - int r) { + int r, std::set &filters) { Mutex::Locker locker(m_lock); CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << ": on_ready=" << on_ready << ", " @@ -835,6 +865,10 @@ void Replay::handle_aio_modify_complete(Context *on_ready, Context *on_safe, if (on_ready != nullptr) { on_ready->complete(0); } + + if (filters.find(r) != filters.end()) + r = 0; + if (r < 0) { lderr(cct) << ": AIO modify op failed: " << cpp_strerror(r) << dendl; on_safe->complete(r); @@ -1004,9 +1038,11 @@ void Replay::handle_op_complete(uint64_t op_tid, int r) { template io::AioCompletion * -Replay::create_aio_modify_completion(Context *on_ready, Context *on_safe, +Replay::create_aio_modify_completion(Context *on_ready, + Context *on_safe, io::aio_type_t aio_type, - bool *flush_required) { + bool *flush_required, + std::set &&filters) { Mutex::Locker locker(m_lock); CephContext *cct = m_image_ctx.cct; assert(m_on_aio_ready == nullptr); @@ -1048,7 +1084,7 @@ Replay::create_aio_modify_completion(Context *on_ready, Context *on_safe, // event. when flushed, the completion of the next flush will fire the // on_safe callback auto aio_comp = io::AioCompletion::create_and_start( - new C_AioModifyComplete(this, on_ready, on_safe), + new C_AioModifyComplete(this, on_ready, on_safe, std::move(filters)), util::get_image_ctx(&m_image_ctx), aio_type); return aio_comp; } diff --git a/src/librbd/journal/Replay.h b/src/librbd/journal/Replay.h index 5b2219851371f..4a4260cb9f00d 100644 --- a/src/librbd/journal/Replay.h +++ b/src/librbd/journal/Replay.h @@ -77,11 +77,14 @@ private: Replay *replay; Context *on_ready; Context *on_safe; - C_AioModifyComplete(Replay *replay, Context *on_ready, Context *on_safe) - : replay(replay), on_ready(on_ready), on_safe(on_safe) { + std::set filters; + C_AioModifyComplete(Replay *replay, Context *on_ready, + Context *on_safe, std::set &&filters) + : replay(replay), on_ready(on_ready), on_safe(on_safe), + filters(std::move(filters)) { } void finish(int r) override { - replay->handle_aio_modify_complete(on_ready, on_safe, r); + replay->handle_aio_modify_complete(on_ready, on_safe, r, filters); } }; @@ -136,6 +139,8 @@ private: Context *on_safe); void handle_event(const AioWriteSameEvent &event, Context *on_ready, Context *on_safe); + void handle_event(const AioCompareAndWriteEvent &event, Context *on_ready, + Context *on_safe); void handle_event(const AioFlushEvent &event, Context *on_ready, Context *on_safe); void handle_event(const OpFinishEvent &event, Context *on_ready, @@ -171,7 +176,8 @@ private: void handle_event(const UnknownEvent &event, Context *on_ready, Context *on_safe); - void handle_aio_modify_complete(Context *on_ready, Context *on_safe, int r); + void handle_aio_modify_complete(Context *on_ready, Context *on_safe, + int r, std::set &filters); void handle_aio_flush_complete(Context *on_flush_safe, Contexts &on_safe_ctxs, int r); @@ -182,7 +188,8 @@ private: io::AioCompletion *create_aio_modify_completion(Context *on_ready, Context *on_safe, io::aio_type_t aio_type, - bool *flush_required); + bool *flush_required, + std::set &&filters); io::AioCompletion *create_aio_flush_completion(Context *on_safe); void handle_aio_completion(io::AioCompletion *aio_comp); diff --git a/src/librbd/journal/Types.cc b/src/librbd/journal/Types.cc index 857542bd74b11..83e80766f0061 100644 --- a/src/librbd/journal/Types.cc +++ b/src/librbd/journal/Types.cc @@ -126,6 +126,29 @@ void AioWriteSameEvent::dump(Formatter *f) const { f->dump_unsigned("length", length); } +uint32_t AioCompareAndWriteEvent::get_fixed_size() { + return EventEntry::get_fixed_size() + 32 /* offset, length */; +} + +void AioCompareAndWriteEvent::encode(bufferlist& bl) const { + ::encode(offset, bl); + ::encode(length, bl); + ::encode(cmp_data, bl); + ::encode(write_data, bl); +} + +void AioCompareAndWriteEvent::decode(__u8 version, bufferlist::iterator& it) { + ::decode(offset, it); + ::decode(length, it); + ::decode(cmp_data, it); + ::decode(write_data, it); +} + +void AioCompareAndWriteEvent::dump(Formatter *f) const { + f->dump_unsigned("offset", offset); + f->dump_unsigned("length", length); +} + void AioFlushEvent::encode(bufferlist& bl) const { } @@ -415,6 +438,9 @@ void EventEntry::decode(bufferlist::iterator& it) { case EVENT_TYPE_AIO_WRITESAME: event = AioWriteSameEvent(); break; + case EVENT_TYPE_AIO_COMPARE_AND_WRITE: + event = AioCompareAndWriteEvent(); + break; default: event = UnknownEvent(); break; @@ -764,6 +790,9 @@ std::ostream &operator<<(std::ostream &out, const EventType &type) { case EVENT_TYPE_AIO_WRITESAME: out << "AioWriteSame"; break; + case EVENT_TYPE_AIO_COMPARE_AND_WRITE: + out << "AioCompareAndWrite"; + break; default: out << "Unknown (" << static_cast(type) << ")"; break; diff --git a/src/librbd/journal/Types.h b/src/librbd/journal/Types.h index adc6f29557520..085ec023f7ef7 100644 --- a/src/librbd/journal/Types.h +++ b/src/librbd/journal/Types.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace ceph { class Formatter; @@ -24,25 +25,26 @@ namespace librbd { namespace journal { enum EventType { - EVENT_TYPE_AIO_DISCARD = 0, - EVENT_TYPE_AIO_WRITE = 1, - EVENT_TYPE_AIO_FLUSH = 2, - EVENT_TYPE_OP_FINISH = 3, - EVENT_TYPE_SNAP_CREATE = 4, - EVENT_TYPE_SNAP_REMOVE = 5, - EVENT_TYPE_SNAP_RENAME = 6, - EVENT_TYPE_SNAP_PROTECT = 7, - EVENT_TYPE_SNAP_UNPROTECT = 8, - EVENT_TYPE_SNAP_ROLLBACK = 9, - EVENT_TYPE_RENAME = 10, - EVENT_TYPE_RESIZE = 11, - EVENT_TYPE_FLATTEN = 12, - EVENT_TYPE_DEMOTE_PROMOTE = 13, - EVENT_TYPE_SNAP_LIMIT = 14, - EVENT_TYPE_UPDATE_FEATURES = 15, - EVENT_TYPE_METADATA_SET = 16, - EVENT_TYPE_METADATA_REMOVE = 17, - EVENT_TYPE_AIO_WRITESAME = 18, + EVENT_TYPE_AIO_DISCARD = 0, + EVENT_TYPE_AIO_WRITE = 1, + EVENT_TYPE_AIO_FLUSH = 2, + EVENT_TYPE_OP_FINISH = 3, + EVENT_TYPE_SNAP_CREATE = 4, + EVENT_TYPE_SNAP_REMOVE = 5, + EVENT_TYPE_SNAP_RENAME = 6, + EVENT_TYPE_SNAP_PROTECT = 7, + EVENT_TYPE_SNAP_UNPROTECT = 8, + EVENT_TYPE_SNAP_ROLLBACK = 9, + EVENT_TYPE_RENAME = 10, + EVENT_TYPE_RESIZE = 11, + EVENT_TYPE_FLATTEN = 12, + EVENT_TYPE_DEMOTE_PROMOTE = 13, + EVENT_TYPE_SNAP_LIMIT = 14, + EVENT_TYPE_UPDATE_FEATURES = 15, + EVENT_TYPE_METADATA_SET = 16, + EVENT_TYPE_METADATA_REMOVE = 17, + EVENT_TYPE_AIO_WRITESAME = 18, + EVENT_TYPE_AIO_COMPARE_AND_WRITE = 19, }; struct AioDiscardEvent { @@ -102,6 +104,28 @@ struct AioWriteSameEvent { void dump(Formatter *f) const; }; +struct AioCompareAndWriteEvent { + static const EventType TYPE = EVENT_TYPE_AIO_COMPARE_AND_WRITE; + + uint64_t offset; + uint64_t length; + bufferlist cmp_data; + bufferlist write_data; + + static uint32_t get_fixed_size(); + + AioCompareAndWriteEvent() : offset(0), length(0) { + } + AioCompareAndWriteEvent(uint64_t _offset, uint64_t _length, + const bufferlist &_cmp_data, const bufferlist &_write_data) + : offset(_offset), length(_length), cmp_data(_cmp_data), write_data(_write_data) { + } + + void encode(bufferlist& bl) const; + void decode(__u8 version, bufferlist::iterator& it); + void dump(Formatter *f) const; +}; + struct AioFlushEvent { static const EventType TYPE = EVENT_TYPE_AIO_FLUSH; @@ -383,26 +407,28 @@ struct UnknownEvent { void dump(Formatter *f) const; }; -typedef boost::variant Event; +typedef boost::mpl::vector EventVector; +typedef boost::make_variant_over::type Event; struct EventEntry { static uint32_t get_fixed_size() { -- 2.39.5