summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormmokhi <mmokhi@FreeBSD.org>2017-03-08 13:09:12 +0000
committermmokhi <mmokhi@FreeBSD.org>2017-03-08 13:09:12 +0000
commit2b2028ab5734299ea38019edcf70af4f8709383d (patch)
tree76338b3007afb1674957c7f8f7ee735a540db10a /sys
parentf5e89bc56ac58006ef4f13939001c3d80dd71341 (diff)
downloadFreeBSD-src-2b2028ab5734299ea38019edcf70af4f8709383d.zip
FreeBSD-src-2b2028ab5734299ea38019edcf70af4f8709383d.tar.gz
MFC r314219
Add linux_preadv() and linux_pwritev() syscalls to Linuxulator. Approved by: dchagin
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/linux/linux_dummy.c3
-rw-r--r--sys/amd64/linux32/linux.h3
-rw-r--r--sys/amd64/linux32/linux32_dummy.c3
-rw-r--r--sys/amd64/linux32/linux32_machdep.c2
-rw-r--r--sys/compat/linux/linux_file.c56
-rw-r--r--sys/i386/linux/linux_dummy.c3
6 files changed, 60 insertions, 10 deletions
diff --git a/sys/amd64/linux/linux_dummy.c b/sys/amd64/linux/linux_dummy.c
index efe18fd..85b6757 100644
--- a/sys/amd64/linux/linux_dummy.c
+++ b/sys/amd64/linux/linux_dummy.c
@@ -111,9 +111,6 @@ DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
DUMMY(inotify_init1);
-/* linux 2.6.30: */
-DUMMY(preadv);
-DUMMY(pwritev);
/* linux 2.6.31: */
DUMMY(rt_tgsigqueueinfo);
DUMMY(perf_event_open);
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 97da878..687f8e8 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -663,6 +663,7 @@ struct l_user_desc {
(((desc)->b >> LINUX_ENTRY_B_USEABLE) & 1)
struct iovec;
+struct uio;
struct l_iovec32 {
uint32_t iov_base;
@@ -671,6 +672,8 @@ struct l_iovec32 {
int linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt,
struct iovec **iovp, int error);
+int linux32_copyinuio(struct l_iovec32 *iovp, l_ulong iovcnt,
+ struct uio **uiop);
int linux_copyout_rusage(struct rusage *ru, void *uaddr);
/* robust futexes */
diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c
index 74e89a9..27f26f4 100644
--- a/sys/amd64/linux32/linux32_dummy.c
+++ b/sys/amd64/linux32/linux32_dummy.c
@@ -110,9 +110,6 @@ DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
DUMMY(inotify_init1);
-/* linux 2.6.30: */
-DUMMY(preadv);
-DUMMY(pwritev);
/* linux 2.6.31: */
DUMMY(rt_tgsigqueueinfo);
DUMMY(perf_event_open);
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 187ec15..74f9315 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -144,7 +144,7 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
CTASSERT(sizeof(struct l_iovec32) == 8);
-static int
+int
linux32_copyinuio(struct l_iovec32 *iovp, l_ulong iovcnt, struct uio **uiop)
{
struct l_iovec32 iov32;
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index b5126f4..7ca2ac7 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -1062,6 +1062,62 @@ linux_pwrite(td, uap)
}
int
+linux_preadv(struct thread *td, struct linux_preadv_args *uap)
+{
+ struct uio *auio;
+ int error;
+ off_t offset;
+
+ /*
+ * According http://man7.org/linux/man-pages/man2/preadv.2.html#NOTES
+ * pos_l and pos_h, respectively, contain the
+ * low order and high order 32 bits of offset.
+ */
+ offset = (((off_t)uap->pos_h << (sizeof(offset) * 4)) <<
+ (sizeof(offset) * 4)) | uap->pos_l;
+ if (offset < 0)
+ return (EINVAL);
+#ifdef COMPAT_LINUX32
+ error = linux32_copyinuio(PTRIN(uap->vec), uap->vlen, &auio);
+#else
+ error = copyinuio(uap->vec, uap->vlen, &auio);
+#endif
+ if (error != 0)
+ return (error);
+ error = kern_preadv(td, uap->fd, auio, offset);
+ free(auio, M_IOV);
+ return (error);
+}
+
+int
+linux_pwritev(struct thread *td, struct linux_pwritev_args *uap)
+{
+ struct uio *auio;
+ int error;
+ off_t offset;
+
+ /*
+ * According http://man7.org/linux/man-pages/man2/pwritev.2.html#NOTES
+ * pos_l and pos_h, respectively, contain the
+ * low order and high order 32 bits of offset.
+ */
+ offset = (((off_t)uap->pos_h << (sizeof(offset) * 4)) <<
+ (sizeof(offset) * 4)) | uap->pos_l;
+ if (offset < 0)
+ return (EINVAL);
+#ifdef COMPAT_LINUX32
+ error = linux32_copyinuio(PTRIN(uap->vec), uap->vlen, &auio);
+#else
+ error = copyinuio(uap->vec, uap->vlen, &auio);
+#endif
+ if (error != 0)
+ return (error);
+ error = kern_pwritev(td, uap->fd, auio, offset);
+ free(auio, M_IOV);
+ return (error);
+}
+
+int
linux_mount(struct thread *td, struct linux_mount_args *args)
{
char fstypename[MFSNAMELEN];
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 9aafeb3..f046600 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -106,9 +106,6 @@ DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
DUMMY(inotify_init1);
-/* linux 2.6.30: */
-DUMMY(preadv);
-DUMMY(pwritev);
/* linux 2.6.31: */
DUMMY(rt_tgsigqueueinfo);
DUMMY(perf_event_open);
OpenPOWER on IntegriCloud