}
void CDentry::scrub_initialize(CDir *parent, bool recurse, bool children,
- ScrubHeaderRefConst header,
+ const ScrubHeaderRefConst& header,
Context *f)
{
if (!scrub_infop)
return scrub_infop;
}
void scrub_initialize(CDir *parent, bool recurse, bool children,
- ScrubHeaderRefConst header,
+ const ScrubHeaderRefConst& header,
Context *f);
void scrub_finished(Context **c);
void scrub_children_finished() {
// Whether we have a tag to apply depends on ScrubHeader (if one is
// present)
- if (in->get_parent_dn() != nullptr &&
- in->get_parent_dn()->scrub_info()->header != nullptr) {
+ if (in->scrub_infop && in->scrub_infop->header) {
// I'm a non-orphan, so look up my ScrubHeader via my linkage
- const std::string &tag = in->get_parent_dn()->scrub_info()->header->tag;
+ const std::string &tag = in->scrub_infop->header->tag;
// Rather than using the usual CInode::fetch_backtrace,
// use a special variant that optionally writes a tag in the same
// operation.
}
}
-void CInode::scrub_initialize(version_t scrub_version)
+void CInode::scrub_initialize(const ScrubHeaderRefConst& header)
{
- dout(20) << __func__ << " with scrub_version "
- << scrub_version << dendl;
+ dout(20) << __func__ << " with scrub_version " << get_version() << dendl;
assert(!scrub_infop || !scrub_infop->scrub_in_progress);
scrub_info();
if (!scrub_infop)
}
}
scrub_infop->scrub_in_progress = true;
- scrub_infop->scrub_start_version = scrub_version;
+ scrub_infop->scrub_start_version = get_version();
scrub_infop->scrub_start_stamp = ceph_clock_now(g_ceph_context);
+ scrub_infop->header = header;
// right now we don't handle remote inodes
}
/// my own (temporary) stamps and versions for each dirfrag we have
std::map<frag_t, scrub_stamp_info_t> dirfrag_stamps;
+ ScrubHeaderRefConst header;
+
scrub_info_t() : scrub_stamp_info_t(), last_scrub_dirty(false),
scrub_in_progress(false) {}
};
* @param scrub_version What version are we scrubbing at (usually, parent
* directory's get_projected_version())
*/
- void scrub_initialize(version_t scrub_version);
+ void scrub_initialize(const ScrubHeaderRefConst& header);
/**
* Get the next dirfrag to scrub. Gives you a frag_t in output param which
* you must convert to a CDir (and possibly load off disk).
}
void ScrubStack::_enqueue_dentry(CDentry *dn, CDir *parent, bool recursive,
- bool children, ScrubHeaderRefConst header,
+ bool children, const ScrubHeaderRefConst& header,
MDSInternalContextBase *on_finish, bool top)
{
dout(10) << __func__ << " with {" << *dn << "}"
}
void ScrubStack::enqueue_dentry(CDentry *dn, bool recursive, bool children,
- ScrubHeaderRefConst header,
+ const ScrubHeaderRefConst& header,
MDSInternalContextBase *on_finish, bool top)
{
_enqueue_dentry(dn, NULL, recursive, children, header, on_finish, top);
// the stack... or actually is that right? Should we perhaps
// only see ourselves once on the way down and once on the way
// back up again, and not do this?
- in->scrub_initialize(in->get_version());
+ in->scrub_initialize(dn->scrub_info()->header);
}
list<frag_t> scrubbing_frags;
} else {
bool ready = get_next_cdir(in, &cur_dir);
dout(20) << __func__ << " get_next_cdir ready=" << ready << dendl;
- if (cur_dir) {
- cur_dir->scrub_initialize();
- }
if (ready && cur_dir) {
scrubbing_cdirs.push_back(cur_dir);
bool frag_added_children = false;
bool frag_terminal = true;
bool frag_done = false;
- scrub_dirfrag(cur_dir, &frag_added_children, &frag_terminal, &frag_done);
+ scrub_dirfrag(cur_dir, dn->scrub_info()->scrub_recursive,
+ &frag_added_children, &frag_terminal, &frag_done);
if (frag_done) {
// FIXME is this right? Can we end up hitting this more than
// once and is that a problem?
return;
}
-void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children,
- bool *is_terminal, bool *done)
+void ScrubStack::scrub_dirfrag(CDir *dir, bool recursive,
+ bool *added_children,
+ bool *is_terminal, bool *done)
{
assert(dir != NULL);
*is_terminal = false;
*done = false;
+ const ScrubHeaderRefConst& header = dir->get_inode()->scrub_info()->header;
+
if (!dir->scrub_info()->directory_scrubbing) {
// Get the frag complete before calling
// scrub initialize, so that it can populate its lists
// never get random IO errors here.
assert(r == 0);
- CDentry *parent_dn = dir->get_inode()->get_parent_dn();
- ScrubHeaderRefConst header = parent_dn->scrub_info()->header;
// FIXME: Do I *really* need to construct a kick context for every
// single dentry I'm going to scrub?
_enqueue_dentry(dn,
dir,
- parent_dn->scrub_info()->scrub_recursive,
+ recursive,
false, // We are already recursing so scrub_children not meaningful
header,
NULL,
* was initiated
*/
void enqueue_dentry_top(CDentry *dn, bool recursive, bool children,
- ScrubHeaderRefConst header,
+ const ScrubHeaderRefConst& header,
MDSInternalContextBase *on_finish) {
enqueue_dentry(dn, recursive, children, header, on_finish, true);
}
* starting this one.
*/
void enqueue_dentry_bottom(CDentry *dn, bool recursive, bool children,
- ScrubHeaderRefConst header,
+ const ScrubHeaderRefConst& header,
MDSInternalContextBase *on_finish) {
enqueue_dentry(dn, recursive, children, header, on_finish, false);
}
* the given scrub params, and then try and kick off more scrubbing.
*/
void enqueue_dentry(CDentry *dn, bool recursive, bool children,
- ScrubHeaderRefConst header,
+ const ScrubHeaderRefConst& header,
MDSInternalContextBase *on_finish, bool top);
void _enqueue_dentry(CDentry *dn, CDir *parent, bool recursive, bool children,
- ScrubHeaderRefConst header,
+ const ScrubHeaderRefConst& header,
MDSInternalContextBase *on_finish, bool top);
/**
* Kick off as many scrubs as are appropriate, based on the current
* progress. Try again later.
*
*/
- void scrub_dirfrag(CDir *dir, bool *added_children, bool *is_terminal,
- bool *done);
+ void scrub_dirfrag(CDir *dir, bool recursive,
+ bool *added_children, bool *is_terminal, bool *done);
/**
* Scrub a directory-representing dentry.
*