qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH v4 3/4] raw-posix: Add full image preallocation


From: Hu Tao
Subject: [Qemu-devel] [RFC PATCH v4 3/4] raw-posix: Add full image preallocation option
Date: Fri, 27 Dec 2013 11:05:53 +0800

This patch adds a new option preallocation for raw format, and implements
full preallocation.

Signed-off-by: Hu Tao <address@hidden>
---
 block/raw-posix.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 6f6b8c1..a722d27 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1160,17 +1160,52 @@ static int64_t 
raw_get_allocated_file_size(BlockDriverState *bs)
     return (int64_t)st.st_blocks * 512;
 }
 
+#ifdef __linux__
+static int raw_preallocate2(int fd, int64_t offset, int64_t length)
+{
+    int ret = -1;
+
+    ret = fallocate(fd, 0, offset, length);
+    if (ret < 0) {
+        ret = -errno;
+    }
+
+    /* fallback to posix_fallocate() if fallocate() is not supported */
+    if (ret == -ENOSYS || ret == -EOPNOTSUPP) {
+        ret = posix_fallocate(fd, offset, length);
+    }
+
+    return ret;
+}
+#else
+static int raw_preallocate2(int fd, int64_t offset, int64_t length)
+{
+    return posix_fallocate(fd, offset, length);
+}
+#endif
+
 static int raw_create(const char *filename, QEMUOptionParameter *options,
                       Error **errp)
 {
     int fd;
     int result = 0;
     int64_t total_size = 0;
+    PreallocMode prealloc = PREALLOC_MODE_OFF;
 
     /* Read out options */
     while (options && options->name) {
         if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
             total_size = options->value.n & BDRV_SECTOR_MASK;
+        } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
+            if (!options->value.s || !strcmp(options->value.s, "off")) {
+                prealloc = PREALLOC_MODE_OFF;
+            } else if (!strcmp(options->value.s, "full")) {
+                prealloc = PREALLOC_MODE_FULL;
+            } else {
+                error_setg(errp, "Invalid preallocation mode: '%s'",
+                           options->value.s);
+                return -EINVAL;
+            }
         }
         options++;
     }
@@ -1185,6 +1220,12 @@ static int raw_create(const char *filename, 
QEMUOptionParameter *options,
             result = -errno;
             error_setg_errno(errp, -result, "Could not resize file");
         }
+        if (prealloc == PREALLOC_MODE_FULL) {
+            result = raw_preallocate2(fd, 0, total_size);
+            if (result != 0)
+                error_setg_errno(errp, -result,
+                                 "Could not preallocate data for the new 
file");
+        }
         if (qemu_close(fd) != 0) {
             result = -errno;
             error_setg_errno(errp, -result, "Could not close the new file");
@@ -1340,6 +1381,11 @@ static QEMUOptionParameter raw_create_options[] = {
         .type = OPT_SIZE,
         .help = "Virtual disk size"
     },
+    {
+        .name = BLOCK_OPT_PREALLOC,
+        .type = OPT_STRING,
+        .help = "Preallocation mode (allowed values: off, full)"
+    },
     { NULL }
 };
 
-- 
1.7.11.7




reply via email to

[Prev in Thread] Current Thread [Next in Thread]