From 3320da0adb346af15a5d50a45e0aea5ca234eb79 Mon Sep 17 00:00:00 2001 From: John Spray Date: Mon, 19 Sep 2016 15:18:24 +0100 Subject: [PATCH] mds: catch duplicates in DamageTable 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 (cherry picked from commit c9cfaef104e9aaefad55583d7e54f8b4665904b3) --- src/mds/DamageTable.cc | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/mds/DamageTable.cc b/src/mds/DamageTable.cc index 1c7b1919ab2d..b8bcdda37d9c 100644 --- a/src/mds/DamageTable.cc +++ b/src/mds/DamageTable.cc @@ -46,10 +46,13 @@ bool DamageTable::notify_dentry( return true; } - DamageEntryRef entry = std::make_shared( - 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( + 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(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(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(ino); - remotes[ino] = entry; - by_id[entry->id] = entry; + if (remotes.count(ino) == 0) { + auto entry = std::make_shared(ino); + remotes[ino] = entry; + by_id[entry->id] = entry; + } return false; } -- 2.47.3