]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: include advisory `path` field in damage 14104/head
authorJohn Spray <john.spray@redhat.com>
Thu, 23 Mar 2017 13:07:32 +0000 (09:07 -0400)
committerJohn Spray <john.spray@redhat.com>
Thu, 13 Apr 2017 16:41:11 +0000 (12:41 -0400)
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 <john.spray@redhat.com>
src/mds/CDir.cc
src/mds/DamageTable.cc
src/mds/DamageTable.h
src/mds/MDCache.cc
src/mds/ScrubStack.cc

index bad5c7a7b43bf9868d704287d4130a326ad5e769..14d706fee4cba0e1abb4639578bdd41721ce9521 100644 (file)
@@ -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
index 3e651097d02735d5bfb2f05cf23bfb55550ee1dd..f7d023c1337fccca1a6ba3d23df975088749df2f 100644 (file)
@@ -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<DentryDamage>(
         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<DirFragDamage>(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<BacktraceDamage>(ino);
+    entry->path = path;
     remotes[ino] = entry;
     by_id[entry->id] = std::move(entry);
   }
index 5a988576dbd31faf70189fa8fa053d2e77af1dab..bc6d3bfdae92795c13119ee237781f24629c4540 100644 (file)
@@ -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,
index 88832279d2fd060e0c29acedf7197608b60f0011..5921b4415d32b7664b9aa5a651e097e81de900ab 100644 (file)
@@ -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
index f351597290911761efd64936655f48a3b89c9af3..66a145c3c2293a8c0bf141cc72a57c4a34092763 100644 (file)
@@ -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";