dir->add_waiter(CDir::WAIT_UNFREEZE, gather.new_sub());
} else if (dir->get_version() == 0) {
dout(20) << __func__ << " barebones " << *dir << dendl;
- dir->fetch(gather.new_sub());
+ dir->fetch_keys({}, gather.new_sub());
} else {
_enqueue(dir, header, true);
queued.insert_raw(dir->get_frag());
ScrubHeaderRef header = dir->get_scrub_header();
version_t last_scrub = dir->scrub_info()->last_recursive.version;
if (header->get_recursive()) {
- for (auto it = dir->begin(); it != dir->end(); ++it) {
- if (it->first.snapid != CEPH_NOSNAP)
+ auto next_seq = mdcache->get_global_snaprealm()->get_newest_seq()+1;
+ for (auto it = dir->begin(); it != dir->end(); /* nop */) {
+ auto [dnk, dn] = *it;
+ ++it; /* trim (in the future) may remove dentry */
+
+ if (dn->scrub(next_seq)) {
+ std::string path;
+ dir->get_inode()->make_path_string(path, true);
+ clog->warn() << "Scrub error on dentry " << *dn
+ << " see " << g_conf()->name
+ << " log and `damage ls` output for details";
+ }
+
+ if (dnk.snapid != CEPH_NOSNAP) {
continue;
- CDentry *dn = it->second;
+ }
+
CDentry::linkage_t *dnl = dn->get_linkage();
if (dn->get_version() <= last_scrub &&
dnl->get_remote_d_type() != DT_DIR &&
!header->get_force()) {
- dout(15) << __func__ << " skip dentry " << it->first
+ dout(15) << __func__ << " skip dentry " << dnk
<< ", no change since last scrub" << dendl;
continue;
}
}
}
- dir->scrub_local();
+ if (!dir->scrub_local()) {
+ std::string path;
+ dir->get_inode()->make_path_string(path, true);
+ clog->warn() << "Scrub error on dir " << dir->ino()
+ << " (" << path << ") see " << g_conf()->name
+ << " log and `damage ls` output for details";
+ }
dir->scrub_finished();
dir->auth_unpin(this);