summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-09-10 17:48:03 +0200
committerChristian Brauner <brauner@kernel.org>2026-09-14 15:58:06 +0200
commit7e6ad3fe9136fefed8fea8ac6d3a14fe2808a58d (patch)
tree06adda9643b92324c18d09f7c4da2c5b2fe92542
parentbf1b25dc344d77c8e4f3b48fe0662f82e9ba98ce (diff)
downloadlinux-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.h1
-rw-r--r--fs/open.c17
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;