]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: for logging generate only 10 final components of dentry path
authorRishabh Dave <ridave@redhat.com>
Thu, 21 Aug 2025 11:51:48 +0000 (17:21 +0530)
committerRishabh Dave <ridave@redhat.com>
Fri, 26 Sep 2025 17:50:44 +0000 (23:20 +0530)
Generating full absolute path for dentries for printing in MDS logs
slows the down the FS to a great extent especially when the path is very
long (imagine a path with 2000 components). Printing such long paths in
MDS logs is not only pointless but also greatly reduces the readability
of MDS logs.

Therefore, generate only 10 final components of the dentry paths for logging.

Fixes: https://tracker.ceph.com/issues/72779
Signed-off-by: Rishabh Dave <ridave@redhat.com>
src/include/filepath.cc
src/include/filepath.h
src/mds/CDentry.cc
src/mds/CDentry.h
src/mds/CInode.cc
src/mds/CInode.h

index 243bf127d0bbc3112fd03f670e0e8a24b7146a6b..f0324f603c4cb209562b47b35eadb96a8b2f0d73 100644 (file)
@@ -41,6 +41,14 @@ void filepath::parse_bits() const {
   }
 }
 
+void filepath::set_trimmed() {
+  if (trimmed)
+    return;
+  // indicates that the path has been shortened.
+  path += "...";
+  trimmed = true;
+}
+
 void filepath::set_path(std::string_view s) {
   if (!s.empty() && s[0] == '/') {
     path = s.substr(1);
index 67be4a08759ab0fd1297d96d107b00e5931e8547..920ffcb95cb44cb10cbda6bc36517a7e58879a78 100644 (file)
@@ -38,6 +38,9 @@ namespace ceph { class Formatter; }
 class filepath {
   inodeno_t ino = 0;   // base inode.  ino=0 implies pure relative path.
   std::string path;     // relative path.
+  // tells get_path() whether it should prefix path with "..." to indicate that
+  // it was shortened.
+  bool trimmed = false;
 
   /** bits - path segments
    * this is ['a', 'b', 'c'] for both the aboslute and relative case.
@@ -82,6 +85,7 @@ class filepath {
   // accessors
   inodeno_t get_ino() const { return ino; }
   const std::string& get_path() const { return path; }
+  void set_trimmed();
   const char *c_str() const { return path.c_str(); }
 
   int length() const { return path.length(); }
index d2796d4c70935d3b0bf00fdf489d520addd40e88..9a593b60be524cc24d1bc32966605dc362f11519 100644 (file)
@@ -85,7 +85,7 @@ const LockType CDentry::versionlock_type(CEPH_LOCK_DVERSION);
 ostream& operator<<(ostream& out, const CDentry& dn)
 {
   filepath path;
-  dn.make_path(path);
+  dn.make_trimmed_path(path);
   
   out << "[dentry " << path;
   
@@ -312,13 +312,44 @@ void CDentry::make_path_string(string& s, bool projected,
   s.append(name.data(), name.length());
 }
 
-void CDentry::make_path(filepath& fp, bool projected) const
+/* path_comp_count = path component count. default value is -1 which implies
+ * generate entire path.
+ */
+void CDentry::make_path(filepath& fp, bool projected,
+                       int path_comp_count) const
 {
-  ceph_assert(dir);
-  dir->inode->make_path(fp, projected);
-  fp.push_dentry(get_name());
+  fp.set_trimmed();
+
+  if (path_comp_count == -1) {
+    ceph_assert(dir);
+    dir->inode->make_path(fp, projected, path_comp_count);
+    fp.push_dentry(get_name());
+  } else if (path_comp_count >= 1) {
+    --path_comp_count;
+
+    ceph_assert(dir);
+    dir->inode->make_path(fp, projected, path_comp_count);
+    fp.push_dentry(get_name());
+  }
 }
 
+/* path_comp_count = path component count. default value is 10 which implies
+ * generate entire path.
+ *
+ * XXX Generating more than 10 components of a path for printing in logs will
+ * consume too much time when the path is too long (imagine a path with 2000
+ * components) since the path would've to be generated indidividually for each
+ * log entry.
+ *
+ * Besides consuming too much time, such long paths in logs are not only not
+ * useful but also it makes reading logs harder. Therefore, shorten the path
+ * when used for logging.
+ */
+void CDentry::make_trimmed_path(filepath& fp, bool projected,
+                               int path_comp_count) const
+{
+  make_path(fp, projected, path_comp_count);
+}
 /*
  * we only add ourselves to remote_parents when the linkage is
  * active (no longer projected).  if the passed dnl is projected,
index 67cf9323666e5741d76074bdbe630cc0392cb598..769ca4bdc75841125ff586ae177456cc651b577a 100644 (file)
@@ -254,7 +254,10 @@ public:
   // misc
   void make_path_string(std::string& s, bool projected=false,
                        int path_comp_count=-1) const;
-  void make_path(filepath& fp, bool projected=false) const;
+  void make_path(filepath& fp, bool projected=false,
+                int path_comp_count=-1) const;
+  void make_trimmed_path(filepath& fp, bool projected=false,
+                        int path_comp_count=10) const;
 
   // -- version --
   version_t get_version() const { return version; }
index 2686e887a7aa333dd3447e5a4063a65045decb8f..a314023d57559def0e7bb33b1718681f444005ab 100644 (file)
@@ -1153,12 +1153,12 @@ void CInode::make_trimmed_path_string(string& s, bool projected,
   make_path_string(s, projected, use_parent, path_comp_count);
 }
 
-void CInode::make_path(filepath& fp, bool projected) const
+void CInode::make_path(filepath& fp, bool projected, int path_comp_count) const
 {
   const CDentry *use_parent = projected ? get_projected_parent_dn() : parent;
   if (use_parent) {
     ceph_assert(!is_base());
-    use_parent->make_path(fp, projected);
+    use_parent->make_path(fp, projected, path_comp_count);
   } else {
     fp = filepath(ino());
   }
index 53ff63ceaefbfbe60fe84862a733953a7bf32e30..2010085701a28dd56d95ea13d2be200be466b0cd 100644 (file)
@@ -745,7 +745,6 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counter<CIno
   void make_path_string(std::string& s, bool projected=false,
                        const CDentry *use_parent=NULL,
                        int path_comp_count=-1) const;
-  void make_path(filepath& s, bool projected=false) const;
   void make_trimmed_path_string(std::string& s, bool projected=false,
                                const CDentry *use_parent=NULL,
                                int path_comp_count=10) const;