From d9234d47a9abc290475a317bb3fd070192df1840 Mon Sep 17 00:00:00 2001 From: John Spray Date: Thu, 23 Mar 2017 09:07:32 -0400 Subject: [PATCH] mds: include advisory `path` field in damage This will just be whatever path we were looking at at the point that damage was notified -- no intention whatsoever of providing any up to date path or resolution when there are multiple paths to an inode. Fixes: http://tracker.ceph.com/issues/18509 Signed-off-by: John Spray (cherry picked from commit c0bff51ef409eb6e4b2fc248e06e5a7e43faf51e) Conflicts: src/mds/CDir.cc - omit dout(10) because jewel does not have cb86740a src/mds/ScrubStack.cc - jewel does not have 7b456109 which changed in->make_path_string_projected() call to in->make_path_string() but it's moot because that line is dropped --- src/mds/CDir.cc | 5 +++-- src/mds/DamageTable.cc | 13 ++++++++++--- src/mds/DamageTable.h | 10 +++++++--- src/mds/MDCache.cc | 10 +++++++++- src/mds/ScrubStack.cc | 12 ++++++++---- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 7e9f7cff1ac43..58bf811b53514 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1927,7 +1927,7 @@ void CDir::_go_bad() void CDir::go_bad_dentry(snapid_t last, const std::string &dname) { const bool fatal = cache->mds->damage_table.notify_dentry( - inode->ino(), frag, last, dname); + inode->ino(), frag, last, dname, get_path() + "/" + dname); if (fatal) { cache->mds->damaged(); assert(0); // unreachable, damaged() respawns us @@ -1936,7 +1936,8 @@ void CDir::go_bad_dentry(snapid_t last, const std::string &dname) void CDir::go_bad() { - const bool fatal = cache->mds->damage_table.notify_dirfrag(inode->ino(), frag); + const bool fatal = cache->mds->damage_table.notify_dirfrag( + inode->ino(), frag, get_path()); if (fatal) { cache->mds->damaged(); assert(0); // unreachable, damaged() respawns us diff --git a/src/mds/DamageTable.cc b/src/mds/DamageTable.cc index a24f8c3d2d3bd..727b654bf6f65 100644 --- a/src/mds/DamageTable.cc +++ b/src/mds/DamageTable.cc @@ -49,6 +49,7 @@ class DirFragDamage : public DamageEntry f->dump_int("id", id); f->dump_int("ino", ino); f->dump_stream("frag") << frag; + f->dump_string("path", path); f->close_section(); } }; @@ -87,6 +88,7 @@ class DentryDamage : public DamageEntry f->dump_stream("frag") << frag; f->dump_string("dname", dname); f->dump_stream("snap_id") << snap_id; + f->dump_string("path", path); f->close_section(); } }; @@ -115,6 +117,7 @@ class BacktraceDamage : public DamageEntry f->dump_string("damage_type", "backtrace"); f->dump_int("id", id); f->dump_int("ino", ino); + f->dump_string("path", path); f->close_section(); } }; @@ -125,7 +128,7 @@ DamageEntry::~DamageEntry() bool DamageTable::notify_dentry( inodeno_t ino, frag_t frag, - snapid_t snap_id, const std::string &dname) + snapid_t snap_id, const std::string &dname, const std::string &path) { if (oversized()) { return true; @@ -147,6 +150,7 @@ bool DamageTable::notify_dentry( if (dentries.count(key) == 0) { DamageEntryRef entry = std::make_shared( ino, frag, dname, snap_id); + entry->path = path; dentries[key][DentryIdent(dname, snap_id)] = entry; by_id[entry->id] = entry; } @@ -154,7 +158,8 @@ bool DamageTable::notify_dentry( return false; } -bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag) +bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag, + const std::string &path) { // Special cases: damage to these dirfrags is considered fatal to // the MDS rank that owns them. @@ -175,6 +180,7 @@ bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag) auto key = DirFragIdent(ino, frag); if (dirfrags.count(key) == 0) { DamageEntryRef entry = std::make_shared(ino, frag); + entry->path = path; dirfrags[key] = entry; by_id[entry->id] = entry; } @@ -182,7 +188,7 @@ bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag) return false; } -bool DamageTable::notify_remote_damaged(inodeno_t ino) +bool DamageTable::notify_remote_damaged(inodeno_t ino, const std::string &path) { if (oversized()) { return true; @@ -190,6 +196,7 @@ bool DamageTable::notify_remote_damaged(inodeno_t ino) if (remotes.count(ino) == 0) { auto entry = std::make_shared(ino); + entry->path = path; remotes[ino] = entry; by_id[entry->id] = entry; } diff --git a/src/mds/DamageTable.h b/src/mds/DamageTable.h index 998e0f84ea6d9..dc48807fffdb6 100644 --- a/src/mds/DamageTable.h +++ b/src/mds/DamageTable.h @@ -37,6 +37,10 @@ class DamageEntry damage_entry_id_t id; utime_t reported_at; + // path is optional, advisory. Used to give the admin an idea of what + // part of his tree the damage affects. + std::string path; + DamageEntry() { id = get_random(0, 0xffffffff); @@ -157,7 +161,7 @@ public: * * @return true if fatal */ - bool notify_dirfrag(inodeno_t ino, frag_t frag); + bool notify_dirfrag(inodeno_t ino, frag_t frag, const std::string &path); /** * Indicate that a particular dentry cannot be loaded. @@ -166,13 +170,13 @@ public: */ bool notify_dentry( inodeno_t ino, frag_t frag, - snapid_t snap_id, const std::string &dname); + snapid_t snap_id, const std::string &dname, const std::string &path); /** * Indicate that a particular Inode could not be loaded by number */ bool notify_remote_damaged( - inodeno_t ino); + inodeno_t ino, const std::string &path); bool is_dentry_damaged( const CDir *dir_frag, diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index b31d8879ac709..4857954ed3a01 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -8204,8 +8204,16 @@ void MDCache::_open_remote_dentry_finish(CDentry *dn, inodeno_t ino, MDSInternal if (r < 0) { dout(0) << "open_remote_dentry_finish bad remote dentry " << *dn << dendl; dn->state_set(CDentry::STATE_BADREMOTEINO); + + std::string path; + CDir *dir = dn->get_dir(); + if (dir) { + dir->get_inode()->make_path_string(path); + path = path + "/" + dn->get_name(); + } + bool fatal = mds->damage_table.notify_remote_damaged( - dn->get_projected_linkage()->get_remote_ino()); + dn->get_projected_linkage()->get_remote_ino(), path); if (fatal) { mds->damaged(); assert(0); // unreachable, damaged() respawns us diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc index 911564ea96360..0175c4aec914e 100644 --- a/src/mds/ScrubStack.cc +++ b/src/mds/ScrubStack.cc @@ -380,10 +380,16 @@ void ScrubStack::_validate_inode_done(CInode *in, int r, LogChannelRef clog = mdcache->mds->clog; const ScrubHeaderRefConst header = in->scrub_info()->header; + std::string path; + if (!result.passed_validation) { + // Build path string for use in messages + in->make_path_string(path, true); + } + if (result.backtrace.checked && !result.backtrace.passed) { // Record backtrace fails as remote linkage damage, as // we may not be able to resolve hard links to this inode - mdcache->mds->damage_table.notify_remote_damaged(in->inode.ino); + mdcache->mds->damage_table.notify_remote_damaged(in->inode.ino, path); } else if (result.inode.checked && !result.inode.passed) { // Record damaged inode structures as damaged dentries as // that is where they are stored @@ -391,14 +397,12 @@ void ScrubStack::_validate_inode_done(CInode *in, int r, if (parent) { auto dir = parent->get_dir(); mdcache->mds->damage_table.notify_dentry( - dir->inode->ino(), dir->frag, parent->last, parent->name); + dir->inode->ino(), dir->frag, parent->last, parent->name, path); } } // Inform the cluster log if we found an error if (!result.passed_validation) { - std::string path; - in->make_path_string_projected(path); clog->warn() << "Scrub error on inode " << *in << " (" << path << ") see " << g_conf->name << " log for details"; -- 2.39.5