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