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
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;
}
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;
}
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;
}
}
}
+ template <typename I>
+ void Replay<I>::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<I>::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<I>::aio_flush(&m_image_ctx, flush_comp, {});
+ }
+}
+
template <typename I>
void Replay<I>::handle_event(const journal::OpFinishEvent &event,
Context *on_ready, Context *on_safe) {
template <typename I>
void Replay<I>::handle_aio_modify_complete(Context *on_ready, Context *on_safe,
- int r) {
+ int r, std::set<int> &filters) {
Mutex::Locker locker(m_lock);
CephContext *cct = m_image_ctx.cct;
ldout(cct, 20) << ": on_ready=" << on_ready << ", "
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);
template <typename I>
io::AioCompletion *
-Replay<I>::create_aio_modify_completion(Context *on_ready, Context *on_safe,
+Replay<I>::create_aio_modify_completion(Context *on_ready,
+ Context *on_safe,
io::aio_type_t aio_type,
- bool *flush_required) {
+ bool *flush_required,
+ std::set<int> &&filters) {
Mutex::Locker locker(m_lock);
CephContext *cct = m_image_ctx.cct;
assert(m_on_aio_ready == nullptr);
// event. when flushed, the completion of the next flush will fire the
// on_safe callback
auto aio_comp = io::AioCompletion::create_and_start<Context>(
- 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;
}
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<int> filters;
+ C_AioModifyComplete(Replay *replay, Context *on_ready,
+ Context *on_safe, std::set<int> &&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);
}
};
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,
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<int> &filters);
void handle_aio_flush_complete(Context *on_flush_safe, Contexts &on_safe_ctxs,
int r);
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<int> &&filters);
io::AioCompletion *create_aio_flush_completion(Context *on_safe);
void handle_aio_completion(io::AioCompletion *aio_comp);
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 {
}
case EVENT_TYPE_AIO_WRITESAME:
event = AioWriteSameEvent();
break;
+ case EVENT_TYPE_AIO_COMPARE_AND_WRITE:
+ event = AioCompareAndWriteEvent();
+ break;
default:
event = UnknownEvent();
break;
case EVENT_TYPE_AIO_WRITESAME:
out << "AioWriteSame";
break;
+ case EVENT_TYPE_AIO_COMPARE_AND_WRITE:
+ out << "AioCompareAndWrite";
+ break;
default:
out << "Unknown (" << static_cast<uint32_t>(type) << ")";
break;
#include <boost/none.hpp>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
+#include <boost/mpl/vector.hpp>
namespace ceph {
class Formatter;
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 {
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;
void dump(Formatter *f) const;
};
-typedef boost::variant<AioDiscardEvent,
- AioWriteEvent,
- AioFlushEvent,
- OpFinishEvent,
- SnapCreateEvent,
- SnapRemoveEvent,
- SnapRenameEvent,
- SnapProtectEvent,
- SnapUnprotectEvent,
- SnapRollbackEvent,
- RenameEvent,
- ResizeEvent,
- FlattenEvent,
- DemotePromoteEvent,
- SnapLimitEvent,
- UpdateFeaturesEvent,
- MetadataSetEvent,
- MetadataRemoveEvent,
- AioWriteSameEvent,
- UnknownEvent> Event;
+typedef boost::mpl::vector<AioDiscardEvent,
+ AioWriteEvent,
+ AioFlushEvent,
+ OpFinishEvent,
+ SnapCreateEvent,
+ SnapRemoveEvent,
+ SnapRenameEvent,
+ SnapProtectEvent,
+ SnapUnprotectEvent,
+ SnapRollbackEvent,
+ RenameEvent,
+ ResizeEvent,
+ FlattenEvent,
+ DemotePromoteEvent,
+ SnapLimitEvent,
+ UpdateFeaturesEvent,
+ MetadataSetEvent,
+ MetadataRemoveEvent,
+ AioWriteSameEvent,
+ AioCompareAndWriteEvent,
+ UnknownEvent> EventVector;
+typedef boost::make_variant_over<EventVector>::type Event;
struct EventEntry {
static uint32_t get_fixed_size() {