]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: catch duplicates in DamageTable 11412/head
authorJohn Spray <john.spray@redhat.com>
Mon, 19 Sep 2016 14:18:24 +0000 (15:18 +0100)
committerLoic Dachary <ldachary@redhat.com>
Tue, 11 Oct 2016 08:34:13 +0000 (10:34 +0200)
There was an implicit assumption in the code that callers
wouldn't hit the notify_*damaged paths twice because they would
have checked is_*_damaged paths first.

However, that's not really true in all cases, e.g. scrub
code isn't required to respect existing damage entries
when trying to load a CDir.

Simply fix this by having the DamageTable notify* functions
check the key they're inserting doesn't already exist.

Fixes: http://tracker.ceph.com/issues/17173
Signed-off-by: John Spray <john.spray@redhat.com>
(cherry picked from commit c9cfaef104e9aaefad55583d7e54f8b4665904b3)

src/mds/DamageTable.cc

index 1c7b1919ab2da098db86fc1a9ca42b7c9811e51f..b8bcdda37d9c4ed813cdf7f77f7303e9b91530b2 100644 (file)
@@ -46,10 +46,13 @@ bool DamageTable::notify_dentry(
     return true;
   }
 
-  DamageEntryRef entry = std::make_shared<DentryDamage>(
-      ino, frag, dname, snap_id);
-  dentries[DirFragIdent(ino, frag)][DentryIdent(dname, snap_id)] = entry;
-  by_id[entry->id] = entry;
+  auto key = DirFragIdent(ino, frag);
+  if (dentries.count(key) == 0) {
+    DamageEntryRef entry = std::make_shared<DentryDamage>(
+        ino, frag, dname, snap_id);
+    dentries[key][DentryIdent(dname, snap_id)] = entry;
+    by_id[entry->id] = entry;
+  }
 
   return false;
 }
@@ -72,9 +75,12 @@ bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag)
     return true;
   }
 
-  DamageEntryRef entry = std::make_shared<DirFragDamage>(ino, frag);
-  dirfrags[DirFragIdent(ino, frag)] = entry;
-  by_id[entry->id] = entry;
+  auto key = DirFragIdent(ino, frag);
+  if (dirfrags.count(key) == 0) {
+    DamageEntryRef entry = std::make_shared<DirFragDamage>(ino, frag);
+    dirfrags[key] = entry;
+    by_id[entry->id] = entry;
+  }
 
   return false;
 }
@@ -85,9 +91,11 @@ bool DamageTable::notify_remote_damaged(inodeno_t ino)
     return true;
   }
 
-  auto entry = std::make_shared<BacktraceDamage>(ino);
-  remotes[ino] = entry;
-  by_id[entry->id] = entry;
+  if (remotes.count(ino) == 0) {
+    auto entry = std::make_shared<BacktraceDamage>(ino);
+    remotes[ino] = entry;
+    by_id[entry->id] = entry;
+  }
 
   return false;
 }