From: Yan, Zheng Date: Wed, 31 Dec 2014 07:25:43 +0000 (+0800) Subject: mds: avoid infinite loop of SnapRealm::_open_parents X-Git-Tag: v0.93~87^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=01ff547b11d369ab216ca2698ef1107faf7ce510;p=ceph.git mds: avoid infinite loop of SnapRealm::_open_parents handle the case that some past parents are missing Signed-off-by: Yan, Zheng --- diff --git a/src/mds/SnapRealm.cc b/src/mds/SnapRealm.cc index e28da9f5f1ef..987288351205 100644 --- a/src/mds/SnapRealm.cc +++ b/src/mds/SnapRealm.cc @@ -64,6 +64,35 @@ void SnapRealm::add_open_past_parent(SnapRealm *parent) parent->inode->get(CInode::PIN_PASTSNAPPARENT); } +struct C_SR_RetryOpenParents : public MDSInternalContextBase { + SnapRealm *sr; + snapid_t first, last, parent_last; + inodeno_t parent; + MDSInternalContextBase* fin; + C_SR_RetryOpenParents(SnapRealm *s, snapid_t f, snapid_t l, snapid_t pl, + inodeno_t p, MDSInternalContextBase *c) : + sr(s), first(f), last(l), parent_last(pl), parent(p), fin(c) {} + MDS *get_mds() { return sr->mdcache->mds; } + void finish(int r) { + if (r < 0) + sr->_remove_missing_parent(parent_last, parent, r); + if (sr->_open_parents(fin, first, last)) + fin->complete(0); + } +}; + +void SnapRealm::_remove_missing_parent(snapid_t snapid, inodeno_t parent, int err) +{ + map::iterator p = srnode.past_parents.find(snapid); + if (p != srnode.past_parents.end()) { + dout(10) << __func__ << " " << parent << " [" << p->second.first << "," + << p->first << "] errno " << err << dendl; + srnode.past_parents.erase(p); + } else { + dout(10) << __func__ << " " << parent << " not found" << dendl; + } +} + bool SnapRealm::_open_parents(MDSInternalContextBase *finish, snapid_t first, snapid_t last) { dout(10) << "open_parents [" << first << "," << last << "]" << dendl; @@ -89,7 +118,9 @@ bool SnapRealm::_open_parents(MDSInternalContextBase *finish, snapid_t first, sn << p->second.ino << dendl; CInode *parent = mdcache->get_inode(p->second.ino); if (!parent) { - mdcache->open_ino(p->second.ino, mdcache->mds->mdsmap->get_metadata_pool(), finish); + C_SR_RetryOpenParents *fin = new C_SR_RetryOpenParents(this, first, last, p->first, + p->second.ino, finish); + mdcache->open_ino(p->second.ino, mdcache->mds->mdsmap->get_metadata_pool(), fin); return false; } assert(parent->snaprealm); // hmm! diff --git a/src/mds/SnapRealm.h b/src/mds/SnapRealm.h index 65e6521d4380..28886240a60f 100644 --- a/src/mds/SnapRealm.h +++ b/src/mds/SnapRealm.h @@ -66,6 +66,7 @@ struct SnapRealm { } bool _open_parents(MDSInternalContextBase *retryorfinish, snapid_t first=1, snapid_t last=CEPH_NOSNAP); + void _remove_missing_parent(snapid_t snapid, inodeno_t parent, int err); bool open_parents(MDSInternalContextBase *retryorfinish) { if (!_open_parents(retryorfinish)) return false;