}
}
+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);
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.
// 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(); }
ostream& operator<<(ostream& out, const CDentry& dn)
{
filepath path;
- dn.make_path(path);
+ dn.make_trimmed_path(path);
out << "[dentry " << path;
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,
// 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; }
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());
}
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;