summaryrefslogtreecommitdiffstats
path: root/src/librados
diff options
context:
space:
mode:
Diffstat (limited to 'src/librados')
-rw-r--r--src/librados/RadosClient.cc18
-rw-r--r--src/librados/RadosClient.h2
-rw-r--r--src/librados/librados_cxx.cc9
-rw-r--r--src/librados/snap_set_diff.cc67
4 files changed, 62 insertions, 34 deletions
diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc
index 9abd923f9..db9143e2d 100644
--- a/src/librados/RadosClient.cc
+++ b/src/librados/RadosClient.cc
@@ -631,16 +631,22 @@ int librados::RadosClient::get_pool_stats(std::list<string>& pools,
return 0;
}
-bool librados::RadosClient::get_pool_is_selfmanaged_snaps_mode(
+int librados::RadosClient::pool_is_in_selfmanaged_snaps_mode(
const std::string& pool)
{
- bool ret = false;
- objecter->with_osdmap([&](const OSDMap& osdmap) {
+ int r = wait_for_osdmap();
+ if (r < 0) {
+ return r;
+ }
+
+ return objecter->with_osdmap([&pool](const OSDMap& osdmap) {
int64_t poolid = osdmap.lookup_pg_pool_name(pool);
- if (poolid >= 0)
- ret = osdmap.get_pg_pool(poolid)->is_unmanaged_snaps_mode();
+ if (poolid < 0) {
+ return -ENOENT;
+ }
+ return static_cast<int>(
+ osdmap.get_pg_pool(poolid)->is_unmanaged_snaps_mode());
});
- return ret;
}
int librados::RadosClient::get_fs_stats(ceph_statfs& stats)
diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h
index 052249a76..a93f81851 100644
--- a/src/librados/RadosClient.h
+++ b/src/librados/RadosClient.h
@@ -131,7 +131,7 @@ public:
int get_pool_stats(std::list<std::string>& ls, std::map<std::string,::pool_stat_t> *result,
bool *per_pool);
int get_fs_stats(ceph_statfs& result);
- bool get_pool_is_selfmanaged_snaps_mode(const std::string& pool);
+ int pool_is_in_selfmanaged_snaps_mode(const std::string& pool);
/*
-1 was set as the default value and monitor will pickup the right crush rule with below order:
diff --git a/src/librados/librados_cxx.cc b/src/librados/librados_cxx.cc
index d20c67556..926ddf86d 100644
--- a/src/librados/librados_cxx.cc
+++ b/src/librados/librados_cxx.cc
@@ -2719,9 +2719,16 @@ int librados::Rados::get_pool_stats(std::list<string>& v,
return -EOPNOTSUPP;
}
+// deprecated, use pool_is_in_selfmanaged_snaps_mode() instead
bool librados::Rados::get_pool_is_selfmanaged_snaps_mode(const std::string& pool)
{
- return client->get_pool_is_selfmanaged_snaps_mode(pool);
+ // errors are ignored, prone to false negative results
+ return client->pool_is_in_selfmanaged_snaps_mode(pool) > 0;
+}
+
+int librados::Rados::pool_is_in_selfmanaged_snaps_mode(const std::string& pool)
+{
+ return client->pool_is_in_selfmanaged_snaps_mode(pool);
}
int librados::Rados::cluster_stat(cluster_stat_t& result)
diff --git a/src/librados/snap_set_diff.cc b/src/librados/snap_set_diff.cc
index 06f76b023..42d78eb03 100644
--- a/src/librados/snap_set_diff.cc
+++ b/src/librados/snap_set_diff.cc
@@ -31,9 +31,8 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
*clone_end_snap_id = 0;
*whole_object = false;
- for (vector<librados::clone_info_t>::const_iterator r = snap_set.clones.begin();
- r != snap_set.clones.end();
- ) {
+ auto r = snap_set.clones.begin();
+ while (r != snap_set.clones.end()) {
// make an interval, and hide the fact that the HEAD doesn't
// include itself in the snaps list
librados::snap_t a, b;
@@ -76,42 +75,58 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
saw_start = true;
}
- *end_size = r->size;
if (end < a) {
- ldout(cct, 20) << " past end " << end << ", end object does not exist" << dendl;
- *end_exists = false;
- diff->clear();
- if (start_size) {
- diff->insert(0, start_size);
- }
break;
}
if (end <= b) {
ldout(cct, 20) << " end" << dendl;
+ *end_size = r->size;
*end_exists = true;
*clone_end_snap_id = b;
- break;
+ return;
}
- // start with the max(this size, next size), and subtract off any
- // overlap
+ // start with the largest possible diff to next, and subtract off
+ // any overlap
const vector<pair<uint64_t, uint64_t> > *overlap = &r->overlap;
interval_set<uint64_t> diff_to_next;
- uint64_t max_size = r->size;
+ uint64_t diff_boundary;
+ uint64_t prev_size = r->size;
++r;
if (r != snap_set.clones.end()) {
- if (r->size > max_size)
- max_size = r->size;
- }
- if (max_size)
- diff_to_next.insert(0, max_size);
- for (vector<pair<uint64_t, uint64_t> >::const_iterator p = overlap->begin();
- p != overlap->end();
- ++p) {
- diff_to_next.erase(p->first, p->second);
+ if (r->size >= prev_size) {
+ diff_boundary = r->size;
+ } else if (prev_size <= start_size) {
+ // truncated range below size at start
+ diff_boundary = prev_size;
+ } else {
+ // truncated range (partially) above size at start -- drop that
+ // part from the running diff
+ diff_boundary = std::max(r->size, start_size);
+ ldout(cct, 20) << " no more diff beyond " << diff_boundary << dendl;
+ diff->erase(diff_boundary, prev_size - diff_boundary);
+ }
+ if (diff_boundary) {
+ diff_to_next.insert(0, diff_boundary);
+ }
+ for (auto p = overlap->begin(); p != overlap->end(); ++p) {
+ diff_to_next.erase(p->first, p->second);
+ }
+ ldout(cct, 20) << " diff_to_next " << diff_to_next << dendl;
+ diff->union_of(diff_to_next);
+ ldout(cct, 20) << " diff now " << *diff << dendl;
}
- ldout(cct, 20) << " diff_to_next " << diff_to_next << dendl;
- diff->union_of(diff_to_next);
- ldout(cct, 20) << " diff now " << *diff << dendl;
+ }
+
+ if (r != snap_set.clones.end()) {
+ ldout(cct, 20) << " past end " << end
+ << ", end object does not exist" << dendl;
+ } else {
+ ldout(cct, 20) << " ran out of clones before reaching end " << end
+ << ", end object does not exist" << dendl;
+ }
+ diff->clear();
+ if (start_size) {
+ diff->insert(0, start_size);
}
}