subs.push_back(f);
f->set_dir_auth(get_dir_auth());
+ f->freeze_tree_state = freeze_tree_state;
f->prepare_new_fragment(replay);
f->init_fragment_pins();
}
{
dout(10) << "merge " << subs << dendl;
- mds_authority_t new_auth = CDIR_AUTH_DEFAULT;
+ set_dir_auth(subs.front()->get_dir_auth());
+ freeze_tree_state = subs.front()->freeze_tree_state;
+
for (auto dir : subs) {
- if (dir->get_dir_auth() != CDIR_AUTH_DEFAULT &&
- dir->get_dir_auth() != new_auth) {
- ceph_assert(new_auth == CDIR_AUTH_DEFAULT);
- new_auth = dir->get_dir_auth();
- }
+ ceph_assert(get_dir_auth() == dir->get_dir_auth());
+ ceph_assert(freeze_tree_state == dir->freeze_tree_state);
}
- set_dir_auth(new_auth);
prepare_new_fragment(replay);
nest_info_t rstatdiff;
if (!was_subtree && is_subtree_root()) {
dout(10) << " new subtree root, adjusting auth_pins" << dendl;
+ if (freeze_tree_state) {
+ // only by CDir::_freeze_tree()
+ ceph_assert(is_freezing_tree_root());
+ }
+
inode->num_subtree_roots++;
// unpin parent of frozen dir/tree?
}
freeze_tree_state->frozen = true;
- // twiddle state
- if (state_test(STATE_FREEZINGTREE)) {
- state_clear(STATE_FREEZINGTREE); // actually, this may get set again by next context?
- --num_freezing_trees;
- }
-
if (is_auth()) {
mds_authority_t auth;
bool was_subtree = is_subtree_root();
);
}
+ // twiddle state
+ if (state_test(STATE_FREEZINGTREE)) {
+ state_clear(STATE_FREEZINGTREE);
+ --num_freezing_trees;
+ }
+
state_set(STATE_FROZENTREE);
++num_frozen_trees;
get(PIN_FROZEN);
// are my constituent bits subtrees? if so, i will be too.
// (it's all or none, actually.)
- bool any_subtree = false;
+ bool any_subtree = false, any_non_subtree = false;
for (CDir *dir : srcfrags) {
- if (dir->is_subtree_root()) {
+ if (dir->is_subtree_root())
any_subtree = true;
- break;
- }
+ else
+ any_non_subtree = true;
}
+ ceph_assert(!any_subtree || !any_non_subtree);
+
set<CDir*> new_bounds;
if (any_subtree) {
for (CDir *dir : srcfrags) {
void MDCache::fragment_freeze_dirs(list<CDir*>& dirs)
{
- for (list<CDir*>::iterator p = dirs.begin(); p != dirs.end(); ++p) {
- CDir *dir = *p;
+ bool any_subtree = false, any_non_subtree = false;
+ for (CDir* dir : dirs) {
dir->auth_pin(dir); // until we mark and complete them
dir->state_set(CDir::STATE_FRAGMENTING);
dir->freeze_dir();
ceph_assert(dir->is_freezing_dir());
+
+ if (dir->is_subtree_root())
+ any_subtree = true;
+ else
+ any_non_subtree = true;
+ }
+
+ if (any_subtree && any_non_subtree) {
+ // either all dirfrags are subtree roots or all are not.
+ for (CDir *dir : dirs) {
+ if (dir->is_subtree_root()) {
+ ceph_assert(dir->state_test(CDir::STATE_AUXSUBTREE));
+ } else {
+ dir->state_set(CDir::STATE_AUXSUBTREE);
+ adjust_subtree_auth(dir, mds->get_nodeid());
+ }
+ }
}
}