goto ack;
 
                /* things we might delay */
-               if ((cap->issued & ~retain) == 0 &&
-                   cap->mds_wanted == want)
+               if ((cap->issued & ~retain) == 0)
                        continue;     /* nope, all good */
 
                if (no_delay)
        int used, wanted, dirty;
        u64 size = le64_to_cpu(grant->size);
        u64 max_size = le64_to_cpu(grant->max_size);
-       int check_caps = 0;
+       unsigned char check_caps = 0;
+       bool was_stale = cap->cap_gen < session->s_cap_gen;
        bool wake = false;
        bool writeback = false;
        bool queue_trunc = false;
             ceph_cap_string(wanted),
             ceph_cap_string(used),
             ceph_cap_string(dirty));
-       if (wanted != le32_to_cpu(grant->wanted)) {
-               dout("mds wanted %s -> %s\n",
-                    ceph_cap_string(le32_to_cpu(grant->wanted)),
-                    ceph_cap_string(wanted));
-               /* imported cap may not have correct mds_wanted */
-               if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT)
-                       check_caps = 1;
+
+       if ((was_stale || le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) &&
+           (wanted & ~(cap->mds_wanted | newcaps))) {
+               /*
+                * If mds is importing cap, prior cap messages that update
+                * 'wanted' may get dropped by mds (migrate seq mismatch).
+                *
+                * We don't send cap message to update 'wanted' if what we
+                * want are already issued. If mds revokes caps, cap message
+                * that releases caps also tells mds what we want. But if
+                * caps got revoked by mds forcedly (session stale). We may
+                * haven't told mds what we want.
+                */
+               check_caps = 1;
        }
 
        /* revocation, grant, or no-op? */