const std::string &oid,
uint64_t object_no,
const ::SnapContext &snapc,
+ const ZTracer::Trace &parent_trace,
Context *completion) {
assert(s_instance != nullptr);
s_instance->on_finish = completion;
uint64_t object_no,
uint64_t object_off,
const ::SnapContext &snapc,
+ const ZTracer::Trace &parent_trace,
Context *completion) {
assert(s_instance != nullptr);
s_instance->on_finish = completion;
uint64_t object_no,
uint64_t object_off,
const ceph::bufferlist &data,
- const ::SnapContext &snapc,
- Context *completion, int op_flags) {
+ const ::SnapContext &snapc, int op_flags,
+ const ZTracer::Trace &parent_trace,
+ Context *completion) {
assert(s_instance != nullptr);
s_instance->on_finish = completion;
return s_instance;
uint64_t object_no, uint64_t object_off,
uint64_t object_len,
const ::SnapContext &snapc,
+ const ZTracer::Trace &parent_trace,
Context *completion) {
assert(s_instance != nullptr);
s_instance->on_finish = completion;
uint64_t object_len,
const ceph::bufferlist &data,
const ::SnapContext &snapc,
- Context *completion, int op_flags) {
+ int op_flags,
+ const ZTracer::Trace &parent_trace,
+ Context *completion) {
+ assert(s_instance != nullptr);
+ s_instance->on_finish = completion;
+ return s_instance;
+ }
+
+ static ObjectRequest* create_compare_and_write(librbd::MockTestImageCtx *ictx,
+ const std::string &oid,
+ uint64_t object_no,
+ uint64_t object_off,
+ const ceph::bufferlist &cmp_data,
+ const ceph::bufferlist &write_data,
+ const ::SnapContext &snapc,
+ uint64_t *mismatch_offset,
+ int op_flags,
+ const ZTracer::Trace &parent_trace,
+ Context *completion) {
assert(s_instance != nullptr);
s_instance->on_finish = completion;
return s_instance;
uint64_t objectno, uint64_t offset,
uint64_t len, Extents &buffer_extents,
librados::snap_t snap_id, bool sparse,
- Context *completion, int op_flags) {
+ int op_flags,
+ const ZTracer::Trace &parent_trace,
+ Context *completion) {
assert(s_instance != nullptr);
s_instance->on_finish = completion;
return s_instance;
typedef ImageDiscardRequest<librbd::MockTestImageCtx> MockImageDiscardRequest;
typedef ImageFlushRequest<librbd::MockTestImageCtx> MockImageFlushRequest;
typedef ImageWriteSameRequest<librbd::MockTestImageCtx> MockImageWriteSameRequest;
+ typedef ImageCompareAndWriteRequest<librbd::MockTestImageCtx> MockImageCompareAndWriteRequest;
typedef ObjectRequest<librbd::MockTestImageCtx> MockObjectRequest;
typedef ObjectReadRequest<librbd::MockTestImageCtx> MockObjectReadRequest;
uint64_t offset, uint64_t length,
uint64_t journal_tid, int r) {
EXPECT_CALL(mock_image_ctx, write_to_cache(object, _, length, offset, _, _,
- journal_tid))
+ journal_tid, _))
.WillOnce(WithArg<4>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
}
InSequence seq;
expect_is_journal_appending(mock_journal, false);
- expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
- 0, 1, 0, 0);
+ if (mock_image_ctx.image_ctx->cache) {
+ expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
+ 0, 1, 0, 0);
+ } else {
+ expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
+ }
C_SaferCond aio_comp_ctx;
AioCompletion *aio_comp = AioCompletion::create_and_start(
bufferlist bl;
bl.append("1");
MockImageWriteRequest mock_aio_image_write(mock_image_ctx, aio_comp,
- {{0, 1}}, std::move(bl), 0);
+ {{0, 1}}, std::move(bl), 0, {});
{
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
mock_aio_image_write.send();
AioCompletion *aio_comp = AioCompletion::create_and_start(
&aio_comp_ctx, ictx, AIO_TYPE_DISCARD);
MockImageDiscardRequest mock_aio_image_discard(mock_image_ctx, aio_comp,
- 0, 1, ictx->skip_partial_discard);
+ 0, 1,
+ ictx->skip_partial_discard,
+ {});
{
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
mock_aio_image_discard.send();
C_SaferCond aio_comp_ctx;
AioCompletion *aio_comp = AioCompletion::create_and_start(
&aio_comp_ctx, ictx, AIO_TYPE_FLUSH);
- MockImageFlushRequest mock_aio_image_flush(mock_image_ctx, aio_comp);
+ MockImageFlushRequest mock_aio_image_flush(mock_image_ctx, aio_comp, {});
{
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
mock_aio_image_flush.send();
InSequence seq;
expect_is_journal_appending(mock_journal, false);
- expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
- 0, 1, 0, 0);
+ if (mock_image_ctx.image_ctx->cache) {
+ expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
+ 0, 1, 0, 0);
+ } else {
+ expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
+ }
+
C_SaferCond aio_comp_ctx;
AioCompletion *aio_comp = AioCompletion::create_and_start(
bufferlist bl;
bl.append("1");
MockImageWriteSameRequest mock_aio_image_writesame(mock_image_ctx, aio_comp,
- 0, 1, std::move(bl), 0);
+ 0, 1, std::move(bl), 0,
+ {});
{
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
mock_aio_image_writesame.send();
ASSERT_EQ(0, aio_comp_ctx.wait());
}
+TEST_F(TestMockIoImageRequest, AioCompareAndWriteJournalAppendDisabled) {
+ REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockObjectRequest mock_aio_object_request;
+ MockTestImageCtx mock_image_ctx(*ictx);
+ MockJournal mock_journal;
+ mock_image_ctx.journal = &mock_journal;
+
+ InSequence seq;
+ expect_is_journal_appending(mock_journal, false);
+ expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
+
+ C_SaferCond aio_comp_ctx;
+ AioCompletion *aio_comp = AioCompletion::create_and_start(
+ &aio_comp_ctx, ictx, AIO_TYPE_COMPARE_AND_WRITE);
+
+ bufferlist cmp_bl;
+ cmp_bl.append("1");
+ bufferlist write_bl;
+ write_bl.append("1");
+ uint64_t mismatch_offset;
+ MockImageCompareAndWriteRequest mock_aio_image_write(mock_image_ctx, aio_comp,
+ {{0, 1}}, std::move(cmp_bl),
+ std::move(write_bl),
+ &mismatch_offset,
+ 0, {});
+ {
+ RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
+ mock_aio_image_write.send();
+ }
+ ASSERT_EQ(0, aio_comp_ctx.wait());
+}
+
} // namespace io
} // namespace librbd