block/nfs: try to avoid the bounce buffer in pwritev
authorPeter Lieven <pl@kamp.de>
Fri, 17 Feb 2017 16:39:01 +0000 (17:39 +0100)
committerJeff Cody <jcody@redhat.com>
Fri, 24 Feb 2017 17:38:35 +0000 (12:38 -0500)
if the passed qiov contains exactly one iov we can
pass the buffer directly.

Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Message-id: 1487349541-10201-3-git-send-email-pl@kamp.de
Signed-off-by: Jeff Cody <jcody@redhat.com>
block/nfs.c

index c11c4c96b5adb699f27964c3519a845e66c9247b..ffb54be0651384ef9854f4a0e8a6376d85433fbf 100644 (file)
@@ -302,20 +302,27 @@ static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
     NFSClient *client = bs->opaque;
     NFSRPC task;
     char *buf = NULL;
+    bool my_buffer = false;
 
     nfs_co_init_task(bs, &task);
 
-    buf = g_try_malloc(bytes);
-    if (bytes && buf == NULL) {
-        return -ENOMEM;
+    if (iov->niov != 1) {
+        buf = g_try_malloc(bytes);
+        if (bytes && buf == NULL) {
+            return -ENOMEM;
+        }
+        qemu_iovec_to_buf(iov, 0, buf, bytes);
+        my_buffer = true;
+    } else {
+        buf = iov->iov[0].iov_base;
     }
 
-    qemu_iovec_to_buf(iov, 0, buf, bytes);
-
     if (nfs_pwrite_async(client->context, client->fh,
                          offset, bytes, buf,
                          nfs_co_generic_cb, &task) != 0) {
-        g_free(buf);
+        if (my_buffer) {
+            g_free(buf);
+        }
         return -ENOMEM;
     }
 
@@ -324,7 +331,9 @@ static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
         qemu_coroutine_yield();
     }
 
-    g_free(buf);
+    if (my_buffer) {
+        g_free(buf);
+    }
 
     if (task.ret != bytes) {
         return task.ret < 0 ? task.ret : -EIO;