mirror of
https://github.com/ceph/ceph
synced 2025-02-07 19:03:18 +00:00
Merge pull request #8180 from ukernel/jewel-15167
Be more careful about directory fragmentation and scrubbing Reviewed-by: John Spray <john.spray@redhat.com> Reviewed-by: Greg Farnum <gfarnum@redhat.com>
This commit is contained in:
commit
0831e5944c
@ -4173,12 +4173,10 @@ void CInode::scrub_initialize(CDentry *scrub_parent,
|
||||
MDSInternalContextBase *f)
|
||||
{
|
||||
dout(20) << __func__ << " with scrub_version " << get_version() << dendl;
|
||||
assert(!scrub_infop || !scrub_infop->scrub_in_progress);
|
||||
assert(!scrub_is_in_progress());
|
||||
scrub_info();
|
||||
if (!scrub_infop)
|
||||
scrub_infop = new scrub_info_t();
|
||||
else
|
||||
assert(!scrub_infop->scrub_in_progress);
|
||||
|
||||
if (get_projected_inode()->is_dir()) {
|
||||
// fill in dirfrag_stamps with initial state
|
||||
@ -4210,7 +4208,7 @@ void CInode::scrub_initialize(CDentry *scrub_parent,
|
||||
int CInode::scrub_dirfrag_next(frag_t* out_dirfrag)
|
||||
{
|
||||
dout(20) << __func__ << dendl;
|
||||
assert(scrub_infop && scrub_infop->scrub_in_progress);
|
||||
assert(scrub_is_in_progress());
|
||||
|
||||
if (!is_dir()) {
|
||||
return -ENOTDIR;
|
||||
@ -4258,7 +4256,7 @@ void CInode::scrub_dirfrags_scrubbing(list<frag_t>* out_dirfrags)
|
||||
void CInode::scrub_dirfrag_finished(frag_t dirfrag)
|
||||
{
|
||||
dout(20) << __func__ << " on frag " << dirfrag << dendl;
|
||||
assert(scrub_infop && scrub_infop->scrub_in_progress);
|
||||
assert(scrub_is_in_progress());
|
||||
|
||||
std::map<frag_t, scrub_stamp_info_t>::iterator i =
|
||||
scrub_infop->dirfrag_stamps.find(dirfrag);
|
||||
@ -4271,7 +4269,7 @@ void CInode::scrub_dirfrag_finished(frag_t dirfrag)
|
||||
|
||||
void CInode::scrub_finished(MDSInternalContextBase **c) {
|
||||
dout(20) << __func__ << dendl;
|
||||
assert(scrub_info()->scrub_in_progress);
|
||||
assert(scrub_is_in_progress());
|
||||
for (std::map<frag_t, scrub_stamp_info_t>::iterator i =
|
||||
scrub_infop->dirfrag_stamps.begin();
|
||||
i != scrub_infop->dirfrag_stamps.end();
|
||||
|
@ -288,6 +288,10 @@ public:
|
||||
scrub_info_create();
|
||||
return scrub_infop;
|
||||
}
|
||||
|
||||
bool scrub_is_in_progress() const {
|
||||
return (scrub_infop && scrub_infop->scrub_in_progress);
|
||||
}
|
||||
/**
|
||||
* Start scrubbing on this inode. That could be very short if it's
|
||||
* a file, or take a long time if we're recursively scrubbing a directory.
|
||||
|
@ -10569,6 +10569,11 @@ bool MDCache::can_fragment(CInode *diri, list<CDir*>& dirs)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (diri->scrub_is_in_progress()) {
|
||||
dout(7) << "can_fragment: scrub in progress" << dendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (list<CDir*>::iterator p = dirs.begin(); p != dirs.end(); ++p) {
|
||||
CDir *dir = *p;
|
||||
if (dir->state_test(CDir::STATE_FRAGMENTING)) {
|
||||
|
@ -146,11 +146,15 @@ void ScrubStack::scrub_dir_inode(CInode *in,
|
||||
++i) {
|
||||
// turn frags into CDir *
|
||||
CDir *dir = in->get_dirfrag(*i);
|
||||
scrubbing_cdirs.push_back(dir);
|
||||
dout(25) << __func__ << " got CDir " << *dir << " presently scrubbing" << dendl;
|
||||
if (dir) {
|
||||
scrubbing_cdirs.push_back(dir);
|
||||
dout(25) << __func__ << " got CDir " << *dir << " presently scrubbing" << dendl;
|
||||
} else {
|
||||
in->scrub_dirfrag_finished(*i);
|
||||
dout(25) << __func__ << " missing dirfrag " << *i << " skip scrubbing" << dendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dout(20) << __func__ << " consuming from " << scrubbing_cdirs.size()
|
||||
<< " scrubbing cdirs" << dendl;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user