1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 #include <boost/container/small_vector.hpp>
7 #include "crimson/os/seastore/transaction_manager.h"
8 #include "onode_delta.h"
10 namespace crimson::os::seastore
{
12 // TODO s/CachedExtent/LogicalCachedExtent/
13 struct OnodeBlock final
: LogicalCachedExtent
{
14 using Ref
= TCachedExtentRef
<OnodeBlock
>;
16 template <typename
... T
>
17 OnodeBlock(T
&&... t
) : LogicalCachedExtent(std::forward
<T
>(t
)...) {}
18 OnodeBlock(OnodeBlock
&& block
) = delete;
19 OnodeBlock(const OnodeBlock
& block
, CachedExtent::share_buffer_t tag
) noexcept
20 : LogicalCachedExtent
{block
, tag
},
24 CachedExtentRef
duplicate_for_write() final
{
25 return new OnodeBlock
{*this, CachedExtent::share_buffer_t
{}};
28 // could materialize the pending changes to the underlying buffer here,
29 // but since we write the change to the buffer immediately, let skip
31 void prepare_write() final
{}
34 static constexpr extent_types_t TYPE
= extent_types_t::ONODE_BLOCK
;
35 extent_types_t
get_type() const final
{
39 // have to stash all the changes before on_delta_write() is called,
40 // otherwise we could pollute the extent with pending mutations
41 // before the transaction carrying these mutations is committed to
43 ceph::bufferlist
get_delta() final
;
44 void logical_on_delta_write() final
;
45 void apply_delta(const ceph::bufferlist
&bl
) final
;
48 apply_pending_changes(false);
50 void mutate(delta_t
&& d
);
51 using mutate_func_t
= std::function
<void (char*, const delta_t
&)>;
52 void set_delta_applier(mutate_func_t
&& func
) {
53 mutate_func
= std::move(func
);
56 // before looking at the extent, we need to make sure the content is up to date
57 void apply_pending_changes(bool do_cleanup
);
58 // assuming we don't stash too many deltas to a single block
59 // otherwise a fullwrite op is necessary
60 boost::container::small_vector
<std::unique_ptr
<delta_t
>, 2> deltas
;
61 mutate_func_t mutate_func
;
62 bool share_buffer
= false;