]> git.proxmox.com Git - ceph.git/blob - ceph/src/osd/SnapMapper.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / osd / SnapMapper.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2013 Inktank Storage, Inc.
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef SNAPMAPPER_H
16 #define SNAPMAPPER_H
17
18 #include <string>
19 #include <set>
20 #include <utility>
21 #include <string.h>
22
23 #include "common/map_cacher.hpp"
24 #include "common/hobject.h"
25 #include "include/buffer.h"
26 #include "include/encoding.h"
27 #include "include/object.h"
28 #include "os/ObjectStore.h"
29
30 class OSDriver : public MapCacher::StoreDriver<std::string, bufferlist> {
31 ObjectStore *os;
32 coll_t cid;
33 ghobject_t hoid;
34
35 public:
36 class OSTransaction : public MapCacher::Transaction<std::string, bufferlist> {
37 friend class OSDriver;
38 coll_t cid;
39 ghobject_t hoid;
40 ObjectStore::Transaction *t;
41 OSTransaction(
42 coll_t cid,
43 const ghobject_t &hoid,
44 ObjectStore::Transaction *t)
45 : cid(cid), hoid(hoid), t(t) {}
46 public:
47 void set_keys(
48 const std::map<std::string, bufferlist> &to_set) override {
49 t->omap_setkeys(cid, hoid, to_set);
50 }
51 void remove_keys(
52 const std::set<std::string> &to_remove) override {
53 t->omap_rmkeys(cid, hoid, to_remove);
54 }
55 void add_callback(
56 Context *c) override {
57 t->register_on_applied(c);
58 }
59 };
60
61 OSTransaction get_transaction(
62 ObjectStore::Transaction *t) {
63 return OSTransaction(cid, hoid, t);
64 }
65
66 OSDriver(ObjectStore *os, coll_t cid, const ghobject_t &hoid) :
67 os(os), cid(cid), hoid(hoid) {}
68 int get_keys(
69 const std::set<std::string> &keys,
70 std::map<std::string, bufferlist> *out) override;
71 int get_next(
72 const std::string &key,
73 pair<std::string, bufferlist> *next) override;
74 };
75
76 /**
77 * SnapMapper
78 *
79 * Manages two mappings:
80 * 1) hobject_t -> {snapid}
81 * 2) snapid -> {hobject_t}
82 *
83 * We accomplish this using two sets of keys:
84 * 1) OBJECT_PREFIX + obj.str() -> encoding of object_snaps
85 * 2) MAPPING_PREFIX + snapid_t + obj.str() -> encoding of pair<snapid_t, obj>
86 *
87 * The on disk strings and encodings are implemented in to_raw, to_raw_key,
88 * from_raw, to_object_key.
89 *
90 * The object -> {snapid} mapping is primarily included so that the
91 * SnapMapper state can be verified against the external PG state during
92 * scrub etc.
93 *
94 * The 2) mapping is arranged such that all objects in a particular
95 * snap will sort together, and so that all objects in a pg for a
96 * particular snap will group under up to 8 prefixes.
97 */
98 class SnapMapper {
99 public:
100 CephContext* cct;
101 struct object_snaps {
102 hobject_t oid;
103 std::set<snapid_t> snaps;
104 object_snaps(hobject_t oid, const std::set<snapid_t> &snaps)
105 : oid(oid), snaps(snaps) {}
106 object_snaps() {}
107 void encode(bufferlist &bl) const;
108 void decode(bufferlist::iterator &bp);
109 };
110
111 private:
112 MapCacher::MapCacher<std::string, bufferlist> backend;
113
114 static const std::string MAPPING_PREFIX;
115 static const std::string OBJECT_PREFIX;
116
117 static std::string get_prefix(snapid_t snap);
118
119 std::string to_raw_key(
120 const std::pair<snapid_t, hobject_t> &to_map);
121
122 std::pair<std::string, bufferlist> to_raw(
123 const std::pair<snapid_t, hobject_t> &to_map);
124
125 static bool is_mapping(const std::string &to_test);
126
127 std::pair<snapid_t, hobject_t> from_raw(
128 const std::pair<std::string, bufferlist> &image);
129
130 std::string to_object_key(const hobject_t &hoid);
131
132 int get_snaps(const hobject_t &oid, object_snaps *out);
133
134 void set_snaps(
135 const hobject_t &oid,
136 const object_snaps &out,
137 MapCacher::Transaction<std::string, bufferlist> *t);
138
139 void clear_snaps(
140 const hobject_t &oid,
141 MapCacher::Transaction<std::string, bufferlist> *t);
142
143 // True if hoid belongs in this mapping based on mask_bits and match
144 bool check(const hobject_t &hoid) const {
145 return hoid.match(mask_bits, match);
146 }
147
148 int _remove_oid(
149 const hobject_t &oid, ///< [in] oid to remove
150 MapCacher::Transaction<std::string, bufferlist> *t ///< [out] transaction
151 );
152
153 public:
154 static string make_shard_prefix(shard_id_t shard) {
155 if (shard == shard_id_t::NO_SHARD)
156 return string();
157 char buf[20];
158 int r = snprintf(buf, sizeof(buf), ".%x", (int)shard);
159 assert(r < (int)sizeof(buf));
160 return string(buf, r) + '_';
161 }
162 uint32_t mask_bits;
163 const uint32_t match;
164 string last_key_checked;
165 const int64_t pool;
166 const shard_id_t shard;
167 const string shard_prefix;
168 SnapMapper(
169 CephContext* cct,
170 MapCacher::StoreDriver<std::string, bufferlist> *driver,
171 uint32_t match, ///< [in] pgid
172 uint32_t bits, ///< [in] current split bits
173 int64_t pool, ///< [in] pool
174 shard_id_t shard ///< [in] shard
175 )
176 : cct(cct), backend(driver), mask_bits(bits), match(match), pool(pool),
177 shard(shard), shard_prefix(make_shard_prefix(shard)) {
178 update_bits(mask_bits);
179 }
180
181 set<string> prefixes;
182 /// Update bits in case of pg split
183 void update_bits(
184 uint32_t new_bits ///< [in] new split bits
185 ) {
186 assert(new_bits >= mask_bits);
187 mask_bits = new_bits;
188 set<string> _prefixes = hobject_t::get_prefixes(
189 mask_bits,
190 match,
191 pool);
192 prefixes.clear();
193 for (set<string>::iterator i = _prefixes.begin();
194 i != _prefixes.end();
195 ++i) {
196 prefixes.insert(shard_prefix + *i);
197 }
198 }
199
200 /// Update snaps for oid, empty new_snaps removes the mapping
201 int update_snaps(
202 const hobject_t &oid, ///< [in] oid to update
203 const std::set<snapid_t> &new_snaps, ///< [in] new snap set
204 const std::set<snapid_t> *old_snaps, ///< [in] old snaps (for debugging)
205 MapCacher::Transaction<std::string, bufferlist> *t ///< [out] transaction
206 ); ///@ return error, 0 on success
207
208 /// Add mapping for oid, must not already be mapped
209 void add_oid(
210 const hobject_t &oid, ///< [in] oid to add
211 const std::set<snapid_t>& new_snaps, ///< [in] snaps
212 MapCacher::Transaction<std::string, bufferlist> *t ///< [out] transaction
213 );
214
215 /// Returns first object with snap as a snap
216 int get_next_objects_to_trim(
217 snapid_t snap, ///< [in] snap to check
218 unsigned max, ///< [in] max to get
219 vector<hobject_t> *out ///< [out] next objects to trim (must be empty)
220 ); ///< @return error, -ENOENT if no more objects
221
222 /// Remove mapping for oid
223 int remove_oid(
224 const hobject_t &oid, ///< [in] oid to remove
225 MapCacher::Transaction<std::string, bufferlist> *t ///< [out] transaction
226 ); ///< @return error, -ENOENT if the object is not mapped
227
228 /// Get snaps for oid
229 int get_snaps(
230 const hobject_t &oid, ///< [in] oid to get snaps for
231 std::set<snapid_t> *snaps ///< [out] snaps
232 ); ///< @return error, -ENOENT if oid is not recorded
233 };
234 WRITE_CLASS_ENCODER(SnapMapper::object_snaps)
235
236 #endif