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
This commit is contained in:
Dmitry Chagin 2023-04-04 23:24:04 +03:00
parent 50111714f5
commit 71bc17803e
3 changed files with 33 additions and 1 deletions

View File

@ -135,7 +135,6 @@ DUMMY(fsconfig);
DUMMY(fsmount);
DUMMY(fspick);
DUMMY(pidfd_open);
DUMMY(close_range);
DUMMY(openat2);
DUMMY(pidfd_getfd);
DUMMY(process_madvise);

View File

@ -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));
}

View File

@ -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_ */