void complete(int r) override {
while (true) {
- object_dispatcher->m_lock.get_read();
+ object_dispatcher->m_lock.lock_shared();
auto it = object_dispatcher->m_object_dispatches.upper_bound(
object_dispatch_layer);
if (it == object_dispatcher->m_object_dispatches.end()) {
- object_dispatcher->m_lock.put_read();
+ object_dispatcher->m_lock.unlock_shared();
Context::complete(r);
return;
}
// prevent recursive locking back into the dispatcher while handling IO
object_dispatch_meta.async_op_tracker->start_op();
- object_dispatcher->m_lock.put_read();
+ object_dispatcher->m_lock.unlock_shared();
// next loop should start after current layer
object_dispatch_layer = object_dispatch->get_object_dispatch_layer();
bool operator()(ObjectDispatchSpec::ReadRequest& read) const {
return object_dispatch->read(
- read.oid, read.object_no, read.object_off, read.object_len, read.snap_id,
+ read.object_no, read.object_off, read.object_len, read.snap_id,
object_dispatch_spec->op_flags, object_dispatch_spec->parent_trace,
read.read_data, read.extent_map,
&object_dispatch_spec->object_dispatch_flags,
bool operator()(ObjectDispatchSpec::DiscardRequest& discard) const {
return object_dispatch->discard(
- discard.oid, discard.object_no, discard.object_off, discard.object_len,
- discard.snapc, discard.discard_flags, object_dispatch_spec->parent_trace,
+ discard.object_no, discard.object_off, discard.object_len, discard.snapc,
+ discard.discard_flags, object_dispatch_spec->parent_trace,
&object_dispatch_spec->object_dispatch_flags, &discard.journal_tid,
&object_dispatch_spec->dispatch_result,
&object_dispatch_spec->dispatcher_ctx.on_finish,
bool operator()(ObjectDispatchSpec::WriteRequest& write) const {
return object_dispatch->write(
- write.oid, write.object_no, write.object_off, std::move(write.data),
- write.snapc, object_dispatch_spec->op_flags,
- object_dispatch_spec->parent_trace,
+ write.object_no, write.object_off, std::move(write.data), write.snapc,
+ object_dispatch_spec->op_flags, object_dispatch_spec->parent_trace,
&object_dispatch_spec->object_dispatch_flags, &write.journal_tid,
&object_dispatch_spec->dispatch_result,
&object_dispatch_spec->dispatcher_ctx.on_finish,
bool operator()(ObjectDispatchSpec::WriteSameRequest& write_same) const {
return object_dispatch->write_same(
- write_same.oid, write_same.object_no, write_same.object_off,
- write_same.object_len, std::move(write_same.buffer_extents),
- std::move(write_same.data), write_same.snapc,
- object_dispatch_spec->op_flags, object_dispatch_spec->parent_trace,
+ write_same.object_no, write_same.object_off, write_same.object_len,
+ std::move(write_same.buffer_extents), std::move(write_same.data),
+ write_same.snapc, object_dispatch_spec->op_flags,
+ object_dispatch_spec->parent_trace,
&object_dispatch_spec->object_dispatch_flags, &write_same.journal_tid,
&object_dispatch_spec->dispatch_result,
&object_dispatch_spec->dispatcher_ctx.on_finish,
bool operator()(
ObjectDispatchSpec::CompareAndWriteRequest& compare_and_write) const {
return object_dispatch->compare_and_write(
- compare_and_write.oid, compare_and_write.object_no,
- compare_and_write.object_off, std::move(compare_and_write.cmp_data),
- std::move(compare_and_write.data), compare_and_write.snapc,
- object_dispatch_spec->op_flags, object_dispatch_spec->parent_trace,
- compare_and_write.mismatch_offset,
+ compare_and_write.object_no, compare_and_write.object_off,
+ std::move(compare_and_write.cmp_data), std::move(compare_and_write.data),
+ compare_and_write.snapc, object_dispatch_spec->op_flags,
+ object_dispatch_spec->parent_trace, compare_and_write.mismatch_offset,
&object_dispatch_spec->object_dispatch_flags,
&compare_and_write.journal_tid,
&object_dispatch_spec->dispatch_result,
bool operator()(ObjectDispatchSpec::FlushRequest& flush) const {
return object_dispatch->flush(
flush.flush_source, object_dispatch_spec->parent_trace,
+ &flush.journal_tid,
&object_dispatch_spec->dispatch_result,
&object_dispatch_spec->dispatcher_ctx.on_finish,
&object_dispatch_spec->dispatcher_ctx);
template <typename I>
ObjectDispatcher<I>::ObjectDispatcher(I* image_ctx)
: m_image_ctx(image_ctx),
- m_lock(librbd::util::unique_lock_name("librbd::io::ObjectDispatcher::lock",
- this)) {
+ m_lock(ceph::make_shared_mutex(
+ librbd::util::unique_lock_name("librbd::io::ObjectDispatcher::lock",
+ this))) {
// configure the core object dispatch handler on startup
auto object_dispatch = new ObjectDispatch(image_ctx);
m_object_dispatches[object_dispatch->get_object_dispatch_layer()] =
std::map<ObjectDispatchLayer, ObjectDispatchMeta> object_dispatches;
{
- RWLock::WLocker locker(m_lock);
+ std::unique_lock locker{m_lock};
std::swap(object_dispatches, m_object_dispatches);
}
auto type = object_dispatch->get_object_dispatch_layer();
ldout(cct, 5) << "object_dispatch_layer=" << type << dendl;
- RWLock::WLocker locker(m_lock);
+ std::unique_lock locker{m_lock};
ceph_assert(type < OBJECT_DISPATCH_LAYER_LAST);
auto result = m_object_dispatches.insert(
ObjectDispatchMeta object_dispatch_meta;
{
- RWLock::WLocker locker(m_lock);
+ std::unique_lock locker{m_lock};
auto it = m_object_dispatches.find(object_dispatch_layer);
ceph_assert(it != m_object_dispatches.end());
auto async_op_tracker = object_dispatch_meta.async_op_tracker;
Context* ctx = *on_finish;
- ctx = new FunctionContext(
+ ctx = new LambdaContext(
[object_dispatch, async_op_tracker, ctx](int r) {
delete object_dispatch;
delete async_op_tracker;
ctx->complete(r);
});
- ctx = new FunctionContext([object_dispatch, ctx](int r) {
+ ctx = new LambdaContext([object_dispatch, ctx](int r) {
object_dispatch->shut_down(ctx);
});
- *on_finish = new FunctionContext([async_op_tracker, ctx](int r) {
+ *on_finish = new LambdaContext([async_op_tracker, ctx](int r) {
async_op_tracker->wait_for_ops(ctx);
});
}
// apply the IO request to all layers -- this method will be re-invoked
// by the dispatch layer if continuing / restarting the IO
while (true) {
- m_lock.get_read();
+ m_lock.lock_shared();
object_dispatch_layer = object_dispatch_spec->object_dispatch_layer;
auto it = m_object_dispatches.upper_bound(object_dispatch_layer);
if (it == m_object_dispatches.end()) {
// the request is complete if handled by all layers
object_dispatch_spec->dispatch_result = DISPATCH_RESULT_COMPLETE;
- m_lock.put_read();
+ m_lock.unlock_shared();
break;
}
// prevent recursive locking back into the dispatcher while handling IO
object_dispatch_meta.async_op_tracker->start_op();
- m_lock.put_read();
+ m_lock.unlock_shared();
// advance to next layer in case we skip or continue
object_dispatch_spec->object_dispatch_layer =