diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-09-10 17:48:03 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-09-14 15:58:06 +0200 |
| commit | 7e6ad3fe9136fefed8fea8ac6d3a14fe2808a58d (patch) | |
| tree | 06adda9643b92324c18d09f7c4da2c5b2fe92542 | |
| parent | bf1b25dc344d77c8e4f3b48fe0662f82e9ba98ce (diff) | |
| download | linux-next-7e6ad3fe9136fefed8fea8ac6d3a14fe2808a58d.tar.gz linux-next-7e6ad3fe9136fefed8fea8ac6d3a14fe2808a58d.zip | |
fs: add filp_close_sync()
Currently close() already does a synchronous release of the last
reference since the task is about to return to userspace and the
deferral through task work buys nothing. Add a filp_close_sync() helper.
We'll use that in the next patches.
No functional changes.
Link: https://patch.msgid.link/20260910-work-coredump-unlock-self-v4-5-a5c1800dc930@kernel.org
Reviewed-by: NeilBrown <neil@brown.name>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
| -rw-r--r-- | fs/internal.h | 1 | ||||
| -rw-r--r-- | fs/open.c | 17 |
2 files changed, 15 insertions, 3 deletions
diff --git a/fs/internal.h b/fs/internal.h index c658c8a5ebd5..8812de210d3f 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -198,6 +198,7 @@ extern struct file *do_file_open_root(const struct path *, extern struct open_how build_open_how(int flags, umode_t mode); extern int build_open_flags(const struct open_how *how, struct open_flags *op); struct file *file_close_fd_locked(struct files_struct *files, unsigned fd); +int filp_close_sync(struct file *filp, fl_owner_t id); int do_ftruncate(struct file *file, loff_t length, unsigned int flags); int chmod_common(const struct path *path, umode_t mode); diff --git a/fs/open.c b/fs/open.c index 6b1c14e684a9..998e42ac319a 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1537,6 +1537,19 @@ int filp_close(struct file *filp, fl_owner_t id) } EXPORT_SYMBOL(filp_close); +/* Like filp_close() but the last reference is put right here. */ +int filp_close_sync(struct file *filp, fl_owner_t id) +{ + int retval; + + /* Kernel threads must never put their final reference here. */ + VFS_WARN_ON_ONCE(current->flags & PF_KTHREAD); + retval = filp_flush(filp, id); + fput_close_sync(filp); + + return retval; +} + /* * Careful here! We test whether the file pointer is NULL before * releasing the fd. This ensures that one clone task can't release @@ -1551,13 +1564,11 @@ SYSCALL_DEFINE1(close, unsigned int, fd) if (!file) return -EBADF; - retval = filp_flush(file, current->files); - /* * We're returning to user space. Don't bother * with any delayed fput() cases. */ - fput_close_sync(file); + retval = filp_close_sync(file, current->files); if (likely(retval == 0)) return 0; |
