]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ReplicatedPG: fix snapdir trimming
authorSamuel Just <sam.just@inktank.com>
Thu, 10 Jan 2013 03:17:23 +0000 (19:17 -0800)
committerSamuel Just <sam.just@inktank.com>
Thu, 10 Jan 2013 19:02:52 +0000 (11:02 -0800)
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)

src/osd/ReplicatedPG.cc

index d9ab6e2012de1ed949127cb2cbd6ef1504b103e6..6446717e2a5b24af646eaa19a3c98ca1d1d02d19 100644 (file)
@@ -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));