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
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
f->dump_int("id", id);
f->dump_int("ino", ino);
f->dump_stream("frag") << frag;
+ f->dump_string("path", path);
f->close_section();
}
};
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();
}
};
f->dump_string("damage_type", "backtrace");
f->dump_int("id", id);
f->dump_int("ino", ino);
+ f->dump_string("path", path);
f->close_section();
}
};
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;
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);
}
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.
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);
}
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;
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);
}
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);
*
* @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.
*/
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,
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
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
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";