]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid infinite loop of SnapRealm::_open_parents
authorYan, Zheng <zyan@redhat.com>
Wed, 31 Dec 2014 07:25:43 +0000 (15:25 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 5 Feb 2015 14:40:39 +0000 (22:40 +0800)
handle the case that some past parents are missing

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/SnapRealm.cc
src/mds/SnapRealm.h

index e28da9f5f1efbab9fc06c83170348d8879669610..98728835120540cb51aee449ea702a847b1bdaf4 100644 (file)
@@ -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<snapid_t, snaplink_t>::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!
index 65e6521d43802ef82c79df4e53d5f526d61f02dd..28886240a60fffbc6e3626af2cedba1a8e0197d7 100644 (file)
@@ -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;