From 8123a931cf54968a0ffb0e4183f59ca4b3c6251d Mon Sep 17 00:00:00 2001 From: Rishabh Dave Date: Tue, 2 Sep 2025 23:07:36 +0530 Subject: [PATCH] client: trim path before logging it Path can be virtually infinitely long and logging a long long path (imagine around 2000 path components) is un-useful as well as lowers readability of the log. Therefore, trim before logging. Fixes: https://tracker.ceph.com/issues/72993 Signed-off-by: Rishabh Dave (cherry picked from commit bdc8aae400fbbdd61df811455d49176deab1f331) Conflicts: src/include/filepath.cc src/include/filepath.h - Unlink main branch, filepath.cc is absent in this branch. Therefore, the changes must be moved to filepath.h. --- src/client/Client.cc | 18 +++++++++++++----- src/client/Client.h | 2 +- src/include/filepath.h | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index e76cd9abc50..4e7e5ad2865 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -7663,7 +7663,10 @@ int Client::path_walk(InodeRef dirinode, const filepath& origpath, InodeRef *end return rc; } -int Client::path_walk(InodeRef dirinode, const filepath& origpath, walk_dentry_result* result, const UserPerm& perms, const PathWalk_ExtraOptions& extra_options) +int Client::path_walk(InodeRef dirinode, const filepath& origpath, + walk_dentry_result* result, const UserPerm& perms, + const PathWalk_ExtraOptions& extra_options, + std::string trimmed_path) { int rc = 0; filepath path = origpath; @@ -7687,7 +7690,11 @@ int Client::path_walk(InodeRef dirinode, const filepath& origpath, walk_dentry_r int symlinks = 0; unsigned i = 0; - ldout(cct, 10) << __func__ << ": cur=" << *diri << " path=" << path << dendl; + if (trimmed_path == "") { + std::string trimmed_path = path.get_trimmed_path(); + } + + ldout(cct, 10) << __func__ << ": cur=" << *diri << " path=" << trimmed_path << dendl; if (path.depth() == 0) { /* diri/dname can also be used as a filepath; or target */ @@ -7701,7 +7708,7 @@ int Client::path_walk(InodeRef dirinode, const filepath& origpath, walk_dentry_r int caps = 0; dname = path[i]; ldout(cct, 10) << " " << i << " " << *diri << " " << dname << dendl; - ldout(cct, 20) << " (path is " << path << ")" << dendl; + ldout(cct, 20) << " (path is " << trimmed_path << ")" << dendl; InodeRef next; if (should_check_perms()) { int r = may_lookup(diri.get(), perms); @@ -15305,11 +15312,12 @@ int Client::ll_unlink(Inode *in, const char *name, const UserPerm& perm) int Client::_rmdir(Inode *dir, const char *name, const UserPerm& perms, bool check_perms) { - ldout(cct, 8) << "_rmdir(" << dir->ino << " " << name << " uid " + std::string trimmed_path = filepath(name).get_trimmed_path(); + ldout(cct, 8) << "_rmdir(" << dir->ino << " " << trimmed_path << " uid " << perms.uid() << " gid " << perms.gid() << ")" << dendl; walk_dentry_result wdr; - if (int rc = path_walk(dir, filepath(name), &wdr, perms, {.followsym = false}); rc < 0) { + if (int rc = path_walk(dir, filepath(name), &wdr, perms, {.followsym = false}, trimmed_path); rc < 0) { return rc; } diff --git a/src/client/Client.h b/src/client/Client.h index 1569fed6be5..a5f6c56d2a3 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1062,7 +1062,7 @@ protected: bool is_rename = false; bool require_target = true; }; - int path_walk(InodeRef dirinode, const filepath& fp, struct walk_dentry_result* result, const UserPerm& perms, const PathWalk_ExtraOptions& extra_options); + int path_walk(InodeRef dirinode, const filepath& fp, struct walk_dentry_result* result, const UserPerm& perms, const PathWalk_ExtraOptions& extra_options, std::string trimmed_path=std::string()); int path_walk(InodeRef dirinode, const filepath& fp, InodeRef *end, const UserPerm& perms, const PathWalk_ExtraOptions& extra_options); // fake inode number for 32-bits ino_t diff --git a/src/include/filepath.h b/src/include/filepath.h index 92d4b06b2b0..be13ad427fa 100644 --- a/src/include/filepath.h +++ b/src/include/filepath.h @@ -104,6 +104,21 @@ class filepath { trimmed = true; } + /* Trim given path to final 10 components and return it by prefixing it with + * "..." to indicate that the path has been trimmed. */ + std::string get_trimmed_path() const + { + std::size_t n = 0; + for (int i = 1; i <= 10; ++i) { + n = path.rfind("/", n - 1); + if (n == std::string::npos) { + return std::string(path); + } + } + + return std::string("..." + path.substr(n, -1)); + } + void set_path(std::string_view s, inodeno_t b) { path = s; ino = b; -- 2.39.5