]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: include advisory `path` field in damage 16106/head
authorJohn Spray <john.spray@redhat.com>
Thu, 23 Mar 2017 13:07:32 +0000 (09:07 -0400)
committerNathan Cutler <ncutler@suse.com>
Tue, 4 Jul 2017 11:16:27 +0000 (13:16 +0200)
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>
(cherry picked from commit c0bff51ef409eb6e4b2fc248e06e5a7e43faf51e)

Conflicts:
    src/mds/CDir.cc - trivial resolution (kraken does not have
        cb86740a5f4aa3eed43c7f09ac5e7e525a5c1d67)

src/mds/CDir.cc
src/mds/DamageTable.cc
src/mds/DamageTable.h
src/mds/MDCache.cc
src/mds/ScrubStack.cc

index f3a7ce8592398128c6640f527e0a6063aab077a4..adabc228d6e63e39404b2e8f3f573ac2135822d3 100644 (file)
@@ -1906,7 +1906,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();
     ceph_abort();  // unreachable, damaged() respawns us
@@ -1915,7 +1915,8 @@ void CDir::go_bad_dentry(snapid_t last, const std::string &dname)
 
 void CDir::go_bad(bool complete)
 {
-  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 58aa0e4ba9390fa542b15750522db1f0013b5c34..2e822cc57d33dd0625eed78d43f5d7d91757febd 100644 (file)
@@ -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<DentryDamage>(
         ino, frag, dname, snap_id);
+    entry->path = path;
     dentries[key][DentryIdent(dname, snap_id)] = entry;
     by_id[entry->id] = std::move(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<DirFragDamage>(ino, frag);
+    entry->path = path;
     dirfrags[key] = entry;
     by_id[entry->id] = std::move(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<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 6a312ba2bd8aed9e9d0236bbe22b638178404a57..e8e5c262dbd94d4b3152bdbdddb7f0408d1937db 100644 (file)
@@ -8243,8 +8243,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 afc91c3961bf754c482e885ecb40ac2fa175d453..1841acf6de5d79c3f3cb21ccc5220a61b98c3beb 100644 (file)
@@ -369,10 +369,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
@@ -380,14 +386,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";