CDir *f = new CDir(inode, *p, cache, is_auth());
f->state_set(state & (MASK_STATE_FRAGMENT_KEPT | STATE_COMPLETE));
f->get_replicas() = get_replicas();
- f->dir_auth = dir_auth;
- f->init_fragment_pins();
f->set_version(get_version());
-
f->pop_me = pop_me;
f->pop_me.scale(fac);
f->set_dir_auth(get_dir_auth());
f->prepare_new_fragment(replay);
+ f->init_fragment_pins();
}
// repartition dentries
// new subtree root?
if (!was_subtree && is_subtree_root()) {
dout(10) << " new subtree root, adjusting auth_pins" << dendl;
-
+
+ inode->num_subtree_roots++;
+
// adjust nested auth pins
if (get_cum_auth_pins())
inode->adjust_nested_auth_pins(-1, NULL);
}
if (was_subtree && !is_subtree_root()) {
dout(10) << " old subtree root, adjusting auth_pins" << dendl;
-
+
+ inode->num_subtree_roots--;
+
// adjust nested auth pins
if (get_cum_auth_pins())
inode->adjust_nested_auth_pins(1, NULL);
void assimilate_dirty_rstat_inodes();
void assimilate_dirty_rstat_inodes_finish(MutationRef& mut, EMetaBlob *blob);
+ void mark_exporting() {
+ state_set(CDir::STATE_EXPORTING);
+ inode->num_exporting_dirs++;
+ }
+ void clear_exporting() {
+ state_clear(CDir::STATE_EXPORTING);
+ inode->num_exporting_dirs--;
+ }
+
protected:
version_t projected_version;
mempool::mds_co::list<fnode_t> projected_fnode;
dir->state_clear(CDir::STATE_STICKY);
dir->put(CDir::PIN_STICKY);
}
+
+ if (dir->is_subtree_root())
+ num_subtree_roots--;
// dump any remaining dentries, for debugging purposes
for (const auto &p : dir->items)
bool CInode::has_subtree_root_dirfrag(int auth)
{
- for (const auto &p : dirfrags) {
- if (p.second->is_subtree_root() &&
- (auth == -1 || p.second->dir_auth.first == auth))
+ if (num_subtree_roots > 0) {
+ if (auth == -1)
return true;
+ for (const auto &p : dirfrags) {
+ if (p.second->is_subtree_root() &&
+ p.second->dir_auth.first == auth)
+ return true;
+ }
}
return false;
}
bool CInode::has_subtree_or_exporting_dirfrag()
{
- for (const auto &p : dirfrags) {
- if (p.second->is_subtree_root() ||
- p.second->state_test(CDir::STATE_EXPORTING))
- return true;
- }
+ if (num_subtree_roots > 0 || num_exporting_dirs > 0)
+ return true;
return false;
}
// -- cache infrastructure --
private:
mempool::mds_co::compact_map<frag_t,CDir*> dirfrags; // cached dir fragments under this Inode
+
+ //for the purpose of quickly determining whether there's a subtree root or exporting dir
+ int num_subtree_roots = 0;
+ int num_exporting_dirs = 0;
+
int stickydir_ref = 0;
scrub_info_t *scrub_infop = nullptr;
assert(num_projected_xattrs == 0);
assert(num_projected_srnodes == 0);
assert(num_caps_wanted == 0);
+ assert(num_subtree_roots == 0);
+ assert(num_exporting_dirs == 0);
}
}
show_subtrees(10);
-
- // dir has no PIN_SUBTREE; CDir::purge_stolen() drops it.
- dir->dir_auth = CDIR_AUTH_DEFAULT;
}
diri->close_dirfrag(dir->get_frag());
if (it->second.state == EXPORT_CANCELLED) {
export_state.erase(it);
- dir->state_clear(CDir::STATE_EXPORTING);
+ dir->clear_exporting();
// send pending import_maps?
cache->maybe_send_pending_resolves();
}
void Migrator::export_cancel_finish(CDir *dir)
{
assert(dir->state_test(CDir::STATE_EXPORTING));
- dir->state_clear(CDir::STATE_EXPORTING);
+ dir->clear_exporting();
// pinned by Migrator::export_notify_abort()
dir->auth_unpin(this);
mds->hit_export_target(ceph_clock_now(), dest, -1);
dir->auth_pin(this);
- dir->state_set(CDir::STATE_EXPORTING);
+ dir->mark_exporting();
MDRequestRef mdr = mds->mdcache->request_start_internal(CEPH_MDS_OP_EXPORTDIR);
mdr->more()->export_dir = dir;
mds->send_message_mds(new MExportDirCancel(dir->dirfrag(), it->second.tid), it->second.peer);
export_state.erase(it);
- dir->state_clear(CDir::STATE_EXPORTING);
+ dir->clear_exporting();
cache->maybe_send_pending_resolves();
return;
}
MutationRef mut = it->second.mut;
// remove from exporting list, clean up state
export_state.erase(it);
- dir->state_clear(CDir::STATE_EXPORTING);
+ dir->clear_exporting();
cache->show_subtrees();
audit();