]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include <vector> | |
5 | ||
6 | #include "snap_set_diff.h" | |
7 | #include "common/ceph_context.h" | |
8 | #include "include/rados/librados.hpp" | |
9 | #include "include/interval_set.h" | |
10 | #include "common/debug.h" | |
11 | ||
12 | #define dout_subsys ceph_subsys_rados | |
13 | ||
14 | /** | |
15 | * calculate intervals/extents that vary between two snapshots | |
16 | */ | |
17 | void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set, | |
18 | librados::snap_t start, librados::snap_t end, | |
19 | interval_set<uint64_t> *diff, uint64_t *end_size, | |
94b18763 FG |
20 | bool *end_exists, librados::snap_t *clone_end_snap_id, |
21 | bool *whole_object) | |
7c673cae FG |
22 | { |
23 | ldout(cct, 10) << "calc_snap_set_diff start " << start << " end " << end | |
24 | << ", snap_set seq " << snap_set.seq << dendl; | |
25 | bool saw_start = false; | |
26 | uint64_t start_size = 0; | |
27 | diff->clear(); | |
28 | *end_size = 0; | |
29 | *end_exists = false; | |
30 | *clone_end_snap_id = 0; | |
94b18763 | 31 | *whole_object = false; |
7c673cae FG |
32 | |
33 | for (vector<librados::clone_info_t>::const_iterator r = snap_set.clones.begin(); | |
34 | r != snap_set.clones.end(); | |
35 | ) { | |
36 | // make an interval, and hide the fact that the HEAD doesn't | |
37 | // include itself in the snaps list | |
38 | librados::snap_t a, b; | |
39 | if (r->cloneid == librados::SNAP_HEAD) { | |
40 | // head is valid starting from right after the last seen seq | |
41 | a = snap_set.seq + 1; | |
42 | b = librados::SNAP_HEAD; | |
94b18763 FG |
43 | } else if (r->snaps.empty()) { |
44 | ldout(cct, 1) << "clone " << r->cloneid | |
45 | << ": empty snaps, return whole object" << dendl; | |
46 | *whole_object = true; | |
47 | return; | |
7c673cae FG |
48 | } else { |
49 | a = r->snaps[0]; | |
50 | // note: b might be < r->cloneid if a snap has been trimmed. | |
51 | b = r->snaps[r->snaps.size()-1]; | |
52 | } | |
53 | ldout(cct, 20) << " clone " << r->cloneid << " snaps " << r->snaps | |
54 | << " -> [" << a << "," << b << "]" | |
55 | << " size " << r->size << " overlap to next " << r->overlap << dendl; | |
56 | ||
57 | if (b < start) { | |
58 | // this is before start | |
59 | ++r; | |
60 | continue; | |
61 | } | |
62 | ||
63 | if (!saw_start) { | |
64 | if (start < a) { | |
65 | ldout(cct, 20) << " start, after " << start << dendl; | |
66 | // this means the object didn't exist at start | |
67 | if (r->size) | |
68 | diff->insert(0, r->size); | |
69 | start_size = 0; | |
70 | } else { | |
71 | ldout(cct, 20) << " start" << dendl; | |
72 | start_size = r->size; | |
73 | } | |
74 | saw_start = true; | |
75 | } | |
76 | ||
77 | *end_size = r->size; | |
78 | if (end < a) { | |
79 | ldout(cct, 20) << " past end " << end << ", end object does not exist" << dendl; | |
80 | *end_exists = false; | |
81 | diff->clear(); | |
82 | if (start_size) { | |
83 | diff->insert(0, start_size); | |
84 | } | |
85 | break; | |
86 | } | |
87 | if (end <= b) { | |
88 | ldout(cct, 20) << " end" << dendl; | |
89 | *end_exists = true; | |
90 | *clone_end_snap_id = b; | |
91 | break; | |
92 | } | |
93 | ||
94 | // start with the max(this size, next size), and subtract off any | |
95 | // overlap | |
96 | const vector<pair<uint64_t, uint64_t> > *overlap = &r->overlap; | |
97 | interval_set<uint64_t> diff_to_next; | |
98 | uint64_t max_size = r->size; | |
99 | ++r; | |
100 | if (r != snap_set.clones.end()) { | |
101 | if (r->size > max_size) | |
102 | max_size = r->size; | |
103 | } | |
104 | if (max_size) | |
105 | diff_to_next.insert(0, max_size); | |
106 | for (vector<pair<uint64_t, uint64_t> >::const_iterator p = overlap->begin(); | |
107 | p != overlap->end(); | |
108 | ++p) { | |
109 | diff_to_next.erase(p->first, p->second); | |
110 | } | |
111 | ldout(cct, 20) << " diff_to_next " << diff_to_next << dendl; | |
112 | diff->union_of(diff_to_next); | |
113 | ldout(cct, 20) << " diff now " << *diff << dendl; | |
114 | } | |
115 | } |