]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: handle mksnap vs resolve_snapname race
authorYan, Zheng <zyan@redhat.com>
Tue, 8 Aug 2017 03:06:34 +0000 (11:06 +0800)
committerYan, Zheng <zyan@redhat.com>
Fri, 9 Feb 2018 10:41:27 +0000 (18:41 +0800)
In multimds setup, it's possible that mds receives snap update message
after receiving client requests that lookup the newly created snapshot.

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

index c55df5c7a17b89381004fc037e58c1cecc007747..6cf2d31c5f7f6141773bf490ea9234f600082272 100644 (file)
@@ -7981,8 +7981,21 @@ int MDCache::path_traverse(MDRequestRef& mdr, Message *req, MDSInternalContextBa
       SnapRealm *realm = cur->find_snaprealm();
       snapid = realm->resolve_snapname(path[depth], cur->ino());
       dout(10) << "traverse: snap " << path[depth] << " -> " << snapid << dendl;
-      if (!snapid)
+      if (!snapid) {
+       CInode *t = cur;
+       while (t) {
+         // if snaplock isn't readable, it's possible that other mds is creating
+         // snapshot, but snap update message hasn't been received.
+         if (!t->snaplock.can_read(client)) {
+           dout(10) << " non-readable snaplock on " << *t << dendl;
+           t->snaplock.add_waiter(SimpleLock::WAIT_RD, _get_waiter(mdr, req, fin));
+           return 1;
+         }
+         CDentry *pdn = t->get_projected_parent_dn();
+         t = pdn ? pdn->get_dir()->get_inode() : NULL;
+       }
        return -ENOENT;
+      }
       mdr->snapid = snapid;
       depth++;
       continue;