if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
                goto exit;
 
-       error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
+       error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN);
        if (error)
                goto exit;
 
                struct inode *inode = nd.path.dentry->d_inode;
                file = ERR_PTR(-EACCES);
                if (S_ISREG(inode->i_mode)) {
-                       int err = vfs_permission(&nd, MAY_EXEC);
+                       int err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN);
                        file = ERR_PTR(err);
                        if (!err) {
                                file = nameidata_to_filp(&nd,
 
 
        /* Ordinary permission routines do not understand MAY_APPEND. */
        if (inode->i_op && inode->i_op->permission) {
-               int extra = 0;
-               if (nd) {
-                       if (nd->flags & LOOKUP_OPEN)
-                               extra |= MAY_OPEN;
-               }
-               retval = inode->i_op->permission(inode, mask | extra);
+               retval = inode->i_op->permission(inode, mask);
                if (!retval) {
                        /*
                         * Exec permission on a regular file is denied if none
                return retval;
 
        return security_inode_permission(inode,
-                       mask & (MAY_READ|MAY_WRITE|MAY_EXEC), nd);
+                       mask & (MAY_READ|MAY_WRITE|MAY_EXEC));
 }
 
 /**
 
        return -EACCES;
 ok:
-       return security_inode_permission(inode, MAY_EXEC, nd);
+       return security_inode_permission(inode, MAY_EXEC);
 }
 
 /*
        int will_write;
        int flag = open_to_namei_flags(open_flag);
 
-       acc_mode = ACC_MODE(flag);
+       acc_mode = MAY_OPEN | ACC_MODE(flag);
 
        /* O_TRUNC implies we need access checks for write permissions */
        if (flag & O_TRUNC)
 
                             struct inode *new_dir, struct dentry *new_dentry);
        int (*inode_readlink) (struct dentry *dentry);
        int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
-       int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
+       int (*inode_permission) (struct inode *inode, int mask);
        int (*inode_setattr)    (struct dentry *dentry, struct iattr *attr);
        int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
        void (*inode_delete) (struct inode *inode);
                          struct inode *new_dir, struct dentry *new_dentry);
 int security_inode_readlink(struct dentry *dentry);
 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
-int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
+int security_inode_permission(struct inode *inode, int mask);
 int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
 int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
 void security_inode_delete(struct inode *inode);
        return 0;
 }
 
-static inline int security_inode_permission(struct inode *inode, int mask,
-                                            struct nameidata *nd)
+static inline int security_inode_permission(struct inode *inode, int mask)
 {
        return 0;
 }
 
        return 0;
 }
 
-static int cap_inode_permission(struct inode *inode, int mask,
-                               struct nameidata *nd)
+static int cap_inode_permission(struct inode *inode, int mask)
 {
        return 0;
 }
 
        return security_ops->inode_follow_link(dentry, nd);
 }
 
-int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
+int security_inode_permission(struct inode *inode, int mask)
 {
        if (unlikely(IS_PRIVATE(inode)))
                return 0;
-       return security_ops->inode_permission(inode, mask, nd);
+       return security_ops->inode_permission(inode, mask);
 }
 
 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
 
        return dentry_has_perm(current, NULL, dentry, FILE__READ);
 }
 
-static int selinux_inode_permission(struct inode *inode, int mask,
-                                   struct nameidata *nd)
+static int selinux_inode_permission(struct inode *inode, int mask)
 {
        int rc;
 
-       rc = secondary_ops->inode_permission(inode, mask, nd);
+       rc = secondary_ops->inode_permission(inode, mask);
        if (rc)
                return rc;
 
 
  *
  * Returns 0 if access is permitted, -EACCES otherwise
  */
-static int smack_inode_permission(struct inode *inode, int mask,
-                                 struct nameidata *nd)
+static int smack_inode_permission(struct inode *inode, int mask)
 {
        /*
         * No permission to check. Existence test. Yup, it's there.