summaryrefslogtreecommitdiffstats
path: root/src/crimson/os/seastore/onode_manager/simple-fltree/onode_block.h
blob: 0025d98479de63a1a9b92ac467c22bffa87796dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#include <cstdint>
#include <boost/container/small_vector.hpp>

#include "crimson/os/seastore/transaction_manager.h"
#include "onode_delta.h"

namespace crimson::os::seastore {

// TODO s/CachedExtent/LogicalCachedExtent/
struct OnodeBlock final : LogicalCachedExtent {
  using Ref = TCachedExtentRef<OnodeBlock>;

  template <typename... T>
  OnodeBlock(T&&... t) : LogicalCachedExtent(std::forward<T>(t)...) {}
  OnodeBlock(OnodeBlock&& block) = delete;
  OnodeBlock(const OnodeBlock& block, CachedExtent::share_buffer_t tag) noexcept
    : LogicalCachedExtent{block, tag},
      share_buffer{true}
  {}

  CachedExtentRef duplicate_for_write() final {
    return new OnodeBlock{*this, CachedExtent::share_buffer_t{}};
  }

  // could materialize the pending changes to the underlying buffer here,
  // but since we write the change to the buffer immediately, let skip
  // this for now.
  void prepare_write() final {}

  // queries
  static constexpr extent_types_t TYPE = extent_types_t::ONODE_BLOCK;
  extent_types_t get_type() const final {
    return TYPE;
  }

  // have to stash all the changes before on_delta_write() is called,
  // otherwise we could pollute the extent with pending mutations
  // before the transaction carrying these mutations is committed to
  // disk
  ceph::bufferlist get_delta() final;
  void logical_on_delta_write() final;
  void apply_delta(const ceph::bufferlist &bl) final;

  void sync() {
    apply_pending_changes(false);
  }
  void mutate(delta_t&& d);
  using mutate_func_t = std::function<void (char*, const delta_t&)>;
  void set_delta_applier(mutate_func_t&& func) {
    mutate_func = std::move(func);
  }
private:
  // before looking at the extent, we need to make sure the content is up to date
  void apply_pending_changes(bool do_cleanup);
  // assuming we don't stash too many deltas to a single block
  // otherwise a fullwrite op is necessary
  boost::container::small_vector<std::unique_ptr<delta_t>, 2> deltas;
  mutate_func_t mutate_func;
  bool share_buffer = false;
};

}