[libvirt] [PATCH 2/2] Use posix_fallocate() to allocate disk space on supported systems

Amit Shah amit.shah at redhat.com
Thu Mar 19 07:15:25 UTC 2009


Make use of the safezero() function to allocate disk space instead
of safewrite() to write zeros. The safezero() function will use
posix_fallocate() on supported systems.

If progress activity is not requested (current behaviour), the new
safezero() function will allocate the file in one go.

If progress activity is requested, allocate in 512MiB chunks.

Signed-off-by: Amit Shah <amit.shah at redhat.com>
---
 src/storage_backend_fs.c |   44 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c
index c0b130e..f0cbcc3 100644
--- a/src/storage_backend_fs.c
+++ b/src/storage_backend_fs.c
@@ -62,6 +62,8 @@ static int qcowXGetBackingStore(virConnectPtr, char **,
 static int vmdk4GetBackingStore(virConnectPtr, char **,
                                 const unsigned char *, size_t);
 
+static int track_allocation_progress = 0;
+
 /* Either 'magic' or 'extension' *must* be provided */
 struct FileTypeInfo {
     int type;           /* One of the constants above */
@@ -1016,24 +1018,44 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
         }
 
         /* Pre-allocate any data if requested */
-        /* XXX slooooooooooooooooow.
-         * Need to add in progress bars & bg thread somehow */
+        /* XXX slooooooooooooooooow on non-extents-based file systems */
+        /* FIXME: Add in progress bars & bg thread if progress bar requested */
         if (vol->allocation) {
-            unsigned long long remain = vol->allocation;
-            static char const zeros[4096];
-            while (remain) {
-                int bytes = sizeof(zeros);
-                if (bytes > remain)
-                    bytes = remain;
-                if ((bytes = safewrite(fd, zeros, bytes)) < 0) {
-                    virReportSystemError(conn, errno,
+            if (track_allocation_progress) {
+                unsigned long long remain = vol->allocation;
+
+                while (remain) {
+                    /* Allocate in chunks of 512MB: big-enough chunk
+                     * size and takes approx. 9s on ext3. A progress
+                     * update every 9s is a fair-enough trade-off
+                     */
+                    unsigned long long bytes = 512 * 1024 * 1024;
+                    int r;
+
+                    if (bytes > remain)
+                        bytes = remain;
+                    if ((r = safezero(fd, 0, vol->allocation - remain,
+                                      bytes)) != 0) {
+                        virReportSystemError(conn, r,
+                                             _("cannot fill file '%s'"),
+                                             vol->target.path);
+                        unlink(vol->target.path);
+                        close(fd);
+                        return -1;
+                    }
+                    remain -= bytes;
+                }
+            } else { /* No progress bars to be shown */
+                int r;
+
+                if ((r = safezero(fd, 0, 0, vol->allocation)) != 0) {
+                    virReportSystemError(conn, r,
                                          _("cannot fill file '%s'"),
                                          vol->target.path);
                     unlink(vol->target.path);
                     close(fd);
                     return -1;
                 }
-                remain -= bytes;
             }
         }
 
-- 
1.6.0.6




More information about the libvir-list mailing list