* Later, fsnotify permission hooks do not check if there are permission event
  * watches, but that there were permission event watches at open time.
  */
-void file_set_fsnotify_mode(struct file *file)
+void file_set_fsnotify_mode_from_watchers(struct file *file)
 {
        struct dentry *dentry = file->f_path.dentry, *parent;
        struct super_block *sb = dentry->d_sb;
         */
        if (likely(!fsnotify_sb_has_priority_watchers(sb,
                                                FSNOTIFY_PRIO_CONTENT))) {
-               file->f_mode |= FMODE_NONOTIFY_PERM;
+               file_set_fsnotify_mode(file, FMODE_NONOTIFY_PERM);
                return;
        }
 
        if ((!d_is_dir(dentry) && !d_is_reg(dentry)) ||
            likely(!fsnotify_sb_has_priority_watchers(sb,
                                                FSNOTIFY_PRIO_PRE_CONTENT))) {
-               file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
+               file_set_fsnotify_mode(file, FMODE_NONOTIFY | FMODE_NONOTIFY_PERM);
                return;
        }
 
         */
        mnt_mask = READ_ONCE(real_mount(file->f_path.mnt)->mnt_fsnotify_mask);
        if (unlikely(fsnotify_object_watched(d_inode(dentry), mnt_mask,
-                                    FSNOTIFY_PRE_CONTENT_EVENTS)))
+                                    FSNOTIFY_PRE_CONTENT_EVENTS))) {
+               /* Enable pre-content events */
+               file_set_fsnotify_mode(file, 0);
                return;
+       }
 
        /* Is parent watching for pre-content events on this file? */
        if (dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED) {
                parent = dget_parent(dentry);
                p_mask = fsnotify_inode_watches_children(d_inode(parent));
                dput(parent);
-               if (p_mask & FSNOTIFY_PRE_CONTENT_EVENTS)
+               if (p_mask & FSNOTIFY_PRE_CONTENT_EVENTS) {
+                       /* Enable pre-content events */
+                       file_set_fsnotify_mode(file, 0);
                        return;
+               }
        }
        /* Nobody watching for pre-content events from this file */
-       file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
+       file_set_fsnotify_mode(file, FMODE_NONOTIFY | FMODE_NONOTIFY_PERM);
 }
 #endif
 
 
        f->f_sb_err = file_sample_sb_err(f);
 
        if (unlikely(f->f_flags & O_PATH)) {
-               f->f_mode = FMODE_PATH | FMODE_OPENED | FMODE_NONOTIFY;
+               f->f_mode = FMODE_PATH | FMODE_OPENED;
+               file_set_fsnotify_mode(f, FMODE_NONOTIFY);
                f->f_op = &empty_fops;
                return 0;
        }
         * If FMODE_NONOTIFY was already set for an fanotify fd, this doesn't
         * change anything.
         */
-       file_set_fsnotify_mode(f);
+       file_set_fsnotify_mode_from_watchers(f);
        error = fsnotify_open_perm(f);
        if (error)
                goto cleanup_all;
        if (!IS_ERR(f)) {
                int error;
 
-               f->f_mode |= FMODE_NONOTIFY;
+               file_set_fsnotify_mode(f, FMODE_NONOTIFY);
                error = vfs_open(path, f);
                if (error) {
                        fput(f);
 
 #define FMODE_FSNOTIFY_HSM(mode)       0
 #endif
 
-
 /*
  * Attribute flags.  These should be or-ed together to figure out what
  * has been changed!
        allow_write_access(exe_file);
 }
 
+static inline void file_set_fsnotify_mode(struct file *file, fmode_t mode)
+{
+       file->f_mode &= ~FMODE_FSNOTIFY_MASK;
+       file->f_mode |= mode;
+}
+
 static inline bool inode_is_open_for_write(const struct inode *inode)
 {
        return atomic_read(&inode->i_writecount) > 0;