From: John Spray Date: Thu, 23 Mar 2017 13:07:32 +0000 (-0400) Subject: mds: include advisory `path` field in damage X-Git-Tag: v12.0.2~45^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c0bff51ef409eb6e4b2fc248e06e5a7e43faf51e;p=ceph.git 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 --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index bad5c7a7b43b..14d706fee4cb 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1958,7 +1958,7 @@ void CDir::go_bad_dentry(snapid_t last, const std::string &dname) { dout(10) << "go_bad_dentry " << dname << dendl; 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(); ceph_abort(); // unreachable, damaged() respawns us @@ -1968,7 +1968,8 @@ void CDir::go_bad_dentry(snapid_t last, const std::string &dname) void CDir::go_bad(bool complete) { dout(10) << "go_bad " << frag << dendl; - 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(); ceph_abort(); // unreachable, damaged() respawns us diff --git a/src/mds/DamageTable.cc b/src/mds/DamageTable.cc index 3e651097d027..f7d023c1337f 100644 --- a/src/mds/DamageTable.cc +++ b/src/mds/DamageTable.cc @@ -50,6 +50,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(); } }; @@ -88,6 +89,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(); } }; @@ -116,6 +118,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(); } }; @@ -126,7 +129,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; @@ -148,6 +151,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] = std::move(entry); } @@ -155,7 +159,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. @@ -176,6 +181,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] = std::move(entry); } @@ -183,7 +189,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; @@ -191,6 +197,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] = std::move(entry); } diff --git a/src/mds/DamageTable.h b/src/mds/DamageTable.h index 5a988576dbd3..bc6d3bfdae92 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 88832279d2fd..5921b4415d32 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -8178,8 +8178,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(); ceph_abort(); // unreachable, damaged() respawns us diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc index f35159729091..66a145c3c229 100644 --- a/src/mds/ScrubStack.cc +++ b/src/mds/ScrubStack.cc @@ -370,10 +370,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 @@ -381,14 +387,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(path, true); clog->warn() << "Scrub error on inode " << *in << " (" << path << ") see " << g_conf->name << " log for details";