From: Yan, Zheng Date: Tue, 8 Aug 2017 03:06:34 +0000 (+0800) Subject: mds: handle mksnap vs resolve_snapname race X-Git-Tag: v13.1.0~413^2~28 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=280ab1c8cf38f2428ea7eb7d9ffe1b35c36b4513;p=ceph.git mds: handle mksnap vs resolve_snapname race 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" --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index c55df5c7a17b..6cf2d31c5f7f 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -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;