if (unlikely(error == -ESTALE))
                error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path);
        if (likely(!error))
-               audit_inode(name, path->dentry, 0);
+               audit_inode(name, path->dentry, flags & LOOKUP_NO_EVAL);
        restore_nameidata();
        putname(name);
        return error;
 
        if (!(flags & UMOUNT_NOFOLLOW))
                lookup_flags |= LOOKUP_FOLLOW;
 
+       lookup_flags |= LOOKUP_NO_EVAL;
+
        retval = user_path_mountpoint_at(AT_FDCWD, name, lookup_flags, &path);
        if (retval)
                goto out;
 
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
+#include <linux/namei.h>  /* LOOKUP_* */
 #include <uapi/linux/audit.h>
 
 #define AUDIT_INO_UNSET ((unsigned long)-1)
 
 #define AUDIT_INODE_PARENT     1       /* dentry represents the parent */
 #define AUDIT_INODE_HIDDEN     2       /* audit record should be hidden */
+#define AUDIT_INODE_NOEVAL     4       /* audit record incomplete */
 extern void __audit_inode(struct filename *name, const struct dentry *dentry,
                                unsigned int flags);
 extern void __audit_file(const struct file *);
 }
 static inline void audit_inode(struct filename *name,
                                const struct dentry *dentry,
-                               unsigned int parent) {
+                               unsigned int flags) {
        if (unlikely(!audit_dummy_context())) {
-               unsigned int flags = 0;
-               if (parent)
-                       flags |= AUDIT_INODE_PARENT;
-               __audit_inode(name, dentry, flags);
+               unsigned int aflags = 0;
+
+               if (flags & LOOKUP_PARENT)
+                       aflags |= AUDIT_INODE_PARENT;
+               if (flags & LOOKUP_NO_EVAL)
+                       aflags |= AUDIT_INODE_NOEVAL;
+               __audit_inode(name, dentry, aflags);
        }
 }
 static inline void audit_file(struct file *file)
 
  *  - internal "there are more path components" flag
  *  - dentry cache is untrusted; force a real lookup
  *  - suppress terminal automount
+ *  - skip revalidation
+ *  - don't fetch xattrs on audit_inode
  */
 #define LOOKUP_FOLLOW          0x0001
 #define LOOKUP_DIRECTORY       0x0002
 #define LOOKUP_REVAL           0x0020
 #define LOOKUP_RCU             0x0040
 #define LOOKUP_NO_REVAL                0x0080
+#define LOOKUP_NO_EVAL         0x0100
 
 /*
  * Intent data
 
 
 static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
 {
+       if (name->fcap_ver == -1) {
+               audit_log_format(ab, " cap_fe=? cap_fver=? cap_fp=? cap_fi=?");
+               return;
+       }
        audit_log_cap(ab, "cap_fp", &name->fcap.permitted);
        audit_log_cap(ab, "cap_fi", &name->fcap.inheritable);
        audit_log_format(ab, " cap_fe=%d cap_fver=%x cap_frootid=%d",
 
 /* Copy inode data into an audit_names. */
 void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,
-                     struct inode *inode)
+                     struct inode *inode, unsigned int flags)
 {
        name->ino   = inode->i_ino;
        name->dev   = inode->i_sb->s_dev;
        name->gid   = inode->i_gid;
        name->rdev  = inode->i_rdev;
        security_inode_getsecid(inode, &name->osid);
+       if (flags & AUDIT_INODE_NOEVAL) {
+               name->fcap_ver = -1;
+               return;
+       }
        audit_copy_fcaps(name, dentry);
 }
 
 
 
 extern void audit_copy_inode(struct audit_names *name,
                             const struct dentry *dentry,
-                            struct inode *inode);
+                            struct inode *inode, unsigned int flags);
 extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
                          kernel_cap_t *cap);
 extern void audit_log_name(struct audit_context *context,
 
                n->type = AUDIT_TYPE_NORMAL;
        }
        handle_path(dentry);
-       audit_copy_inode(n, dentry, inode);
+       audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NOEVAL);
 }
 
 void __audit_file(const struct file *file)
                n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
                if (!n)
                        return;
-               audit_copy_inode(n, NULL, parent);
+               audit_copy_inode(n, NULL, parent, 0);
        }
 
        if (!found_child) {
        }
 
        if (inode)
-               audit_copy_inode(found_child, dentry, inode);
+               audit_copy_inode(found_child, dentry, inode, 0);
        else
                found_child->ino = AUDIT_INO_UNSET;
 }