}
}
-void CDentry::make_path_string(string& s, bool projected) const
+void CDentry::make_path_string(string& s, bool projected,
+ int path_comp_count) const
{
if (dir) {
- dir->inode->make_path_string(s, projected);
+ dir->inode->make_path_string(s, projected, NULL, path_comp_count);
} else {
s = "???";
}
const CDentry& operator= (const CDentry& right);
// misc
- void make_path_string(std::string& s, bool projected=false) const;
+ 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;
// -- version --
ostream& operator<<(ostream& out, const CDir& dir)
{
- out << "[dir " << dir.dirfrag() << " " << dir.get_path() << "/"
+ out << "[dir " << dir.dirfrag() << " " << dir.get_trimmed_path() << "/"
<< " [" << dir.first << ",head]";
if (dir.is_auth()) {
out << " auth";
<< " mode " << ref_in->get_inode()->mode
<< " mtime " << ref_in->get_inode()->mtime << dendl;
string dirpath, inopath;
- this->inode->make_path_string(dirpath);
- ref_in->make_path_string(inopath);
+ this->inode->make_trimmed_path_string(dirpath);
+ ref_in->make_trimmed_path_string(inopath);
mdcache->mds->clog->error() << "loaded dup referent inode " << inode_data.inode->ino
<< " [" << first << "," << last << "] v" << inode_data.inode->version
<< " at " << dirpath << "/" << dname
dout(0) << "_fetched missing object for " << *this << dendl;
clog->error() << "dir " << dirfrag() << " object missing on disk; some "
- "files may be lost (" << get_path() << ")";
+ "files may be lost (" << get_trimmed_path() << ")";
go_bad(complete);
return;
derr << "Corrupt fnode in dirfrag " << dirfrag()
<< ": " << err.what() << dendl;
clog->warn() << "Corrupt fnode header in " << dirfrag() << ": "
- << err.what() << " (" << get_path() << ")";
+ << err.what() << " (" << get_trimmed_path() << ")";
go_bad(complete);
return;
}
if (!p.end()) {
clog->warn() << "header buffer of dir " << dirfrag() << " has "
<< hdrbl.length() - p.get_off() << " extra bytes ("
- << get_path() << ")";
+ << get_trimmed_path() << ")";
go_bad(complete);
return;
}
} catch (const buffer::error &err) {
mdcache->mds->clog->warn() << "Corrupt dentry '" << key.name << "' in "
"dir frag " << dirfrag() << ": "
- << err.what() << "(" << get_path() << ")";
+ << err.what() << "(" << get_trimmed_path() << ")";
// Remember that this dentry is damaged. Subsequent operations
// that try to act directly on it will get their EIOs, but this
return good;
}
-std::string CDir::get_path() const
+/* XXX: Return string containing only final 10 components of the path. This
+ * shortened path is to be used usually for only logging. This prevents the
+ * unnecessary generation of full version of a very long path (imagine a path
+ * with 2000 components) from inode because not only repeatedly printing long
+ * path in logs is unnecessary and unreadable but more importantly because it
+ * is an expensive process (since it's done for more or less individual log
+ * entries).
+ */
+std::string CDir::get_trimmed_path() const
+{
+ std::string path;
+ get_inode()->make_trimmed_path_string(path, true);
+ return path;
+}
+
+std::string CDir::get_path(bool trim_path) const
{
std::string path;
get_inode()->make_path_string(path, true);
void steal_dentry(CDentry *dn); // from another dir. used by merge/split.
void finish_old_fragment(std::vector<MDSContext*>& waiters, bool replay);
void init_fragment_pins();
- std::string get_path() const;
+ std::string get_trimmed_path() const;
+ std::string get_path(bool trim_path=false) const;
// -- authority --
/*
ostream& operator<<(ostream& out, const CInode& in)
{
string path;
- in.make_path_string(path, true);
+ in.make_trimmed_path_string(path);
out << "[inode " << in.ino();
out << " ["
* use_parent is NULL and projected is true, the primary parent's projected
* inode is used all the way up the path chain. Otherwise the primary parent
* stable inode is used.
+ *
+ * path_comp_count = path components count. default value is -1, which implies
+ * generate full path.
*/
-void CInode::make_path_string(string& s, bool projected, const CDentry *use_parent) const
+void CInode::make_path_string(string& s, bool projected,
+ const CDentry *use_parent,
+ int path_comp_count) const
{
if (!use_parent) {
use_parent = projected ? get_projected_parent_dn() : parent;
}
if (use_parent) {
- use_parent->make_path_string(s, projected);
+ if (path_comp_count == -1) {
+ use_parent->make_path_string(s, projected, path_comp_count);
+ } else if (path_comp_count >= 1) {
+ --path_comp_count;
+ use_parent->make_path_string(s, projected, path_comp_count);
+ } else if (path_comp_count == 0) {
+ // this indicates that path has been shortened.
+ s = "...";
+ return;
+ }
} else if (is_root()) {
s = "";
} else if (is_mdsdir()) {
}
}
+/* 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.
+ *
+ * path_comp_count = path components count. default value is 10, which implies
+ * generate full path.
+ */
+void CInode::make_trimmed_path_string(string& s, bool projected,
+ const CDentry* use_parent,
+ int path_comp_count) const
+{
+ make_path_string(s, projected, use_parent, path_comp_count);
+}
+
void CInode::make_path(filepath& fp, bool projected) const
{
const CDentry *use_parent = projected ? get_projected_parent_dn() : parent;
if (pi->dirstat.nfiles < 0 || pi->dirstat.nsubdirs < 0) {
std::string path;
- make_path_string(path);
+ make_trimmed_path_string(path);
clog->error() << "Inconsistent statistics detected: fragstat on inode "
<< ino() << " (" << path << "), inode has " << pi->dirstat;
ceph_assert(!"bad/negative fragstat" == g_conf()->mds_verify_scatter);
if (!results->backtrace.passed && in->scrub_infop->header->get_repair()) {
std::string path;
- in->make_path_string(path);
+ in->make_trimmed_path_string(path);
in->mdcache->mds->clog->warn() << "bad backtrace on inode " << in->ino()
<< "(" << path << "), rewriting it";
in->mark_dirty_parent(in->mdcache->mds->mdlog->get_current_segment(),
bool is_ancestor_of(const CInode *other, std::unordered_map<CInode const*,bool>* visited=nullptr) const;
bool is_projected_ancestor_of(const CInode *other) const;
- void make_path_string(std::string& s, bool projected=false, const CDentry *use_parent=NULL) const;
+ 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;
+ void make_path(filepath& s, bool projected=false,
+ int path_comp_count=-1) const;
void name_stray_dentry(std::string& dname);
// -- dirtyness --