mirror of
https://github.com/ceph/ceph
synced 2024-12-16 16:39:21 +00:00
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:
commit
f742113e6c
@ -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()) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user