summaryrefslogtreecommitdiff
path: root/src/mds
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-06-12 11:02:12 +0800
committerYan, Zheng <zheng.z.yan@intel.com>2013-06-17 19:14:05 +0800
commitf11ec5ccbb4f95979b5bf98995f6be4e5cd60aaf (patch)
tree486f928967d751ab41760b00e28f3880e2e0f07b /src/mds
parent29e6597e9f34d3494a2e43582a42fde72ae2b137 (diff)
downloadceph-f11ec5ccbb4f95979b5bf98995f6be4e5cd60aaf.tar.gz
mds: handle undefined dirfrags when opening inode
When MDS is rejoin stage, cache rejoin message can add undefined inodes and dirfrags to the cache. These undefined objects can affect "lookup-by-ino" processes. If an undefined dirfrag is encountered, we should fetch it from disk. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Diffstat (limited to 'src/mds')
-rw-r--r--src/mds/MDCache.cc37
-rw-r--r--src/mds/MDCache.h1
2 files changed, 34 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;
}
diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h
index 3da8a36f799..36a322c6324 100644
--- a/src/mds/MDCache.h
+++ b/src/mds/MDCache.h
@@ -790,6 +790,7 @@ protected:
void _open_ino_backtrace_fetched(inodeno_t ino, bufferlist& bl, int err);
void _open_ino_parent_opened(inodeno_t ino, int ret);
void _open_ino_traverse_dir(inodeno_t ino, open_ino_info_t& info, int err);
+ void _open_ino_fetch_dir(inodeno_t ino, MMDSOpenIno *m, CDir *dir);
Context* _open_ino_get_waiter(inodeno_t ino, MMDSOpenIno *m);
int open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m,
vector<inode_backpointer_t>& ancestors,