Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/linux/linux_file.c
Show All 35 Lines | |||||
#include <sys/capsicum.h> | #include <sys/capsicum.h> | ||||
#include <sys/conf.h> | #include <sys/conf.h> | ||||
#include <sys/dirent.h> | #include <sys/dirent.h> | ||||
#include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||
#include <sys/file.h> | #include <sys/file.h> | ||||
#include <sys/filedesc.h> | #include <sys/filedesc.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mman.h> | |||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/namei.h> | #include <sys/namei.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/syscallsubr.h> | #include <sys/syscallsubr.h> | ||||
#include <sys/sysproto.h> | #include <sys/sysproto.h> | ||||
Show All 11 Lines | |||||
#endif | #endif | ||||
#include <compat/linux/linux_misc.h> | #include <compat/linux/linux_misc.h> | ||||
#include <compat/linux/linux_util.h> | #include <compat/linux/linux_util.h> | ||||
#include <compat/linux/linux_file.h> | #include <compat/linux/linux_file.h> | ||||
static int linux_common_open(struct thread *, int, char *, int, int); | static int linux_common_open(struct thread *, int, char *, int, int); | ||||
static int linux_getdents_error(struct thread *, int, int); | static int linux_getdents_error(struct thread *, int, int); | ||||
static struct bsd_to_linux_bitmap seal_bitmap[] = { | |||||
BITMAP_1t1_LINUX(F_SEAL_SEAL), | |||||
BITMAP_1t1_LINUX(F_SEAL_SHRINK), | |||||
BITMAP_1t1_LINUX(F_SEAL_GROW), | |||||
BITMAP_1t1_LINUX(F_SEAL_WRITE), | |||||
}; | |||||
#define MFD_HUGETLB_ENTRY(_size) \ | |||||
{ \ | |||||
.bsd_value = MFD_HUGE_##_size, \ | |||||
.linux_value = LINUX_HUGETLB_FLAG_ENCODE_##_size \ | |||||
} | |||||
static struct bsd_to_linux_bitmap mfd_bitmap[] = { | |||||
BITMAP_1t1_LINUX(MFD_CLOEXEC), | |||||
BITMAP_1t1_LINUX(MFD_ALLOW_SEALING), | |||||
BITMAP_1t1_LINUX(MFD_HUGETLB), | |||||
MFD_HUGETLB_ENTRY(64KB), | |||||
MFD_HUGETLB_ENTRY(512KB), | |||||
MFD_HUGETLB_ENTRY(1MB), | |||||
MFD_HUGETLB_ENTRY(2MB), | |||||
MFD_HUGETLB_ENTRY(8MB), | |||||
MFD_HUGETLB_ENTRY(16MB), | |||||
MFD_HUGETLB_ENTRY(32MB), | |||||
MFD_HUGETLB_ENTRY(256MB), | |||||
MFD_HUGETLB_ENTRY(512MB), | |||||
MFD_HUGETLB_ENTRY(1GB), | |||||
MFD_HUGETLB_ENTRY(2GB), | |||||
MFD_HUGETLB_ENTRY(16GB), | |||||
}; | |||||
#undef MFD_HUGETLB_ENTRY | |||||
#ifdef LINUX_LEGACY_SYSCALLS | #ifdef LINUX_LEGACY_SYSCALLS | ||||
int | int | ||||
linux_creat(struct thread *td, struct linux_creat_args *args) | linux_creat(struct thread *td, struct linux_creat_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
▲ Show 20 Lines • Show All 1,287 Lines • ▼ Show 20 Lines | if (fp->f_type == DTYPE_PIPE) { | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
return (kern_fcntl(td, args->fd, F_SETOWN, args->arg)); | return (kern_fcntl(td, args->fd, F_SETOWN, args->arg)); | ||||
case LINUX_F_DUPFD_CLOEXEC: | case LINUX_F_DUPFD_CLOEXEC: | ||||
return (kern_fcntl(td, args->fd, F_DUPFD_CLOEXEC, args->arg)); | return (kern_fcntl(td, args->fd, F_DUPFD_CLOEXEC, args->arg)); | ||||
/* | |||||
* Our F_SEAL_* values match Linux one for maximum compatibility. So we | |||||
* only needed to account for different values for fcntl(2) commands. | |||||
*/ | |||||
case LINUX_F_GET_SEALS: | |||||
error = kern_fcntl(td, args->fd, F_GET_SEALS, 0); | |||||
if (error != 0) | |||||
return (error); | |||||
td->td_retval[0] = bsd_to_linux_bits(td->td_retval[0], | |||||
seal_bitmap, 0); | |||||
return (0); | |||||
case LINUX_F_ADD_SEALS: | |||||
return (kern_fcntl(td, args->fd, F_ADD_SEALS, | |||||
linux_to_bsd_bits(args->arg, seal_bitmap, 0))); | |||||
default: | default: | ||||
linux_msg(td, "unsupported fcntl cmd %d\n", args->cmd); | linux_msg(td, "unsupported fcntl cmd %d\n", args->cmd); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
} | } | ||||
int | int | ||||
linux_fcntl(struct thread *td, struct linux_fcntl_args *args) | linux_fcntl(struct thread *td, struct linux_fcntl_args *args) | ||||
▲ Show 20 Lines • Show All 289 Lines • ▼ Show 20 Lines | error = kern_copy_file_range(td, args->fd_in, inoffp, args->fd_out, | ||||
outoffp, args->len, flags); | outoffp, args->len, flags); | ||||
if (error == 0 && args->off_in != NULL) | if (error == 0 && args->off_in != NULL) | ||||
error = copyout(inoffp, args->off_in, sizeof(l_loff_t)); | error = copyout(inoffp, args->off_in, sizeof(l_loff_t)); | ||||
if (error == 0 && args->off_out != NULL) | if (error == 0 && args->off_out != NULL) | ||||
error = copyout(outoffp, args->off_out, sizeof(l_loff_t)); | error = copyout(outoffp, args->off_out, sizeof(l_loff_t)); | ||||
return (error); | return (error); | ||||
} | } | ||||
#define LINUX_MEMFD_PREFIX "memfd:" | |||||
int | |||||
linux_memfd_create(struct thread *td, struct linux_memfd_create_args *args) | |||||
{ | |||||
char memfd_name[LINUX_NAME_MAX + 1]; | |||||
int error, flags, shmflags, oflags; | |||||
/* | |||||
* This is our clever trick to avoid the heap allocation to copy in the | |||||
* uname. We don't really need to go this far out of our way, but it | |||||
* does keep the rest of this function fairly clean as they don't have | |||||
* to worry about cleanup on the way out. | |||||
*/ | |||||
error = copyinstr(args->uname_ptr, | |||||
memfd_name + sizeof(LINUX_MEMFD_PREFIX) - 1, | |||||
LINUX_NAME_MAX - sizeof(LINUX_MEMFD_PREFIX) - 1, NULL); | |||||
if (error != 0) { | |||||
if (error == ENAMETOOLONG) | |||||
error = EINVAL; | |||||
return (error); | |||||
} | |||||
memcpy(memfd_name, LINUX_MEMFD_PREFIX, sizeof(LINUX_MEMFD_PREFIX) - 1); | |||||
flags = linux_to_bsd_bits(args->flags, mfd_bitmap, 0); | |||||
if ((flags & ~(MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB | | |||||
MFD_HUGE_MASK)) != 0) | |||||
return (EINVAL); | |||||
/* Size specified but no HUGETLB. */ | |||||
if ((flags & MFD_HUGE_MASK) != 0 && (flags & MFD_HUGETLB) == 0) | |||||
return (EINVAL); | |||||
/* We don't actually support HUGETLB. */ | |||||
if ((flags & MFD_HUGETLB) != 0) | |||||
return (ENOSYS); | |||||
oflags = O_RDWR; | |||||
shmflags = 0; | |||||
if ((flags & MFD_CLOEXEC) != 0) | |||||
oflags |= O_CLOEXEC; | |||||
if ((flags & MFD_ALLOW_SEALING) != 0) | |||||
shmflags |= SHM_ALLOW_SEALING; | |||||
return (kern_shm_open2(td, SHM_ANON, oflags, 0, shmflags, NULL, | |||||
memfd_name)); | |||||
} |