]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fsnotify: move fsnotify_open() hook into do_dentry_open()
authorAmir Goldstein <amir73il@gmail.com>
Sun, 11 Jun 2023 12:24:29 +0000 (15:24 +0300)
committerJan Kara <jack@suse.cz>
Mon, 12 Jun 2023 08:43:45 +0000 (10:43 +0200)
fsnotify_open() hook is called only from high level system calls
context and not called for the very many helpers to open files.

This may makes sense for many of the special file open cases, but it is
inconsistent with fsnotify_close() hook that is called for every last
fput() of on a file object with FMODE_OPENED.

As a result, it is possible to observe ACCESS, MODIFY and CLOSE events
without ever observing an OPEN event.

Fix this inconsistency by replacing all the fsnotify_open() hooks with
a single hook inside do_dentry_open().

If there are special cases that would like to opt-out of the possible
overhead of fsnotify() call in fsnotify_open(), they would probably also
want to avoid the overhead of fsnotify() call in the rest of the fsnotify
hooks, so they should be opening that file with the __FMODE_NONOTIFY flag.

However, in the majority of those cases, the s_fsnotify_connectors
optimization in fsnotify_parent() would be sufficient to avoid the
overhead of fsnotify() call anyway.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Message-Id: <20230611122429.1499617-1-amir73il@gmail.com>

fs/exec.c
fs/fhandle.c
fs/open.c
io_uring/openclose.c

index a466e797c8e2e67577be128e1e95775b00970d95..238473de1ec5382091dbf37b97dbabe30ce7c43a 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -152,8 +152,6 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
                         path_noexec(&file->f_path)))
                goto exit;
 
-       fsnotify_open(file);
-
        error = -ENOEXEC;
 
        read_lock(&binfmt_lock);
@@ -934,9 +932,6 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
        if (err)
                goto exit;
 
-       if (name->name[0] != '\0')
-               fsnotify_open(file);
-
 out:
        return file;
 
index fd0d6a3b3699b917476f4cd39b730b41d4935c98..6ea8d35a9382ace3fac22b89c818c74f0f123c34 100644 (file)
@@ -242,7 +242,6 @@ static long do_handle_open(int mountdirfd, struct file_handle __user *ufh,
                retval =  PTR_ERR(file);
        } else {
                retval = fd;
-               fsnotify_open(file);
                fd_install(fd, file);
        }
        path_put(&path);
index 4478adcc4f3a0570a9c8c586fbfe8fe2c642ac12..005ca91a173bd7e3534280f5eded980cfffbd475 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -969,6 +969,11 @@ static int do_dentry_open(struct file *f,
                }
        }
 
+       /*
+        * Once we return a file with FMODE_OPENED, __fput() will call
+        * fsnotify_close(), so we need fsnotify_open() here for symmetry.
+        */
+       fsnotify_open(f);
        return 0;
 
 cleanup_all:
@@ -1358,7 +1363,6 @@ static long do_sys_openat2(int dfd, const char __user *filename,
                        put_unused_fd(fd);
                        fd = PTR_ERR(f);
                } else {
-                       fsnotify_open(f);
                        fd_install(fd, f);
                }
        }
index a1b98c81a52d9c3028a298fdb2d2414dba1f497b..10ca57f5bd249522755db6ce5baf28cc83aca8a7 100644 (file)
@@ -150,7 +150,6 @@ int io_openat2(struct io_kiocb *req, unsigned int issue_flags)
 
        if ((issue_flags & IO_URING_F_NONBLOCK) && !nonblock_set)
                file->f_flags &= ~O_NONBLOCK;
-       fsnotify_open(file);
 
        if (!fixed)
                fd_install(ret, file);