void CDir::_committed(int r, version_t v)
{
if (r < 0) {
- dout(1) << "commit error " << r << " v " << v << dendl;
- cache->mds->clog->error() << "failed to commit dir " << dirfrag() << " object,"
- << " errno " << r << "\n";
- cache->mds->handle_write_error(r);
- return;
+ // the directory could be partly purged during MDS failover
+ if (r == -ENOENT && committed_version == 0 &&
+ inode->inode.nlink == 0 && inode->snaprealm) {
+ inode->state_set(CInode::STATE_MISSINGOBJS);
+ r = 0;
+ }
+ if (r < 0) {
+ dout(1) << "commit error " << r << " v " << v << dendl;
+ cache->mds->clog->error() << "failed to commit dir " << dirfrag() << " object,"
+ << " errno " << r << "\n";
+ cache->mds->handle_write_error(r);
+ return;
+ }
}
dout(10) << "_committed v " << v << " on " << *this << dendl;
if (in.state_test(CInode::STATE_NEEDSRECOVER)) out << " needsrecover";
if (in.state_test(CInode::STATE_RECOVERING)) out << " recovering";
if (in.state_test(CInode::STATE_DIRTYPARENT)) out << " dirtyparent";
+ if (in.state_test(CInode::STATE_MISSINGOBJS)) out << " missingobjs";
if (in.is_freezing_inode()) out << " FREEZING=" << in.auth_pin_freeze_allowance;
if (in.is_frozen_inode()) out << " FROZEN";
if (in.is_frozen_auth_pin()) out << " FROZEN_AUTHPIN";
f->dump_string("state", "dirtypool");
if (state_test(STATE_ORPHAN))
f->dump_string("state", "orphan");
+ if (state_test(STATE_MISSINGOBJS))
+ f->dump_string("state", "missingobjs");
f->close_section();
f->open_array_section("client_caps");
static const int STATE_FROZENAUTHPIN = (1<<17);
static const int STATE_DIRTYPOOL = (1<<18);
static const int STATE_REPAIRSTATS = (1<<19);
+ static const int STATE_MISSINGOBJS = (1<<20);
// orphan inode needs notification of releasing reference
static const int STATE_ORPHAN = STATE_NOTIFYREF;
if (in->is_dir()) {
if (in->snaprealm && in->snaprealm->has_past_parents()) {
dout(20) << " directory has past parents "
- << in->snaprealm->srnode.past_parents << dendl;
+ << in->snaprealm->srnode.past_parents << dendl;
+ if (in->state_test(CInode::STATE_MISSINGOBJS)) {
+ mds->clog->error() << "previous attempt at committing dirfrag of ino "
+ << in->ino() << " has failed, missing object\n";
+ mds->handle_write_error(-ENOENT);
+ }
return false; // not until some snaps are deleted.
}