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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
// vim: ts=8 sw=2 smarttab
#include <cstring>
#include "fwd.h"
#pragma once
namespace crimson::os::seastore::onode {
class NodeExtent;
/**
* NodeExtentMutable
*
* A thin wrapper of NodeExtent to make sure that only the newly allocated
* or the duplicated NodeExtent is mutable, and the memory modifications are
* safe within the extent range.
*/
class NodeExtentMutable {
public:
void copy_in_absolute(void* dst, const void* src, extent_len_t len) {
assert((char*)dst >= get_write());
assert((char*)dst + len <= buf_upper_bound());
std::memcpy(dst, src, len);
}
template <typename T>
void copy_in_absolute(void* dst, const T& src) {
copy_in_absolute(dst, &src, sizeof(T));
}
const void* copy_in_relative(
extent_len_t dst_offset, const void* src, extent_len_t len) {
auto dst = get_write() + dst_offset;
copy_in_absolute(dst, src, len);
return dst;
}
template <typename T>
const T* copy_in_relative(
extent_len_t dst_offset, const T& src) {
auto dst = copy_in_relative(dst_offset, &src, sizeof(T));
return static_cast<const T*>(dst);
}
void shift_absolute(const void* src, extent_len_t len, int offset) {
assert((const char*)src >= get_write());
assert((const char*)src + len <= buf_upper_bound());
char* to = (char*)src + offset;
assert(to >= get_write());
assert(to + len <= buf_upper_bound());
if (len != 0) {
std::memmove(to, src, len);
}
}
void shift_relative(extent_len_t src_offset, extent_len_t len, int offset) {
shift_absolute(get_write() + src_offset, len, offset);
}
template <typename T>
void validate_inplace_update(const T& updated) {
assert((const char*)&updated >= get_write());
assert((const char*)&updated + sizeof(T) <= buf_upper_bound());
}
const char* get_read() const;
char* get_write();
extent_len_t get_length() const;
laddr_t get_laddr() const;
private:
explicit NodeExtentMutable(NodeExtent&);
const char* buf_upper_bound() const;
NodeExtent& extent;
friend class NodeExtent;
};
}
|