diff --git a/fs/namei.c b/fs/namei.c
index 82da447..5e213a89 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -330,6 +330,8 @@ static int acl_permission_check(struct inode *inode, int mask)
 int generic_permission(struct inode *inode, int mask)
 {
 	int ret;
+	bool has_cap_dac_override = false;
+	bool has_cap_dac_read_search = false;
 
 	/*
 	 * Do the basic permission checks.
@@ -344,12 +346,18 @@ int generic_permission(struct inode *inode, int mask)
 		return -ECHILD;
 #endif
 
+	has_cap_dac_override = capable_wrt_inode_uidgid_nolog(inode, CAP_DAC_OVERRIDE);
+	has_cap_dac_read_search = capable_wrt_inode_uidgid_nolog(inode, CAP_DAC_READ_SEARCH);
+
 	if (S_ISDIR(inode->i_mode)) {
 		/* DACs are overridable for directories */
-		if (!(mask & MAY_WRITE))
-			if (capable_wrt_inode_uidgid_nolog(inode, CAP_DAC_OVERRIDE) ||
-			    capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
-				return 0;
+		if (!(mask & MAY_WRITE)) {
+			if (!has_cap_dac_override || (has_cap_dac_override && has_cap_dac_read_search)) {
+				if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
+					return 0;
+				return -EACCES;
+			}
+		}
 		if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
 			return 0;
 		return -EACCES;
@@ -358,10 +366,22 @@ int generic_permission(struct inode *inode, int mask)
 	 * Searching includes executable on directories, else just read.
 	 */
 	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
-	if (mask == MAY_READ)
-		if (capable_wrt_inode_uidgid_nolog(inode, CAP_DAC_OVERRIDE) ||
-		    capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
-			return 0;
+	if (mask == MAY_READ) {
+		/* this part is a little different, as when we don't override here and return,
+		   we do want to have both caps logged/learned
+		 */
+		if (!has_cap_dac_override || (has_cap_dac_override && has_cap_dac_read_search)) {
+			if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
+				return 0;
+		} else if (!has_cap_dac_read_search) {
+			/* for this case though, if they don't have CAP_DAC_OVERRIDE, there's no point
+			   in checking and logging it again
+			*/
+			if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
+				return 0;
+			return -EACCES;
+		}
+	}
 
 	/*
 	 * Read/write DACs are always overridable.
