1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "ImageWriteback.h"
5 #include "include/buffer.h"
6 #include "common/dout.h"
7 #include "librbd/ImageCtx.h"
8 #include "librbd/Utils.h"
9 #include "librbd/io/AioCompletion.h"
10 #include "librbd/io/ImageDispatchSpec.h"
11 #include "librbd/io/ImageRequest.h"
12 #include "librbd/io/ReadResult.h"
15 #define dout_subsys ceph_subsys_rbd
17 #define dout_prefix *_dout << "librbd::ImageWriteback: " << __func__ << ": "
23 ImageWriteback
<I
>::ImageWriteback(I
&image_ctx
) : m_image_ctx(image_ctx
) {
27 void ImageWriteback
<I
>::aio_read(Extents
&&image_extents
, bufferlist
*bl
,
28 int fadvise_flags
, Context
*on_finish
) {
29 CephContext
*cct
= m_image_ctx
.cct
;
30 ldout(cct
, 20) << "image_extents=" << image_extents
<< ", "
31 << "on_finish=" << on_finish
<< dendl
;
33 ImageCtx
*image_ctx
= util::get_image_ctx(&m_image_ctx
);
34 auto aio_comp
= io::AioCompletion::create_and_start(
35 on_finish
, image_ctx
, io::AIO_TYPE_READ
);
37 auto req
= io::ImageDispatchSpec::create_read(
38 *image_ctx
, io::IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE
, aio_comp
,
39 std::move(image_extents
), io::ImageArea::DATA
, io::ReadResult
{bl
},
40 image_ctx
->get_data_io_context(), fadvise_flags
, 0, trace
);
45 void ImageWriteback
<I
>::aio_write(Extents
&&image_extents
,
46 ceph::bufferlist
&& bl
,
47 int fadvise_flags
, Context
*on_finish
) {
48 CephContext
*cct
= m_image_ctx
.cct
;
49 ldout(cct
, 20) << "image_extents=" << image_extents
<< ", "
50 << "on_finish=" << on_finish
<< dendl
;
52 ImageCtx
*image_ctx
= util::get_image_ctx(&m_image_ctx
);
53 auto aio_comp
= io::AioCompletion::create_and_start(
54 on_finish
, image_ctx
, io::AIO_TYPE_WRITE
);
56 auto req
= io::ImageDispatchSpec::create_write(
57 *image_ctx
, io::IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE
, aio_comp
,
58 std::move(image_extents
), io::ImageArea::DATA
, std::move(bl
),
59 fadvise_flags
, trace
);
64 void ImageWriteback
<I
>::aio_discard(uint64_t offset
, uint64_t length
,
65 uint32_t discard_granularity_bytes
,
67 CephContext
*cct
= m_image_ctx
.cct
;
68 ldout(cct
, 20) << "offset=" << offset
<< ", "
69 << "length=" << length
<< ", "
70 << "on_finish=" << on_finish
<< dendl
;
72 ImageCtx
*image_ctx
= util::get_image_ctx(&m_image_ctx
);
73 auto aio_comp
= io::AioCompletion::create_and_start(
74 on_finish
, image_ctx
, io::AIO_TYPE_DISCARD
);
76 auto req
= io::ImageDispatchSpec::create_discard(
77 *image_ctx
, io::IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE
, aio_comp
,
78 {{offset
, length
}}, io::ImageArea::DATA
, discard_granularity_bytes
, trace
);
83 void ImageWriteback
<I
>::aio_flush(io::FlushSource flush_source
,
85 CephContext
*cct
= m_image_ctx
.cct
;
86 ldout(cct
, 20) << "on_finish=" << on_finish
<< dendl
;
88 ImageCtx
*image_ctx
= util::get_image_ctx(&m_image_ctx
);
89 auto aio_comp
= io::AioCompletion::create_and_start(
90 on_finish
, image_ctx
, io::AIO_TYPE_FLUSH
);
93 auto req
= io::ImageDispatchSpec::create_flush(
94 *image_ctx
, io::IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE
, aio_comp
,
100 void ImageWriteback
<I
>::aio_writesame(uint64_t offset
, uint64_t length
,
101 ceph::bufferlist
&& bl
,
102 int fadvise_flags
, Context
*on_finish
) {
103 CephContext
*cct
= m_image_ctx
.cct
;
104 ldout(cct
, 20) << "offset=" << offset
<< ", "
105 << "length=" << length
<< ", "
106 << "data_len=" << bl
.length() << ", "
107 << "on_finish=" << on_finish
<< dendl
;
109 ImageCtx
*image_ctx
= util::get_image_ctx(&m_image_ctx
);
110 auto aio_comp
= io::AioCompletion::create_and_start(
111 on_finish
, image_ctx
, io::AIO_TYPE_WRITESAME
);
112 ZTracer::Trace trace
;
113 auto req
= io::ImageDispatchSpec::create_write_same(
114 *image_ctx
, io::IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE
, aio_comp
,
115 {{offset
, length
}}, io::ImageArea::DATA
, std::move(bl
),
116 fadvise_flags
, trace
);
120 template <typename I
>
121 void ImageWriteback
<I
>::aio_compare_and_write(Extents
&&image_extents
,
122 ceph::bufferlist
&& cmp_bl
,
123 ceph::bufferlist
&& bl
,
124 uint64_t *mismatch_offset
,
126 Context
*on_finish
) {
127 CephContext
*cct
= m_image_ctx
.cct
;
128 ldout(cct
, 20) << "image_extents=" << image_extents
<< ", "
129 << "on_finish=" << on_finish
<< dendl
;
131 ImageCtx
*image_ctx
= util::get_image_ctx(&m_image_ctx
);
132 auto aio_comp
= io::AioCompletion::create_and_start(
133 on_finish
, image_ctx
, io::AIO_TYPE_COMPARE_AND_WRITE
);
134 ZTracer::Trace trace
;
135 auto req
= io::ImageDispatchSpec::create_compare_and_write(
136 *image_ctx
, io::IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE
, aio_comp
,
137 std::move(image_extents
), io::ImageArea::DATA
, std::move(cmp_bl
),
138 std::move(bl
), mismatch_offset
, fadvise_flags
, trace
);
143 } // namespace librbd
145 template class librbd::cache::ImageWriteback
<librbd::ImageCtx
>;