summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSamuel Just <sam.just@inktank.com>2013-01-09 19:17:23 -0800
committerSamuel Just <sam.just@inktank.com>2013-01-10 11:02:52 -0800
commit830b8ffa2e53fde37b74de12a053e037ff3f15b0 (patch)
tree8ded5ad8071ece445b55b4518af474737c066d87 /src
parent920f82e805efec2cae05b79c155c07df0f3ed5dd (diff)
downloadceph-830b8ffa2e53fde37b74de12a053e037ff3f15b0.tar.gz
ReplicatedPG: fix snapdir trimming
The previous logic was both complicated and not correct. Consequently, we have been tending to drop snapcollection links in some cases. This has resulted in clones incorrectly not being trimmed. This patch replaces the logic with something less efficient but hopefully a bit clearer. Signed-off-by: Samuel Just <sam.just@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com> (cherry picked from commit 0f42c37359d976d1fe90f2d3b877b9b0268adc0b)
Diffstat (limited to 'src')
-rw-r--r--src/osd/ReplicatedPG.cc37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc
index d9ab6e2012d..6446717e2a5 100644
--- a/src/osd/ReplicatedPG.cc
+++ b/src/osd/ReplicatedPG.cc
@@ -1345,16 +1345,35 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid,
::encode(coi, bl);
t->setattr(coll, coid, OI_ATTR, bl);
- if (oldsnaps[0] != snaps[0]) {
- t->collection_remove(coll_t(info.pgid, oldsnaps[0]), coid);
- if (oldsnaps.size() > 1 && oldsnaps[snaps.size() - 1] != snaps[0] && snaps.size() > 1)
- t->collection_add(coll_t(info.pgid, snaps[0]), coll, coid);
+ set<snapid_t> old_snapdirs, new_snapdirs;
+
+ old_snapdirs.insert(oldsnaps[0]);
+ old_snapdirs.insert(*(oldsnaps.rbegin()));
+
+ new_snapdirs.insert(snaps[0]);
+ new_snapdirs.insert(*(snaps.rbegin()));
+
+ set<snapid_t> to_remove, to_create;
+ for (set<snapid_t>::iterator i = old_snapdirs.begin();
+ i != old_snapdirs.end();
+ ++i) {
+ if (new_snapdirs.count(*i))
+ continue;
+ t->collection_remove(coll_t(info.pgid, *i), coid);
+ to_remove.insert(*i);
}
- if (oldsnaps.size() > 1 && oldsnaps[oldsnaps.size()-1] != snaps[snaps.size()-1]) {
- t->collection_remove(coll_t(info.pgid, oldsnaps[oldsnaps.size()-1]), coid);
- if (snaps.size() > 1)
- t->collection_add(coll_t(info.pgid, snaps[snaps.size()-1]), coll, coid);
- }
+ for (set<snapid_t>::iterator i = new_snapdirs.begin();
+ i != new_snapdirs.end();
+ ++i) {
+ if (old_snapdirs.count(*i))
+ continue;
+ t->collection_add(coll_t(info.pgid, *i), coll, coid);
+ to_create.insert(*i);
+ }
+
+ dout(10) << "removing coid " << coid << " from snap collections "
+ << to_remove << " and adding to snap collections "
+ << to_create << dendl;
ctx->log.push_back(pg_log_entry_t(pg_log_entry_t::MODIFY, coid, coi.version, coi.prior_version,
osd_reqid_t(), ctx->mtime));