valid = 1;
        }
 
+       if (!valid) {
+               struct ceph_mds_client *mdsc =
+                       ceph_sb_to_client(dir->i_sb)->mdsc;
+               struct ceph_mds_request *req;
+               int op, mask, err;
+
+               op = ceph_snap(dir) == CEPH_SNAPDIR ?
+                       CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
+               req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
+               if (!IS_ERR(req)) {
+                       req->r_dentry = dget(dentry);
+                       req->r_num_caps = 2;
+
+                       mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
+                       if (ceph_security_xattr_wanted(dir))
+                               mask |= CEPH_CAP_XATTR_SHARED;
+                       req->r_args.getattr.mask = mask;
+
+                       req->r_locked_dir = dir;
+                       err = ceph_mdsc_do_request(mdsc, NULL, req);
+                       if (err == 0 || err == -ENOENT) {
+                               if (dentry == req->r_dentry) {
+                                       valid = !d_unhashed(dentry);
+                               } else {
+                                       d_invalidate(req->r_dentry);
+                                       err = -EAGAIN;
+                               }
+                       }
+                       ceph_mdsc_put_request(req);
+                       dout("d_revalidate %p lookup result=%d\n",
+                            dentry, err);
+               }
+       }
+
        dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid");
        if (valid) {
                ceph_dentry_lru_touch(dentry);
 
                        dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
                             dn, d_inode(dn), ceph_vinop(d_inode(dn)),
                             ceph_vinop(in));
+                       d_invalidate(dn);
                        have_lease = false;
                }