Merge pull request #10281 from vishalkanaujia/wip_inotable_repair

cephfs: Inotable repair during forward scrub

Reviewed-by: John Spray <john.spray@redhat.com>
This commit is contained in:
John Spray 2016-07-28 11:25:18 +01:00 committed by GitHub
commit f742113e6c
3 changed files with 57 additions and 0 deletions

View File

@ -46,6 +46,7 @@
#include "include/assert.h"
#include "mds/MDSContinuation.h"
#include "mds/InoTable.h"
#define dout_subsys ceph_subsys_mds
#undef dout_prefix
@ -3841,6 +3842,37 @@ void CInode::validate_disk_state(CInode::validated_data *results,
}
}
next:
// If the inode's number was free in the InoTable, fix that
// (#15619)
{
const inode_t& inode = in->inode;
MDCache *mdcache = in->mdcache;
InoTable *inotable = mdcache->mds->inotable;
dout(10) << "scrub: inotable ino = 0x" << std::hex << inode.ino << dendl;
dout(10) << "scrub: inotable free says "
<< inotable->is_marked_free(inode.ino) << dendl;
if (inotable->is_marked_free(inode.ino)) {
LogChannelRef clog = in->mdcache->mds->clog;
clog->error() << "scrub: inode wrongly marked free: 0x" << std::hex
<< inode.ino;
if (in->scrub_infop->header && in->scrub_infop->header->repair) {
bool repaired = inotable->repair(inode.ino);
if (repaired) {
clog->error() << "inode table repaired for inode: 0x" << std::hex
<< inode.ino;
inotable->save();
} else {
clog->error() << "Cannot repair inotable while other operations"
" are in progress";
}
}
}
}
// quit if we're a file, or kick off directory checks otherwise
// TODO: validate on-disk inode for non-base directories
if (!in->is_dir()) {

View File

@ -190,3 +190,26 @@ void InoTable::generate_test_instances(list<InoTable*>& ls)
{
ls.push_back(new InoTable());
}
bool InoTable::is_marked_free(inodeno_t id) const
{
return free.contains(id) || projected_free.contains(id);
}
bool InoTable::repair(inodeno_t id)
{
if (projected_version != version) {
// Can't do the repair while other things are in flight
return false;
}
assert(is_marked_free(id));
dout(10) << "repair: before status. ino = 0x" << std::hex << id << " pver =" << projected_version << " ver= " << version << dendl;
free.erase(id);
projected_free.erase(id);
projected_version = ++version;
dout(10) << "repair: after status. ino = 0x" << std::hex <<id << " pver =" << projected_version << " ver= " << version << dendl;
return true;
}

View File

@ -41,6 +41,8 @@ class InoTable : public MDSTable {
void replay_alloc_ids(interval_set<inodeno_t>& inos);
void replay_release_ids(interval_set<inodeno_t>& inos);
void replay_reset();
bool repair(inodeno_t id);
bool is_marked_free(inodeno_t id) const;
void reset_state();
void encode_state(bufferlist& bl) const {