All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RfC / experimental patch] preadv/pwritev code for qemu
Date: Fri, 23 Jan 2009 13:17:16 +0100	[thread overview]
Message-ID: <4979B54C.7090009@redhat.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 179 bytes --]

  Hi,

You needs also the kernel patches if you wanna play with this on linux.
On *BSD it should detect preadv being present and use it.

No code uses this (yet).

cheers,
  Gerd

[-- Attachment #2: 0003-preadv-writev-code-for-qemu.patch --]
[-- Type: text/plain, Size: 6415 bytes --]

>From 8b640cab61853efa622e17bb9145fe242fffc5a4 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Thu, 22 Jan 2009 16:22:41 +0100
Subject: [PATCH 3/3] preadv/writev code for qemu.


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile           |    1 +
 configure          |   13 +++++
 qemu-common.h      |    3 +
 qemu-io-syscalls.c |  152 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 169 insertions(+), 0 deletions(-)
 create mode 100644 qemu-io-syscalls.c

diff --git a/Makefile b/Makefile
index a09d6e0..d61f914 100644
--- a/Makefile
+++ b/Makefile
@@ -85,6 +85,7 @@ OBJS+=sd.o ssi-sd.o
 OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
 OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
 OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
+OBJS+=qemu-io-syscalls.o
 
 ifdef CONFIG_BRLAPI
 OBJS+= baum.o
diff --git a/configure b/configure
index 6a1432a..3cd0e62 100755
--- a/configure
+++ b/configure
@@ -1027,6 +1027,16 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
 fi
 
 ##########################################
+# preadv probe
+cat > $TMPC <<EOF
+int main(void) { preadv; }
+EOF
+preadv=no
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
+  preadv=yes
+fi
+
+##########################################
 # fdt probe
 if test "$fdt" = "yes" ; then
     fdt=no
@@ -1422,6 +1432,9 @@ fi
 if test "$iovec" = "yes" ; then
   echo "#define HAVE_IOVEC 1" >> $config_h
 fi
+if test "$preadv" = "yes" ; then
+  echo "#define HAVE_PREADV 1" >> $config_h
+fi
 if test "$fdt" = "yes" ; then
   echo "#define HAVE_FDT 1" >> $config_h
   echo "FDT_LIBS=-lfdt" >> $config_mak
diff --git a/qemu-common.h b/qemu-common.h
index 42d5e49..0dfc575 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -204,6 +204,9 @@ void qemu_iovec_destroy(QEMUIOVector *qiov);
 void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf);
 void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count);
 
+ssize_t qemu_preadv(int fd, QEMUIOVector *qiov, off_t offset);
+ssize_t qemu_pwritev(int fd, QEMUIOVector *qiov, off_t offset);
+
 #endif /* dyngen-exec.h hack */
 
 #endif
diff --git a/qemu-io-syscalls.c b/qemu-io-syscalls.c
new file mode 100644
index 0000000..79804d7
--- /dev/null
+++ b/qemu-io-syscalls.c
@@ -0,0 +1,152 @@
+/*
+ *  preadv/pwritev implementation
+ *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include <qemu-common.h>
+#include <unistd.h>
+
+/* --------------------------------------------------------------- */
+/* linux: preadv/pwritev syscall windup                            */
+
+#ifndef HAVE_PREADV
+# ifdef __linux__
+#  include <sys/syscall.h>
+
+#if 0
+/* WARNING: Be sure you know what you are doing if you enable this.
+ * linux syscall code isn't upstream yet, syscall numbers are subject
+ * to change */
+#  ifndef __NR_preadv
+#   ifdef __i386__
+#    define __NR_preadv  333
+#    define __NR_pwritev 334
+#   endif
+#   ifdef __x86_64__
+#    define __NR_preadv  295
+#    define __NR_pwritev 296
+#   endif
+#  endif
+#endif
+
+#  ifdef __NR_preadv
+#   define HAVE_PREADV 1
+
+static ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+    uint32_t pos_high = (offset >> 32) & 0xffffffff;
+    uint32_t pos_low  =  offset        & 0xffffffff;
+    ssize_t ret;
+
+    ret = syscall(__NR_preadv, fd, iov, iovcnt, pos_high, pos_low);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
+}
+
+static ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+    uint32_t pos_high = (offset >> 32) & 0xffffffff;
+    uint32_t pos_low  =  offset        & 0xffffffff;
+    ssize_t ret;
+
+    ret = syscall(__NR_pwritev, fd, iov, iovcnt, pos_high, pos_low);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
+}
+
+#  endif /* __NR_preadv */
+# endif /* __linux__ */
+
+#endif /* HAVE_PREADV */
+
+/* --------------------------------------------------------------- */
+/* preadv/pwritev emulation                                        */
+
+static ssize_t emulate_prwv(int fd, QEMUIOVector *qiov,
+                            off_t offset, int is_write)
+{
+    uint8_t *buf;
+    ssize_t ret;
+
+    buf = malloc(qiov->size);
+    if (NULL == buf) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    if (is_write) {
+        qemu_iovec_to_buffer(qiov, buf);
+        ret = pwrite(fd, buf, qiov->size, offset);
+    } else {
+        ret = pread(fd, buf, qiov->size, offset);
+        if (ret > 0)
+            qemu_iovec_from_buffer(qiov, buf, ret);
+    }
+
+    free(buf);
+    return ret;
+}
+
+/* --------------------------------------------------------------- */
+/* qemu preadv/pwritev interface */
+
+#ifdef HAVE_PREADV
+static int preadv_present = 1;
+#endif
+
+ssize_t qemu_preadv(int fd, QEMUIOVector *qiov, off_t offset)
+{
+#ifdef HAVE_PREADV
+    ssize_t ret;
+
+    if (preadv_present) {
+        ret = preadv(fd, qiov->iov, qiov->niov, offset);
+        if (ret < 0 && errno == ENOSYS) {
+            preadv_present = 0;
+            goto emulate;
+        }
+        return ret;
+    }
+emulate:
+#endif
+
+    return emulate_prwv(fd, qiov, offset, 0);
+}
+
+ssize_t qemu_pwritev(int fd, QEMUIOVector *qiov, off_t offset)
+{
+#ifdef HAVE_PREADV
+    ssize_t ret;
+
+    if (preadv_present) {
+        ret = pwritev(fd, qiov->iov, qiov->niov, offset);
+        if (ret < 0 && errno == ENOSYS) {
+            preadv_present = 0;
+            goto emulate;
+        }
+        return ret;
+    }
+emulate:
+#endif
+
+    return emulate_prwv(fd, qiov, offset, 1);
+}
-- 
1.6.1


                 reply	other threads:[~2009-01-23 12:17 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4979B54C.7090009@redhat.com \
    --to=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.