/
ImageCtx.h
315 lines (268 loc) · 10.5 KB
/
ImageCtx.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_LIBRBD_IMAGECTX_H
#define CEPH_LIBRBD_IMAGECTX_H
#include "include/int_types.h"
#include <list>
#include <map>
#include <string>
#include <vector>
#include "common/event_socket.h"
#include "common/Mutex.h"
#include "common/Readahead.h"
#include "common/RWLock.h"
#include "common/snap_types.h"
#include "include/buffer_fwd.h"
#include "include/rbd/librbd.hpp"
#include "include/rbd_types.h"
#include "include/types.h"
#include "include/xlist.h"
#include "osdc/ObjectCacher.h"
#include "cls/rbd/cls_rbd_client.h"
#include "librbd/AsyncRequest.h"
#include "librbd/SnapInfo.h"
#include "librbd/parent_types.h"
class CephContext;
class ContextWQ;
class Finisher;
class PerfCounters;
class ThreadPool;
class SafeTimer;
namespace librbd {
struct ImageCtx;
class AioCompletion;
class AioImageRequestWQ;
class AsyncOperation;
class CopyupRequest;
template <typename> class ExclusiveLock;
template <typename> class ImageState;
template <typename> class ImageWatcher;
template <typename> class Journal;
class LibrbdAdminSocketHook;
class ObjectMap;
template <typename> class Operations;
class LibrbdWriteback;
namespace exclusive_lock { struct Policy; }
namespace journal { struct Policy; }
namespace operation {
template <typename> class ResizeRequest;
}
struct ImageCtx {
CephContext *cct;
PerfCounters *perfcounter;
struct rbd_obj_header_ondisk header;
::SnapContext snapc;
std::vector<librados::snap_t> snaps; // this mirrors snapc.snaps, but is in
// a format librados can understand
std::map<librados::snap_t, SnapInfo> snap_info;
std::map<std::string, librados::snap_t> snap_ids;
uint64_t snap_id;
bool snap_exists; // false if our snap_id was deleted
// whether the image was opened read-only. cannot be changed after opening
bool read_only;
bool flush_encountered;
std::map<rados::cls::lock::locker_id_t,
rados::cls::lock::locker_info_t> lockers;
bool exclusive_locked;
std::string lock_tag;
std::string name;
std::string snap_name;
IoCtx data_ctx, md_ctx;
ImageWatcher<ImageCtx> *image_watcher;
Journal<ImageCtx> *journal;
/**
* Lock ordering:
*
* owner_lock, md_lock, cache_lock, snap_lock, parent_lock,
* object_map_lock, async_op_lock
*/
RWLock owner_lock; // protects exclusive lock leadership updates
RWLock md_lock; // protects access to the mutable image metadata that
// isn't guarded by other locks below, and blocks writes
// when held exclusively, so snapshots can be consistent.
// Fields guarded include:
// flush_encountered
// total_bytes_read
// exclusive_locked
// lock_tag
// lockers
Mutex cache_lock; // used as client_lock for the ObjectCacher
RWLock snap_lock; // protects snapshot-related member variables,
// features (and associated helper classes), and flags
RWLock parent_lock; // protects parent_md and parent
RWLock object_map_lock; // protects object map updates and object_map itself
Mutex async_ops_lock; // protects async_ops and async_requests
Mutex copyup_list_lock; // protects copyup_waiting_list
Mutex completed_reqs_lock; // protects completed_reqs
unsigned extra_read_flags;
bool old_format;
uint8_t order;
uint64_t size;
uint64_t features;
std::string object_prefix;
char *format_string;
std::string header_oid;
std::string id; // only used for new-format images
parent_info parent_md;
ImageCtx *parent;
cls::rbd::GroupSpec group_spec;
uint64_t stripe_unit, stripe_count;
uint64_t flags;
file_layout_t layout;
ObjectCacher *object_cacher;
LibrbdWriteback *writeback_handler;
ObjectCacher::ObjectSet *object_set;
Readahead readahead;
uint64_t total_bytes_read;
std::map<uint64_t, CopyupRequest*> copyup_list;
xlist<AsyncOperation*> async_ops;
xlist<AsyncRequest<>*> async_requests;
std::list<Context*> async_requests_waiters;
ImageState<ImageCtx> *state;
Operations<ImageCtx> *operations;
ExclusiveLock<ImageCtx> *exclusive_lock;
ObjectMap *object_map;
xlist<operation::ResizeRequest<ImageCtx>*> resize_reqs;
AioImageRequestWQ *aio_work_queue;
xlist<AioCompletion*> completed_reqs;
EventSocket event_socket;
ContextWQ *op_work_queue;
// Configuration
static const string METADATA_CONF_PREFIX;
bool non_blocking_aio;
bool cache;
bool cache_writethrough_until_flush;
uint64_t cache_size;
uint64_t cache_max_dirty;
uint64_t cache_target_dirty;
double cache_max_dirty_age;
uint32_t cache_max_dirty_object;
bool cache_block_writes_upfront;
uint32_t concurrent_management_ops;
bool balance_snap_reads;
bool localize_snap_reads;
bool balance_parent_reads;
bool localize_parent_reads;
uint32_t readahead_trigger_requests;
uint64_t readahead_max_bytes;
uint64_t readahead_disable_after_bytes;
bool clone_copy_on_read;
bool blacklist_on_break_lock;
uint32_t blacklist_expire_seconds;
uint32_t request_timed_out_seconds;
bool enable_alloc_hint;
uint8_t journal_order;
uint8_t journal_splay_width;
double journal_commit_age;
int journal_object_flush_interval;
uint64_t journal_object_flush_bytes;
double journal_object_flush_age;
std::string journal_pool;
uint32_t journal_max_payload_bytes;
int journal_max_concurrent_object_sets;
bool mirroring_resync_after_disconnect;
LibrbdAdminSocketHook *asok_hook;
exclusive_lock::Policy *exclusive_lock_policy = nullptr;
journal::Policy *journal_policy = nullptr;
static bool _filter_metadata_confs(const string &prefix, std::map<string, bool> &configs,
const map<string, bufferlist> &pairs, map<string, bufferlist> *res);
// unit test mock helpers
static ImageCtx* create(const std::string &image_name,
const std::string &image_id,
const char *snap, IoCtx& p, bool read_only) {
return new ImageCtx(image_name, image_id, snap, p, read_only);
}
void destroy() {
delete this;
}
/**
* Either image_name or image_id must be set.
* If id is not known, pass the empty std::string,
* and init() will look it up.
*/
ImageCtx(const std::string &image_name, const std::string &image_id,
const char *snap, IoCtx& p, bool read_only);
~ImageCtx();
void init();
void shutdown();
void init_layout();
void perf_start(std::string name);
void perf_stop();
void set_read_flag(unsigned flag);
int get_read_flags(librados::snap_t snap_id);
int snap_set(std::string in_snap_name);
void snap_unset();
librados::snap_t get_snap_id(std::string in_snap_name) const;
const SnapInfo* get_snap_info(librados::snap_t in_snap_id) const;
int get_snap_name(librados::snap_t in_snap_id,
std::string *out_snap_name) const;
int get_parent_spec(librados::snap_t in_snap_id,
parent_spec *pspec) const;
int is_snap_protected(librados::snap_t in_snap_id,
bool *is_protected) const;
int is_snap_unprotected(librados::snap_t in_snap_id,
bool *is_unprotected) const;
uint64_t get_current_size() const;
uint64_t get_object_size() const;
string get_object_name(uint64_t num) const;
uint64_t get_stripe_unit() const;
uint64_t get_stripe_count() const;
uint64_t get_stripe_period() const;
void add_snap(std::string in_snap_name, librados::snap_t id,
uint64_t in_size, parent_info parent,
uint8_t protection_status, uint64_t flags);
void rm_snap(std::string in_snap_name, librados::snap_t id);
uint64_t get_image_size(librados::snap_t in_snap_id) const;
uint64_t get_object_count(librados::snap_t in_snap_id) const;
bool test_features(uint64_t test_features) const;
bool test_features(uint64_t test_features,
const RWLock &in_snap_lock) const;
int get_flags(librados::snap_t in_snap_id, uint64_t *flags) const;
bool test_flags(uint64_t test_flags) const;
bool test_flags(uint64_t test_flags, const RWLock &in_snap_lock) const;
int update_flags(librados::snap_t in_snap_id, uint64_t flag, bool enabled);
const parent_info* get_parent_info(librados::snap_t in_snap_id) const;
int64_t get_parent_pool_id(librados::snap_t in_snap_id) const;
std::string get_parent_image_id(librados::snap_t in_snap_id) const;
uint64_t get_parent_snap_id(librados::snap_t in_snap_id) const;
int get_parent_overlap(librados::snap_t in_snap_id,
uint64_t *overlap) const;
void aio_read_from_cache(object_t o, uint64_t object_no, bufferlist *bl,
size_t len, uint64_t off, Context *onfinish,
int fadvise_flags);
void write_to_cache(object_t o, const bufferlist& bl, size_t len,
uint64_t off, Context *onfinish, int fadvise_flags,
uint64_t journal_tid);
void user_flushed();
void flush_cache(Context *onfinish);
void shut_down_cache(Context *on_finish);
int invalidate_cache(bool purge_on_error=false);
void invalidate_cache(Context *on_finish);
void clear_nonexistence_cache();
void register_watch(Context *on_finish);
uint64_t prune_parent_extents(vector<pair<uint64_t,uint64_t> >& objectx,
uint64_t overlap);
void flush_async_operations();
void flush_async_operations(Context *on_finish);
int flush();
void flush(Context *on_safe);
void cancel_async_requests();
void cancel_async_requests(Context *on_finish);
void apply_metadata(const std::map<std::string, bufferlist> &meta);
ExclusiveLock<ImageCtx> *create_exclusive_lock();
ObjectMap *create_object_map(uint64_t snap_id);
Journal<ImageCtx> *create_journal();
void clear_pending_completions();
void set_image_name(const std::string &name);
void notify_update();
void notify_update(Context *on_finish);
exclusive_lock::Policy *get_exclusive_lock_policy() const;
void set_exclusive_lock_policy(exclusive_lock::Policy *policy);
journal::Policy *get_journal_policy() const;
void set_journal_policy(journal::Policy *policy);
static ThreadPool *get_thread_pool_instance(CephContext *cct);
static void get_timer_instance(CephContext *cct, SafeTimer **timer,
Mutex **timer_lock);
};
}
#endif