git: 0f287f6a96ca - stable/13 - linux(4): Implement close_range over native

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Thu, 29 Jun 2023 10:56:31 UTC
The branch stable/13 has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=0f287f6a96cacda32ee17447987add3e05aa5fc6

commit 0f287f6a96cacda32ee17447987add3e05aa5fc6
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2023-04-04 20:24:04 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2023-06-29 10:50:41 +0000

    linux(4): Implement close_range over native
    
    Handling of the CLOSE_RANGE_UNSHARE flag is not implemented due to
    difference in fd unsharing mechanism in the Linux and FreeBSD.
    
    Reviewed by:            mjg
    Differential revision:  https://reviews.freebsd.org/D39398
    MFC after:              2 weeks
    
    (cherry picked from commit 71bc17803edfaad545f0c1f1111ca892aed7a5c4)
---
 sys/compat/linux/linux_dummy.c |  1 -
 sys/compat/linux/linux_file.c  | 26 ++++++++++++++++++++++++++
 sys/compat/linux/linux_file.h  |  7 +++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c
index 45b0db6d6dde..e3812218514c 100644
--- a/sys/compat/linux/linux_dummy.c
+++ b/sys/compat/linux/linux_dummy.c
@@ -135,7 +135,6 @@ DUMMY(fsconfig);
 DUMMY(fsmount);
 DUMMY(fspick);
 DUMMY(pidfd_open);
-DUMMY(close_range);
 DUMMY(openat2);
 DUMMY(pidfd_getfd);
 DUMMY(process_madvise);
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 249318a2e619..4ce0a2cb4c0e 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -2083,3 +2083,29 @@ linux_splice(struct thread *td, struct linux_splice_args *args)
 	 */
 	return (EINVAL);
 }
+
+int
+linux_close_range(struct thread *td, struct linux_close_range_args *args)
+{
+	u_int flags = 0;
+
+	/*
+	 * Implementing close_range(CLOSE_RANGE_UNSHARE) allows Linux to
+	 * unshare filedesc table of the calling thread from others threads
+	 * in a thread group (i.e., process in the FreeBSD) or others processes,
+	 * which shares the same table, before closing the files. FreeBSD does
+	 * not have compatible unsharing mechanism due to the fact that sharing
+	 * process resources, including filedesc table, is at thread level in the
+	 * Linux, while in the FreeBSD it is at the process level.
+	 * Return EINVAL for now if the CLOSE_RANGE_UNSHARE flag is specified
+	 * until this new Linux API stabilizes.
+	 */
+
+	if ((args->flags & ~(LINUX_CLOSE_RANGE_CLOEXEC)) != 0)
+		return (EINVAL);
+	if (args->first > args->last)
+		return (EINVAL);
+	if ((args->flags & LINUX_CLOSE_RANGE_CLOEXEC) != 0)
+		flags |= CLOSE_RANGE_CLOEXEC;
+	return (kern_close_range(td, flags, args->first, args->last));
+}
diff --git a/sys/compat/linux/linux_file.h b/sys/compat/linux/linux_file.h
index 3f885f915411..061bd1fc2c24 100644
--- a/sys/compat/linux/linux_file.h
+++ b/sys/compat/linux/linux_file.h
@@ -197,4 +197,11 @@ struct l_file_handle {
 	unsigned char f_handle[0];
 };
 
+/*
+ * Look at linux_close_range() for an explanation.
+ *
+ * #define	LINUX_CLOSE_RANGE_UNSHARE	(1U << 1)
+ */
+#define	LINUX_CLOSE_RANGE_CLOEXEC	(1U << 2)
+
 #endif	/* !_LINUX_FILE_H_ */