ldout(cct, 20) << "object_no=" << object_no << " " << object_off << "~"
<< object_len << dendl;
- return dispatch_io(object_no, object_off, object_len, dispatch_result,
+ return dispatch_io(object_no, object_off, object_len, 0, dispatch_result,
on_finish, on_dispatched);
}
ldout(cct, 20) << "object_no=" << object_no << " " << object_off << "~"
<< data.length() << dendl;
- return dispatch_io(object_no, object_off, data.length(), dispatch_result,
- on_finish, on_dispatched);
+ return dispatch_io(object_no, object_off, data.length(), op_flags,
+ dispatch_result, on_finish, on_dispatched);
}
template <typename I>
ldout(cct, 20) << "object_no=" << object_no << " " << object_off << "~"
<< object_len << dendl;
- return dispatch_io(object_no, object_off, object_len, dispatch_result,
+ return dispatch_io(object_no, object_off, object_len, 0, dispatch_result,
on_finish, on_dispatched);
}
template <typename I>
bool WriteAroundObjectDispatch<I>::dispatch_io(
uint64_t object_no, uint64_t object_off, uint64_t object_len,
- io::DispatchResult* dispatch_result, Context** on_finish,
+ int op_flags, io::DispatchResult* dispatch_result, Context** on_finish,
Context* on_dispatched) {
auto cct = m_image_ctx->cct;
return false;
}
+ if ((op_flags & LIBRADOS_OP_FLAG_FADVISE_FUA) != 0) {
+ // force unit access flag is set -- disable write-around
+ m_lock.Unlock();
+ return dispatch_unoptimized_io(object_no, object_off, object_len,
+ dispatch_result, on_dispatched);
+ }
+
auto tid = ++m_last_tid;
auto ctx = util::create_async_context_callback(*m_image_ctx, *on_finish);
io::DispatchResult* dispatch_result,
Context* on_dispatched);
bool dispatch_io(uint64_t object_no, uint64_t object_off,
- uint64_t object_len, io::DispatchResult* dispatch_result,
- Context** on_finish, Context* on_dispatch);
+ uint64_t object_len, int op_flags,
+ io::DispatchResult* dispatch_result, Context** on_finish,
+ Context* on_dispatch);
bool block_overlapping_io(InFlightObjectExtents* in_flight_object_extents,
uint64_t object_off, uint64_t object_len);
finish_ctx_ptr2->complete(0);
}
+TEST_F(TestMockCacheWriteAroundObjectDispatch, FUA) {
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockTestImageCtx mock_image_ctx(*ictx);
+ MockWriteAroundObjectDispatch object_dispatch(&mock_image_ctx, 16384, false);
+
+ InSequence seq;
+
+ bufferlist data;
+ data.append(std::string(4096, '1'));
+
+ io::DispatchResult dispatch_result;
+ MockContext finish_ctx;
+ MockContext dispatch_ctx;
+ Context* finish_ctx_ptr = &finish_ctx;
+ ASSERT_FALSE(object_dispatch.write("oid", 0, 0, std::move(data), {},
+ LIBRADOS_OP_FLAG_FADVISE_FUA, {},
+ nullptr, nullptr, &dispatch_result,
+ &finish_ctx_ptr, &dispatch_ctx));
+ ASSERT_EQ(finish_ctx_ptr, &finish_ctx);
+}
+
} // namespace cache
} // namespace librbd