-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmetadata.h
175 lines (138 loc) · 4.27 KB
/
metadata.h
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Copyright (C) 2011 Red Hat, Inc. All rights reserved.
//
// This file is part of the thin-provisioning-tools source.
//
// thin-provisioning-tools is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// thin-provisioning-tools is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with thin-provisioning-tools. If not, see
// <http://www.gnu.org/licenses/>.
#ifndef METADATA_LL_H
#define METADATA_LL_H
#include "block.h"
#include "btree.h"
#include "endian_utils.h"
#include "metadata_disk_structures.h"
#include "space_map_disk.h"
#include "transaction_manager.h"
//----------------------------------------------------------------
namespace thin_provisioning {
// FIXME: don't use namespaces in a header
using namespace base;
using namespace persistent_data;
block_address const SUPERBLOCK_LOCATION = 0;
typedef uint64_t sector_t;
typedef uint32_t thin_dev_t;
//------------------------------------------------
class space_map_ref_counter {
public:
space_map_ref_counter(space_map::ptr sm)
: sm_(sm) {
}
void inc(block_address b) {
sm_->inc(b);
}
void dec(block_address b) {
sm_->dec(b);
}
private:
space_map::ptr sm_;
};
struct block_time {
uint64_t block_;
uint32_t time_;
};
class block_time_ref_counter {
public:
block_time_ref_counter(space_map::ptr sm)
: sm_(sm) {
}
void inc(block_time bt) {
sm_->inc(bt.block_);
}
void dec(block_time bt) {
sm_->dec(bt.block_);
}
private:
space_map::ptr sm_;
};
struct block_traits {
typedef base::__le64 disk_type;
typedef block_time value_type;
typedef block_time_ref_counter ref_counter;
static void unpack(disk_type const &disk, value_type &value) {
uint64_t v = to_cpu<uint64_t>(disk);
value.block_ = v >> 24;
value.time_ = v & ((1 << 24) - 1);
}
static void pack(value_type const &value, disk_type &disk) {
uint64_t v = (value.block_ << 24) | value.time_;
disk = base::to_disk<base::__le64>(v);
}
};
//------------------------------------------------
class mtree_ref_counter {
public:
mtree_ref_counter(transaction_manager::ptr tm)
: tm_(tm) {
}
void inc(block_address b) {
}
void dec(block_address b) {
}
private:
transaction_manager::ptr tm_;
};
struct mtree_traits {
typedef base::__le64 disk_type;
typedef uint64_t value_type;
typedef mtree_ref_counter ref_counter;
static void unpack(disk_type const &disk, value_type &value) {
value = base::to_cpu<uint64_t>(disk);
}
static void pack(value_type const &value, disk_type &disk) {
disk = base::to_disk<base::__le64>(value);
}
};
// FIXME: should these be in a sub-namespace?
typedef persistent_data::transaction_manager::ptr tm_ptr;
typedef persistent_data::btree<1, device_details_traits> detail_tree;
typedef persistent_data::btree<1, mtree_traits> dev_tree;
typedef persistent_data::btree<2, block_traits> mapping_tree;
typedef persistent_data::btree<1, block_traits> single_mapping_tree;
// The tools require different interfaces onto the metadata than
// the in kernel driver. This class gives access to the low-level
// implementation of metadata. Implement more specific interfaces
// on top of this.
struct metadata {
enum open_type {
CREATE,
OPEN
};
metadata(std::string const &dev_path, open_type ot,
sector_t data_block_size = 128,
block_address nr_data_blocks = 0); // Only used if CREATE
metadata(std::string const &dev_path, block_address metadata_snap);
void commit();
typedef block_manager<>::read_ref read_ref;
typedef block_manager<>::write_ref write_ref;
typedef boost::shared_ptr<metadata> ptr;
tm_ptr tm_;
superblock sb_;
checked_space_map::ptr metadata_sm_;
checked_space_map::ptr data_sm_;
detail_tree::ptr details_;
dev_tree::ptr mappings_top_level_;
mapping_tree::ptr mappings_;
};
}
//----------------------------------------------------------------
#endif