Merge pull request #14104 from jcsp/wip-18509

mds: include advisory `path` field in damage

Reviewed-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
John Spray 2017-04-18 12:48:52 +01:00 committed by GitHub
commit a762ad4d7f
5 changed files with 37 additions and 13 deletions

View File

@ -1958,7 +1958,7 @@ void CDir::go_bad_dentry(snapid_t last, const std::string &dname)
{
dout(10) << "go_bad_dentry " << dname << dendl;
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
@ -1968,7 +1968,8 @@ void CDir::go_bad_dentry(snapid_t last, const std::string &dname)
void CDir::go_bad(bool complete)
{
dout(10) << "go_bad " << frag << dendl;
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

View File

@ -50,6 +50,7 @@ class DirFragDamage : public DamageEntry
f->dump_int("id", id);
f->dump_int("ino", ino);
f->dump_stream("frag") << frag;
f->dump_string("path", path);
f->close_section();
}
};
@ -88,6 +89,7 @@ class DentryDamage : public DamageEntry
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();
}
};
@ -116,6 +118,7 @@ class BacktraceDamage : public DamageEntry
f->dump_string("damage_type", "backtrace");
f->dump_int("id", id);
f->dump_int("ino", ino);
f->dump_string("path", path);
f->close_section();
}
};
@ -126,7 +129,7 @@ DamageEntry::~DamageEntry()
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;
@ -148,6 +151,7 @@ bool DamageTable::notify_dentry(
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);
}
@ -155,7 +159,8 @@ bool DamageTable::notify_dentry(
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.
@ -176,6 +181,7 @@ bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag)
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);
}
@ -183,7 +189,7 @@ bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag)
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;
@ -191,6 +197,7 @@ bool DamageTable::notify_remote_damaged(inodeno_t ino)
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);
}

View File

@ -37,6 +37,10 @@ class DamageEntry
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);
@ -157,7 +161,7 @@ public:
*
* @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.
@ -166,13 +170,13 @@ public:
*/
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,

View File

@ -8178,8 +8178,16 @@ void MDCache::_open_remote_dentry_finish(CDentry *dn, inodeno_t ino, MDSInternal
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

View File

@ -370,10 +370,16 @@ void ScrubStack::_validate_inode_done(CInode *in, int r,
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
@ -381,14 +387,12 @@ void ScrubStack::_validate_inode_done(CInode *in, int r,
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";