diff options
author | Dmitry Chagin <dchagin@FreeBSD.org> | 2023-04-04 20:24:04 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2023-06-29 10:50:41 +0000 |
commit | 0f287f6a96cacda32ee17447987add3e05aa5fc6 (patch) | |
tree | 5712f6a90cd1ea33a8dfd05d1a658cec1438f832 | |
parent | 4a1f66b81f24c4ae0207e2898eba145299609308 (diff) | |
download | src-0f287f6a96cacda32ee17447987add3e05aa5fc6.tar.gz src-0f287f6a96cacda32ee17447987add3e05aa5fc6.zip |
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)
-rw-r--r-- | sys/compat/linux/linux_dummy.c | 1 | ||||
-rw-r--r-- | sys/compat/linux/linux_file.c | 26 | ||||
-rw-r--r-- | sys/compat/linux/linux_file.h | 7 |
3 files changed, 33 insertions, 1 deletions
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_ */ |