git: 4231b825ac19 - main - linux(4): Add a dedicated writev syscall wrapper

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Sun, 20 Aug 2023 07:37:48 UTC
The branch main has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=4231b825ac19112b84b4001625e0ef7a80e82f80

commit 4231b825ac19112b84b4001625e0ef7a80e82f80
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2023-08-20 07:36:31 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2023-08-20 07:36:31 +0000

    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
---
 sys/amd64/linux32/linux32_machdep.c | 14 --------------
 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));
+}