All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v4 1/2] file: allow callers to free the old file descriptor after dup2
@ 2023-03-24  6:34 aloktiagi
  2023-03-24  6:34 ` [RFC v4 2/2] file, epoll: Implement do_replace() and eventpoll_replace() aloktiagi
  0 siblings, 1 reply; 15+ messages in thread
From: aloktiagi @ 2023-03-24  6:34 UTC (permalink / raw)
  To: viro, willy, brauner, David.Laight, linux-fsdevel, linux-kernel
  Cc: keescook, hch, aloktiagi

Allow callers of do_dup2 to get a reference to the file pointer being dup'ed
over. The callers can then replace the file with the new file in the eventpoll
interface or the file table before freeing it.

Signed-off-by: aloktiagi <aloktiagi@gmail.com>
---
Changes in v4:
  - Address review comment for a cleaner if else block in do_dup2() to free the
    file pointer.

Changes in v2:
  - Make the commit message more clearer.
  - Address review comment to make the interface cleaner so that the caller cannot
    forget to initialize the fdfile.
---
 fs/file.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 4b2346b8a5ee..cbc258504a64 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1086,7 +1086,7 @@ bool get_close_on_exec(unsigned int fd)
 }
 
 static int do_dup2(struct files_struct *files,
-	struct file *file, unsigned fd, unsigned flags)
+	struct file *file, unsigned fd, struct file **fdfile, unsigned flags)
 __releases(&files->file_lock)
 {
 	struct file *tofree;
@@ -1119,7 +1119,9 @@ __releases(&files->file_lock)
 		__clear_close_on_exec(fd, fdt);
 	spin_unlock(&files->file_lock);
 
-	if (tofree)
+	if (fdfile)
+		*fdfile = tofree;
+	else if (tofree)
 		filp_close(tofree, files);
 
 	return fd;
@@ -1132,6 +1134,7 @@ __releases(&files->file_lock)
 int replace_fd(unsigned fd, struct file *file, unsigned flags)
 {
 	int err;
+	struct file *fdfile = NULL;
 	struct files_struct *files = current->files;
 
 	if (!file)
@@ -1144,7 +1147,10 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags)
 	err = expand_files(files, fd);
 	if (unlikely(err < 0))
 		goto out_unlock;
-	return do_dup2(files, file, fd, flags);
+	err = do_dup2(files, file, fd, &fdfile, flags);
+	if (fdfile)
+		filp_close(fdfile, files);
+	return err;
 
 out_unlock:
 	spin_unlock(&files->file_lock);
@@ -1237,7 +1243,7 @@ static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
 			goto Ebadf;
 		goto out_unlock;
 	}
-	return do_dup2(files, file, newfd, flags);
+	return do_dup2(files, file, newfd, NULL, flags);
 
 Ebadf:
 	err = -EBADF;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread
* [RFC v2 1/3] file: Introduce iterate_fd_locked
@ 2023-03-18  6:02 aloktiagi
  2023-03-18  6:02 ` [RFC v2 2/3] file: allow callers to free the old file descriptor after dup2 aloktiagi
  2023-03-18  6:02 ` [RFC v2 3/3] file, epoll: Implement do_replace() and eventpoll_replace() aloktiagi
  0 siblings, 2 replies; 15+ messages in thread
From: aloktiagi @ 2023-03-18  6:02 UTC (permalink / raw)
  To: viro, David.Laight, linux-fsdevel, linux-kernel
  Cc: keescook, hch, aloktiagi, Tycho Andersen

Callers holding the files->file_lock lock can call iterate_fd_locked instead of
iterate_fd

Signed-off-by: aloktiagi <aloktiagi@gmail.com>
Reviewed-by: Tycho Andersen <tycho@tycho.pizza>
---
 fs/file.c               | 21 +++++++++++++++------
 include/linux/fdtable.h |  3 +++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index c942c89ca4cd..4b2346b8a5ee 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1295,15 +1295,12 @@ int f_dupfd(unsigned int from, struct file *file, unsigned flags)
 	return err;
 }
 
-int iterate_fd(struct files_struct *files, unsigned n,
-		int (*f)(const void *, struct file *, unsigned),
-		const void *p)
+int iterate_fd_locked(struct files_struct *files, unsigned n,
+                int (*f)(const void *, struct file *, unsigned),
+                const void *p)
 {
 	struct fdtable *fdt;
 	int res = 0;
-	if (!files)
-		return 0;
-	spin_lock(&files->file_lock);
 	for (fdt = files_fdtable(files); n < fdt->max_fds; n++) {
 		struct file *file;
 		file = rcu_dereference_check_fdtable(files, fdt->fd[n]);
@@ -1313,6 +1310,18 @@ int iterate_fd(struct files_struct *files, unsigned n,
 		if (res)
 			break;
 	}
+	return res;
+}
+
+int iterate_fd(struct files_struct *files, unsigned n,
+		int (*f)(const void *, struct file *, unsigned),
+		const void *p)
+{
+	int res = 0;
+	if (!files)
+		return 0;
+	spin_lock(&files->file_lock);
+	res = iterate_fd_locked(files, n, f, p);
 	spin_unlock(&files->file_lock);
 	return res;
 }
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index e066816f3519..14882520d1fe 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -122,6 +122,9 @@ void do_close_on_exec(struct files_struct *);
 int iterate_fd(struct files_struct *, unsigned,
 		int (*)(const void *, struct file *, unsigned),
 		const void *);
+int iterate_fd_locked(struct files_struct *, unsigned,
+			int (*)(const void *, struct file *, unsigned),
+			const void *);
 
 extern int close_fd(unsigned int fd);
 extern int __close_range(unsigned int fd, unsigned int max_fd, unsigned int flags);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-03-27 20:40 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-24  6:34 [RFC v4 1/2] file: allow callers to free the old file descriptor after dup2 aloktiagi
2023-03-24  6:34 ` [RFC v4 2/2] file, epoll: Implement do_replace() and eventpoll_replace() aloktiagi
2023-03-24  9:03   ` kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2023-03-18  6:02 [RFC v2 1/3] file: Introduce iterate_fd_locked aloktiagi
2023-03-18  6:02 ` [RFC v2 2/3] file: allow callers to free the old file descriptor after dup2 aloktiagi
2023-03-18  6:02 ` [RFC v2 3/3] file, epoll: Implement do_replace() and eventpoll_replace() aloktiagi
2023-03-18  8:10   ` kernel test robot
2023-03-20 14:51   ` Christian Brauner
2023-03-23 22:23     ` Alok Tiagi
2023-03-24  8:23       ` [RFC v4 2/2] " Christian Brauner
2023-03-24 13:43         ` Tycho Andersen
2023-03-27  9:01           ` Christian Brauner
2023-03-27 13:06             ` Tycho Andersen
2023-03-27 13:16               ` Tycho Andersen
2023-03-27 20:39                 ` Alok Tiagi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.