summaryrefslogtreecommitdiff
path: root/src/mds/MDCache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds/MDCache.cc')
-rw-r--r--src/mds/MDCache.cc37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc
index 2b7ad7152f3..b9b154d91b3 100644
--- a/src/mds/MDCache.cc
+++ b/src/mds/MDCache.cc
@@ -8015,6 +8015,29 @@ void MDCache::_open_ino_traverse_dir(inodeno_t ino, open_ino_info_t& info, int r
do_open_ino(ino, info, ret);
}
+void MDCache::_open_ino_fetch_dir(inodeno_t ino, MMDSOpenIno *m, CDir *dir)
+{
+ if (dir->state_test(CDir::STATE_REJOINUNDEF) && dir->get_frag() == frag_t()) {
+ rejoin_undef_dirfrags.erase(dir);
+ dir->state_clear(CDir::STATE_REJOINUNDEF);
+
+ CInode *diri = dir->get_inode();
+ diri->force_dirfrags();
+ list<CDir*> ls;
+ diri->get_dirfrags(ls);
+
+ C_GatherBuilder gather(g_ceph_context, _open_ino_get_waiter(ino, m));
+ for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
+ rejoin_undef_dirfrags.insert(*p);
+ (*p)->state_set(CDir::STATE_REJOINUNDEF);
+ (*p)->fetch(gather.new_sub());
+ }
+ assert(gather.has_subs());
+ gather.activate();
+ } else
+ dir->fetch(_open_ino_get_waiter(ino, m));
+}
+
int MDCache::open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m,
vector<inode_backpointer_t>& ancestors,
bool discover, bool want_xlocked, int *hint)
@@ -8032,8 +8055,14 @@ int MDCache::open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m,
continue;
}
- if (diri->state_test(CInode::STATE_REJOINUNDEF))
- continue;
+ if (diri->state_test(CInode::STATE_REJOINUNDEF)) {
+ CDir *dir = diri->get_parent_dir();
+ while (dir->state_test(CDir::STATE_REJOINUNDEF) &&
+ dir->get_inode()->state_test(CInode::STATE_REJOINUNDEF))
+ dir = dir->get_inode()->get_parent_dir();
+ _open_ino_fetch_dir(ino, m, dir);
+ return 1;
+ }
if (!diri->is_dir()) {
dout(10) << " " << *diri << " is not dir" << dendl;
@@ -8067,14 +8096,14 @@ int MDCache::open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m,
if (dnl && dnl->is_primary() &&
dnl->get_inode()->state_test(CInode::STATE_REJOINUNDEF)) {
dout(10) << " fetching undef " << *dnl->get_inode() << dendl;
- dir->fetch(_open_ino_get_waiter(ino, m));
+ _open_ino_fetch_dir(ino, m, dir);
return 1;
}
if (!dnl && !dir->is_complete() &&
(!dir->has_bloom() || dir->is_in_bloom(name))) {
dout(10) << " fetching incomplete " << *dir << dendl;
- dir->fetch(_open_ino_get_waiter(ino, m));
+ _open_ino_fetch_dir(ino, m, dir);
return 1;
}