]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
PG::activate(): handle unexpected cached_removed_snaps more gracefully 7309/head
authorAlexey Sheplyakov <asheplyakov@mirantis.com>
Thu, 21 Jan 2016 06:42:09 +0000 (09:42 +0300)
committerAlexey Sheplyakov <asheplyakov@mirantis.com>
Mon, 25 Jan 2016 10:53:52 +0000 (13:53 +0300)
PGPool::update(): ditto

Fixes: #14428
Backport: infernalis, hammer, firefly

Signed-off-by: Alexey Sheplyakov <asheplyakov@mirantis.com>
src/osd/PG.cc

index 88b42d061e233fbaebd61c5f859b980ca51fc62a..bfafd37373a29391db5e4655d83f3fd4a2f7f8d8 100644 (file)
@@ -156,8 +156,18 @@ void PGPool::update(OSDMapRef map)
   name = map->get_pool_name(id);
   if (pi->get_snap_epoch() == map->get_epoch()) {
     pi->build_removed_snaps(newly_removed_snaps);
-    newly_removed_snaps.subtract(cached_removed_snaps);
-    cached_removed_snaps.union_of(newly_removed_snaps);
+    interval_set<snapid_t> intersection;
+    intersection.intersection_of(newly_removed_snaps, cached_removed_snaps);
+    if (intersection == cached_removed_snaps) {
+        newly_removed_snaps.subtract(cached_removed_snaps);
+        cached_removed_snaps.union_of(newly_removed_snaps);
+    } else {
+        lgeneric_subdout(g_ceph_context, osd, 0) << __func__
+          << " cached_removed_snaps shrank from " << cached_removed_snaps
+          << " to " << newly_removed_snaps << dendl;
+        cached_removed_snaps = newly_removed_snaps;
+        newly_removed_snaps.clear();
+    }
     snapc = pi->get_snap_context();
   } else {
     newly_removed_snaps.clear();
@@ -1586,7 +1596,16 @@ void PG::activate(ObjectStore::Transaction& t,
     dout(20) << "activate - purged_snaps " << info.purged_snaps
             << " cached_removed_snaps " << pool.cached_removed_snaps << dendl;
     snap_trimq = pool.cached_removed_snaps;
-    snap_trimq.subtract(info.purged_snaps);
+    interval_set<snapid_t> intersection;
+    intersection.intersection_of(snap_trimq, info.purged_snaps);
+    if (intersection == info.purged_snaps) {
+      snap_trimq.subtract(info.purged_snaps);
+    } else {
+        dout(0) << "warning: info.purged_snaps (" << info.purged_snaps
+                << ") is not a subset of pool.cached_removed_snaps ("
+                << pool.cached_removed_snaps << ")" << dendl;
+        snap_trimq.subtract(intersection);
+    }
     dout(10) << "activate - snap_trimq " << snap_trimq << dendl;
     if (!snap_trimq.empty() && is_clean())
       queue_snap_trim();