BUG_ON(!(nd->flags & LOOKUP_RCU));
 
        nd->flags &= ~LOOKUP_RCU;
+       if (nd->flags & LOOKUP_CACHED)
+               goto out1;
        if (unlikely(!legitimize_links(nd)))
                goto out1;
        if (unlikely(!legitimize_path(nd, &nd->path, nd->seq)))
        BUG_ON(!(nd->flags & LOOKUP_RCU));
 
        nd->flags &= ~LOOKUP_RCU;
+       if (nd->flags & LOOKUP_CACHED)
+               goto out2;
        if (unlikely(!legitimize_links(nd)))
                goto out2;
        if (unlikely(!legitimize_mnt(nd->path.mnt, nd->m_seq)))
                 */
                if (!(nd->flags & (LOOKUP_ROOT | LOOKUP_IS_SCOPED)))
                        nd->root.mnt = NULL;
+               nd->flags &= ~LOOKUP_CACHED;
                if (!try_to_unlazy(nd))
                        return -ECHILD;
        }
        int error;
        const char *s = nd->name->name;
 
+       /* LOOKUP_CACHED requires RCU, ask caller to retry */
+       if ((flags & (LOOKUP_RCU | LOOKUP_CACHED)) == LOOKUP_CACHED)
+               return ERR_PTR(-EAGAIN);
+
        if (!*s)
                flags &= ~LOOKUP_RCU;
        if (flags & LOOKUP_RCU)
 
 #define LOOKUP_NO_XDEV         0x040000 /* No mountpoint crossing. */
 #define LOOKUP_BENEATH         0x080000 /* No escaping from starting point. */
 #define LOOKUP_IN_ROOT         0x100000 /* Treat dirfd as fs root. */
+#define LOOKUP_CACHED          0x200000 /* Only do cached lookup */
 /* LOOKUP_* flags which do scope-related checks based on the dirfd. */
 #define LOOKUP_IS_SCOPED (LOOKUP_BENEATH | LOOKUP_IN_ROOT)