1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
12 #define dout_subsys ceph_subsys_rados
15 * calculate intervals/extents that vary between two snapshots
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,
20 bool *end_exists, librados::snap_t *clone_end_snap_id)
22 ldout(cct, 10) << "calc_snap_set_diff start " << start << " end " << end
23 << ", snap_set seq " << snap_set.seq << dendl;
24 bool saw_start = false;
25 uint64_t start_size = 0;
29 *clone_end_snap_id = 0;
31 for (vector<librados::clone_info_t>::const_iterator r = snap_set.clones.begin();
32 r != snap_set.clones.end();
34 // make an interval, and hide the fact that the HEAD doesn't
35 // include itself in the snaps list
36 librados::snap_t a, b;
37 if (r->cloneid == librados::SNAP_HEAD) {
38 // head is valid starting from right after the last seen seq
40 b = librados::SNAP_HEAD;
43 // note: b might be < r->cloneid if a snap has been trimmed.
44 b = r->snaps[r->snaps.size()-1];
46 ldout(cct, 20) << " clone " << r->cloneid << " snaps " << r->snaps
47 << " -> [" << a << "," << b << "]"
48 << " size " << r->size << " overlap to next " << r->overlap << dendl;
51 // this is before start
58 ldout(cct, 20) << " start, after " << start << dendl;
59 // this means the object didn't exist at start
61 diff->insert(0, r->size);
64 ldout(cct, 20) << " start" << dendl;
72 ldout(cct, 20) << " past end " << end << ", end object does not exist" << dendl;
76 diff->insert(0, start_size);
81 ldout(cct, 20) << " end" << dendl;
83 *clone_end_snap_id = b;
87 // start with the max(this size, next size), and subtract off any
89 const vector<pair<uint64_t, uint64_t> > *overlap = &r->overlap;
90 interval_set<uint64_t> diff_to_next;
91 uint64_t max_size = r->size;
93 if (r != snap_set.clones.end()) {
94 if (r->size > max_size)
98 diff_to_next.insert(0, max_size);
99 for (vector<pair<uint64_t, uint64_t> >::const_iterator p = overlap->begin();
102 diff_to_next.erase(p->first, p->second);
104 ldout(cct, 20) << " diff_to_next " << diff_to_next << dendl;
105 diff->union_of(diff_to_next);
106 ldout(cct, 20) << " diff now " << *diff << dendl;