From: Yan, Zheng Date: Wed, 15 Jan 2014 04:13:52 +0000 (+0800) Subject: mds: fix open undef dirfrags X-Git-Tag: v0.78~165^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0eb311d39c6cd2cf61e81730364a89792c8f8411;p=ceph.git mds: fix open undef dirfrags Undef inode may contain a undef dirfrag (*). When undef inode is opened, we should force fragment the undef dirfrag (*). because we may open other dirfrags later, the undef dirfrag (*) will overlap with them. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index f0dc962f1f9..99bbc841e33 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1522,6 +1522,8 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map& omap, } } + list undef_inodes; + // purge stale snaps? // only if we have past_parents open! bool purged_any = false; @@ -1636,10 +1638,7 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map& omap, if (in) { dout(12) << "_fetched had dentry " << *dn << dendl; if (in->state_test(CInode::STATE_REJOINUNDEF)) { - assert(cache->mds->is_rejoin()); - assert(in->vino() == vinodeno_t(inode.ino, last)); - in->state_clear(CInode::STATE_REJOINUNDEF); - cache->opened_undef_inode(in); + undef_inodes.push_back(in); undef_inode = true; } } else @@ -1749,6 +1748,15 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map& omap, // mark complete, !fetching mark_complete(); state_clear(STATE_FETCHING); + + // open & force frags + while (!undef_inodes.empty()) { + CInode *in = undef_inodes.front(); + undef_inodes.pop_front(); + in->state_clear(CInode::STATE_REJOINUNDEF); + cache->opened_undef_inode(in); + } + auth_unpin(this); // kick waiters diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 30c01822f6a..02e76d8c87d 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -131,7 +131,8 @@ public: static const unsigned MASK_STATE_FRAGMENT_KEPT = (STATE_DIRTY| STATE_EXPORTBOUND | - STATE_IMPORTBOUND); + STATE_IMPORTBOUND | + STATE_REJOINUNDEF); // -- rep spec -- static const int REP_NONE = 0; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 3a16ae7d548..96a17154fd0 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -5548,19 +5548,8 @@ bool MDCache::open_undef_inodes_dirfrags() CInode *diri = dir->get_inode(); if (diri->state_test(CInode::STATE_REJOINUNDEF)) continue; - if (dir->state_test(CDir::STATE_REJOINUNDEF) && dir->get_frag() == frag_t()) { - rejoin_undef_dirfrags.erase(dir); - dir->state_clear(CDir::STATE_REJOINUNDEF); - diri->force_dirfrags(); - list ls; - diri->get_dirfrags(ls); - for (list::iterator q = ls.begin(); q != ls.end(); ++q) { - rejoin_undef_dirfrags.insert(*q); - (*q)->state_set(CDir::STATE_REJOINUNDEF); - (*q)->fetch(gather.new_sub()); - } - continue; - } + if (dir->state_test(CDir::STATE_REJOINUNDEF)) + assert(diri->dirfragtree.is_leaf(dir->get_frag())); dir->fetch(gather.new_sub()); } assert(gather.has_subs()); @@ -5568,6 +5557,23 @@ bool MDCache::open_undef_inodes_dirfrags() return true; } +void MDCache::opened_undef_inode(CInode *in) { + dout(10) << "opened_undef_inode " << *in << dendl; + rejoin_undef_inodes.erase(in); + if (in->is_dir()) { + if (in->has_dirfrags() && !in->dirfragtree.is_leaf(frag_t())) { + CDir *dir = in->get_dirfrag(frag_t()); + assert(dir); + rejoin_undef_dirfrags.erase(dir); + in->force_dirfrags(); + list ls; + in->get_dirfrags(ls); + for (list::iterator p = ls.begin(); p != ls.end(); ++p) + rejoin_undef_dirfrags.insert(*p); + } + } +} + void MDCache::finish_snaprealm_reconnect(client_t client, SnapRealm *realm, snapid_t seq) { if (seq < realm->get_newest_seq()) { @@ -8201,25 +8207,9 @@ void MDCache::_open_ino_traverse_dir(inodeno_t ino, open_ino_info_t& info, int r 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 ls; - diri->get_dirfrags(ls); - - C_GatherBuilder gather(g_ceph_context, _open_ino_get_waiter(ino, m)); - for (list::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)); + if (dir->state_test(CDir::STATE_REJOINUNDEF)) + assert(dir->get_inode()->dirfragtree.is_leaf(dir->get_frag())); + dir->fetch(_open_ino_get_waiter(ino, m)); } int MDCache::open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m, diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 6087e984742..34b9e8c9ca3 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -514,12 +514,10 @@ public: void open_snap_parents(); bool open_undef_inodes_dirfrags(); + void opened_undef_inode(CInode *in); void opened_undef_dirfrag(CDir *dir) { rejoin_undef_dirfrags.erase(dir); } - void opened_undef_inode(CInode *in) { - rejoin_undef_inodes.erase(in); - } void reissue_all_caps();