File Run-fstat-asynchronously-inside-coroutin.patch of Package qemu.37352

From: Dario Faggioli <dfaggioli@suse.com>
Date: Thu, 1 Jun 2023 16:33:34 +0200
Subject: Run fstat asynchronously inside coroutines

Git-commit: Not yet
References: bsc#1211000

Signed-off-by: Joao Silva <joao.silva@suse.com
Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
---
 block/file-posix.c      | 44 +++++++++++++++++++++++++++++++++++------
 include/block/raw-aio.h |  4 +++-
 2 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 3f25264ad629b50f512b8960f300..85ae2ebb22690c7f16a0394379b7 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -209,6 +209,9 @@ typedef struct RawPosixAIOData {
             PreallocMode prealloc;
             Error **errp;
         } truncate;
+        struct {
+            struct stat *st;
+        } fstat;
     };
 } RawPosixAIOData;
 
@@ -1984,6 +1987,19 @@ out:
     return result;
 }
 
+static int handle_aiocb_fstat(void *opaque)
+{
+    RawPosixAIOData *aiocb = opaque;
+    int ret;
+
+    ret = fstat(aiocb->aio_fildes, aiocb->fstat.st);
+    if (ret == -1) {
+        return -errno;
+    }
+
+    return 0;
+}
+
 static int coroutine_fn raw_thread_pool_submit(BlockDriverState *bs,
                                                ThreadPoolFunc func, void *arg)
 {
@@ -2150,6 +2166,23 @@ static void raw_close(BlockDriverState *bs)
     }
 }
 
+static int coroutine_fn raw_co_fstat(BlockDriverState *bs, struct stat *st)
+{
+    BDRVRawState *s = bs->opaque;
+    RawPosixAIOData acb;
+
+    acb = (RawPosixAIOData) {
+        .bs             = bs,
+        .aio_fildes     = s->fd,
+        .aio_type       = QEMU_AIO_FSTAT,
+        .fstat          = {
+            st
+        },
+    };
+
+    return raw_thread_pool_submit(bs, handle_aiocb_fstat, &acb);
+}
+
 /**
  * Truncates the given regular file @fd to @offset and, when growing, fills the
  * new space according to @prealloc.
@@ -2182,10 +2215,9 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
 {
     BDRVRawState *s = bs->opaque;
     struct stat st;
-    int ret;
+    int ret = raw_co_fstat(bs, &st);
 
-    if (fstat(s->fd, &st)) {
-        ret = -errno;
+    if (ret) {
         error_setg_errno(errp, -ret, "Failed to fstat() the file");
         return ret;
     }
@@ -2391,10 +2423,10 @@ static int64_t raw_getlength(BlockDriverState *bs)
 static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
 {
     struct stat st;
-    BDRVRawState *s = bs->opaque;
+    int ret = raw_co_fstat(bs, &st);
 
-    if (fstat(s->fd, &st) < 0) {
-        return -errno;
+    if (ret) {
+        return ret;
     }
     return (int64_t)st.st_blocks * 512;
 }
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
index 251b10d273326b6478e5f6622694..742efff53e44a612d3a8b31c60da 100644
--- a/include/block/raw-aio.h
+++ b/include/block/raw-aio.h
@@ -29,6 +29,7 @@
 #define QEMU_AIO_WRITE_ZEROES 0x0020
 #define QEMU_AIO_COPY_RANGE   0x0040
 #define QEMU_AIO_TRUNCATE     0x0080
+#define QEMU_AIO_FSTAT        0x0100
 #define QEMU_AIO_TYPE_MASK \
         (QEMU_AIO_READ | \
          QEMU_AIO_WRITE | \
@@ -37,7 +38,8 @@
          QEMU_AIO_DISCARD | \
          QEMU_AIO_WRITE_ZEROES | \
          QEMU_AIO_COPY_RANGE | \
-         QEMU_AIO_TRUNCATE)
+         QEMU_AIO_TRUNCATE | \
+         QEMU_AIO_FSTAT)
 
 /* AIO flags */
 #define QEMU_AIO_MISALIGNED   0x1000
openSUSE Build Service is sponsored by