]>
git.proxmox.com Git - ceph.git/blob - ceph/src/osd/SnapMapper.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
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.
15 #include "SnapMapper.h"
17 #define dout_context cct
18 #define dout_subsys ceph_subsys_osd
20 #define dout_prefix *_dout << "snap_mapper."
24 const string
SnapMapper::MAPPING_PREFIX
= "MAP_";
25 const string
SnapMapper::OBJECT_PREFIX
= "OBJ_";
27 int OSDriver::get_keys(
28 const std::set
<std::string
> &keys
,
29 std::map
<std::string
, bufferlist
> *out
)
31 return os
->omap_get_values(cid
, hoid
, keys
, out
);
34 int OSDriver::get_next(
35 const std::string
&key
,
36 pair
<std::string
, bufferlist
> *next
)
38 ObjectMap::ObjectMapIterator iter
=
39 os
->get_omap_iterator(cid
, hoid
);
44 iter
->upper_bound(key
);
47 *next
= make_pair(iter
->key(), iter
->value());
57 explicit Mapping(const pair
<snapid_t
, hobject_t
> &in
)
58 : snap(in
.first
), hoid(in
.second
) {}
59 Mapping() : snap(0) {}
60 void encode(bufferlist
&bl
) const {
61 ENCODE_START(1, 1, bl
);
66 void decode(bufferlist::iterator
&bl
) {
73 WRITE_CLASS_ENCODER(Mapping
)
75 string
SnapMapper::get_prefix(snapid_t snap
)
80 "%.*X_", (int)(sizeof(snap
)*2),
81 static_cast<unsigned>(snap
));
82 return MAPPING_PREFIX
+ string(buf
, len
);
85 string
SnapMapper::to_raw_key(
86 const pair
<snapid_t
, hobject_t
> &in
)
88 return get_prefix(in
.first
) + shard_prefix
+ in
.second
.to_str();
91 pair
<string
, bufferlist
> SnapMapper::to_raw(
92 const pair
<snapid_t
, hobject_t
> &in
)
95 ::encode(Mapping(in
), bl
);
101 pair
<snapid_t
, hobject_t
> SnapMapper::from_raw(
102 const pair
<std::string
, bufferlist
> &image
)
105 bufferlist
bl(image
.second
);
106 bufferlist::iterator
bp(bl
.begin());
108 return make_pair(map
.snap
, map
.hoid
);
111 bool SnapMapper::is_mapping(const string
&to_test
)
113 return to_test
.substr(0, MAPPING_PREFIX
.size()) == MAPPING_PREFIX
;
116 string
SnapMapper::to_object_key(const hobject_t
&hoid
)
118 return OBJECT_PREFIX
+ shard_prefix
+ hoid
.to_str();
121 void SnapMapper::object_snaps::encode(bufferlist
&bl
) const
123 ENCODE_START(1, 1, bl
);
129 void SnapMapper::object_snaps::decode(bufferlist::iterator
&bl
)
137 int SnapMapper::get_snaps(
138 const hobject_t
&oid
,
143 map
<string
, bufferlist
> got
;
144 keys
.insert(to_object_key(oid
));
145 int r
= backend
.get_keys(keys
, &got
);
151 bufferlist::iterator bp
= got
.begin()->second
.begin();
153 dout(20) << __func__
<< " " << oid
<< " " << out
->snaps
<< dendl
;
154 assert(!out
->snaps
.empty());
156 dout(20) << __func__
<< " " << oid
<< " (out == NULL)" << dendl
;
161 void SnapMapper::clear_snaps(
162 const hobject_t
&oid
,
163 MapCacher::Transaction
<std::string
, bufferlist
> *t
)
165 dout(20) << __func__
<< " " << oid
<< dendl
;
167 set
<string
> to_remove
;
168 to_remove
.insert(to_object_key(oid
));
169 if (g_conf
->subsys
.should_gather(ceph_subsys_osd
, 20)) {
170 for (auto& i
: to_remove
) {
171 dout(20) << __func__
<< " rm " << i
<< dendl
;
174 backend
.remove_keys(to_remove
, t
);
177 void SnapMapper::set_snaps(
178 const hobject_t
&oid
,
179 const object_snaps
&in
,
180 MapCacher::Transaction
<std::string
, bufferlist
> *t
)
183 map
<string
, bufferlist
> to_set
;
186 to_set
[to_object_key(oid
)] = bl
;
187 dout(20) << __func__
<< " " << oid
<< " " << in
.snaps
<< dendl
;
188 if (g_conf
->subsys
.should_gather(ceph_subsys_osd
, 20)) {
189 for (auto& i
: to_set
) {
190 dout(20) << __func__
<< " set " << i
.first
<< dendl
;
193 backend
.set_keys(to_set
, t
);
196 int SnapMapper::update_snaps(
197 const hobject_t
&oid
,
198 const set
<snapid_t
> &new_snaps
,
199 const set
<snapid_t
> *old_snaps_check
,
200 MapCacher::Transaction
<std::string
, bufferlist
> *t
)
202 dout(20) << __func__
<< " " << oid
<< " " << new_snaps
203 << " was " << (old_snaps_check
? *old_snaps_check
: set
<snapid_t
>())
206 if (new_snaps
.empty())
207 return remove_oid(oid
, t
);
210 int r
= get_snaps(oid
, &out
);
214 assert(out
.snaps
== *old_snaps_check
);
216 object_snaps
in(oid
, new_snaps
);
217 set_snaps(oid
, in
, t
);
219 set
<string
> to_remove
;
220 for (set
<snapid_t
>::iterator i
= out
.snaps
.begin();
221 i
!= out
.snaps
.end();
223 if (!new_snaps
.count(*i
)) {
224 to_remove
.insert(to_raw_key(make_pair(*i
, oid
)));
227 if (g_conf
->subsys
.should_gather(ceph_subsys_osd
, 20)) {
228 for (auto& i
: to_remove
) {
229 dout(20) << __func__
<< " rm " << i
<< dendl
;
232 backend
.remove_keys(to_remove
, t
);
236 void SnapMapper::add_oid(
237 const hobject_t
&oid
,
238 const set
<snapid_t
>& snaps
,
239 MapCacher::Transaction
<std::string
, bufferlist
> *t
)
241 dout(20) << __func__
<< " " << oid
<< " " << snaps
<< dendl
;
245 int r
= get_snaps(oid
, &out
);
246 assert(r
== -ENOENT
);
249 object_snaps
_snaps(oid
, snaps
);
250 set_snaps(oid
, _snaps
, t
);
252 map
<string
, bufferlist
> to_add
;
253 for (set
<snapid_t
>::iterator i
= snaps
.begin();
256 to_add
.insert(to_raw(make_pair(*i
, oid
)));
258 if (g_conf
->subsys
.should_gather(ceph_subsys_osd
, 20)) {
259 for (auto& i
: to_add
) {
260 dout(20) << __func__
<< " set " << i
.first
<< dendl
;
263 backend
.set_keys(to_add
, t
);
266 int SnapMapper::get_next_objects_to_trim(
269 vector
<hobject_t
> *out
)
272 assert(out
->empty());
274 for (set
<string
>::iterator i
= prefixes
.begin();
275 i
!= prefixes
.end() && out
->size() < max
&& r
== 0;
277 string
prefix(get_prefix(snap
) + *i
);
279 while (out
->size() < max
) {
280 pair
<string
, bufferlist
> next
;
281 r
= backend
.get_next(pos
, &next
);
282 dout(20) << __func__
<< " get_next(" << pos
<< ") returns " << r
283 << " " << next
<< dendl
;
288 if (next
.first
.substr(0, prefix
.size()) !=
290 break; // Done with this prefix
293 assert(is_mapping(next
.first
));
295 dout(20) << __func__
<< " " << next
.first
<< dendl
;
296 pair
<snapid_t
, hobject_t
> next_decoded(from_raw(next
));
297 assert(next_decoded
.first
== snap
);
298 assert(check(next_decoded
.second
));
300 out
->push_back(next_decoded
.second
);
304 if (out
->size() == 0) {
312 int SnapMapper::remove_oid(
313 const hobject_t
&oid
,
314 MapCacher::Transaction
<std::string
, bufferlist
> *t
)
316 dout(20) << __func__
<< " " << oid
<< dendl
;
318 return _remove_oid(oid
, t
);
321 int SnapMapper::_remove_oid(
322 const hobject_t
&oid
,
323 MapCacher::Transaction
<std::string
, bufferlist
> *t
)
325 dout(20) << __func__
<< " " << oid
<< dendl
;
327 int r
= get_snaps(oid
, &out
);
333 set
<string
> to_remove
;
334 for (set
<snapid_t
>::iterator i
= out
.snaps
.begin();
335 i
!= out
.snaps
.end();
337 to_remove
.insert(to_raw_key(make_pair(*i
, oid
)));
339 if (g_conf
->subsys
.should_gather(ceph_subsys_osd
, 20)) {
340 for (auto& i
: to_remove
) {
341 dout(20) << __func__
<< " rm " << i
<< dendl
;
344 backend
.remove_keys(to_remove
, t
);
348 int SnapMapper::get_snaps(
349 const hobject_t
&oid
,
350 std::set
<snapid_t
> *snaps
)
354 int r
= get_snaps(oid
, &out
);
358 snaps
->swap(out
.snaps
);