diff options
author | Dmitry Chagin <dchagin@FreeBSD.org> | 2023-08-20 07:36:31 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2023-08-20 07:36:31 +0000 |
commit | 4231b825ac19112b84b4001625e0ef7a80e82f80 (patch) | |
tree | d20a0e8a3a141b2cea49d4216867bd0e697e0a3d | |
parent | 1f9d71ee32cf74ece18f36b31c7e9ea1613be730 (diff) | |
download | src-4231b825ac19112b84b4001625e0ef7a80e82f80.tar.gz src-4231b825ac19112b84b4001625e0ef7a80e82f80.zip |
linux(4): Add a dedicated writev syscall wrapper
Adding a writev syscall wrapper is needed due to Linux family of write
syscalls doesn't distinguish between in kernel blocking operations
and always returns EAGAIN while FreeBSD can return ENOBUFS.
MFC after: 1 month
-rw-r--r-- | sys/amd64/linux32/linux32_machdep.c | 14 | ||||
-rw-r--r-- | sys/compat/linux/linux_file.c | 19 |
2 files changed, 19 insertions, 14 deletions
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index 2598384aada5..ac8234503bdd 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -196,20 +196,6 @@ linux_readv(struct thread *td, struct linux_readv_args *uap) return (error); } -int -linux_writev(struct thread *td, struct linux_writev_args *uap) -{ - struct uio *auio; - int error; - - error = linux32_copyinuio(uap->iovp, uap->iovcnt, &auio); - if (error) - return (error); - error = kern_writev(td, uap->fd, auio); - free(auio, M_IOV); - return (error); -} - struct l_ipc_kludge { l_uintptr_t msgp; l_long msgtyp; diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 6a1f61984b08..27b6e1a5f77d 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -47,6 +47,7 @@ #ifdef COMPAT_LINUX32 #include <compat/freebsd32/freebsd32_misc.h> +#include <compat/freebsd32/freebsd32_util.h> #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> #else @@ -1855,3 +1856,21 @@ linux_write(struct thread *td, struct linux_write_args *args) return (linux_enobufs2eagain(td, args->fd, sys_write(td, &bargs))); } + +int +linux_writev(struct thread *td, struct linux_writev_args *args) +{ + struct uio *auio; + int error; + +#ifdef COMPAT_LINUX32 + error = freebsd32_copyinuio(PTRIN(args->iovp), args->iovcnt, &auio); +#else + error = copyinuio(args->iovp, args->iovcnt, &auio); +#endif + if (error != 0) + return (error); + error = kern_writev(td, args->fd, auio); + free(auio, M_IOV); + return (linux_enobufs2eagain(td, args->fd, error)); +} |