[gnome-disk-utility] Pre-allocate disk image file, if possible



commit b3a0a51763da00ff1aaa8cb9be4d812be7c44665
Author: David Zeuthen <zeuthen gmail com>
Date:   Mon Dec 17 12:21:25 2012 -0500

    Pre-allocate disk image file, if possible
    
    ... using posix_fallocate(3). This hint helps the filesystem lay out
    the blocks for the disk image in a contiguous way, if possible. See
    http://lwn.net/Articles/226710/ for more information about this.
    
    Signed-off-by: David Zeuthen <zeuthen gmail com>

 src/disks/gducreatediskimagedialog.c |   39 +++++++++++++++++++++++++++++++++-
 1 files changed, 38 insertions(+), 1 deletions(-)
---
diff --git a/src/disks/gducreatediskimagedialog.c b/src/disks/gducreatediskimagedialog.c
index dd8eab2..c7d2baa 100644
--- a/src/disks/gducreatediskimagedialog.c
+++ b/src/disks/gducreatediskimagedialog.c
@@ -12,6 +12,7 @@
 #include <glib/gi18n.h>
 #include <gio/gunixfdlist.h>
 #include <gio/gunixinputstream.h>
+#include <gio/gfiledescriptorbased.h>
 
 #include <glib-unix.h>
 #include <sys/ioctl.h>
@@ -71,6 +72,7 @@ typedef struct
   GMutex copy_lock;
   GduEstimator *estimator;
 
+  gboolean allocating_file;
   gboolean retrieving_dvd_keys;
   guint64 num_error_bytes;
   gint64 start_time_usec;
@@ -313,7 +315,11 @@ update_job (DialogData *data,
   data->update_id = 0;
   g_mutex_unlock (&data->copy_lock);
 
-  if (data->retrieving_dvd_keys)
+  if (data->allocating_file)
+    {
+      extra_markup = g_strdup (_("Allocating Disk Image"));
+    }
+  else if (data->retrieving_dvd_keys)
     {
       extra_markup = g_strdup (_("Retrieving DVD keys"));
     }
@@ -642,6 +648,37 @@ copy_thread_func (gpointer user_data)
       goto out;
     }
 
+  /* Allocate space at once to ensure blocks are laid out contigously,
+   * see http://lwn.net/Articles/226710/
+   */
+  if (G_IS_FILE_DESCRIPTOR_BASED (data->output_file_stream))
+    {
+      gint output_fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (data->output_file_stream));
+      gint rc;
+
+      /* With some filesystems drivers - for example ntfs-3g - posix_fallocate(3) may take a
+       * loong time since it may be implemented as writing zeroes to the file.
+       */
+      g_mutex_lock (&data->copy_lock);
+      data->allocating_file = TRUE;
+      g_mutex_unlock (&data->copy_lock);
+      g_idle_add (on_update_job, dialog_data_ref (data));
+
+      rc = posix_fallocate (output_fd, (off_t) 0, (off_t) block_device_size);
+
+      g_mutex_lock (&data->copy_lock);
+      data->allocating_file = FALSE;
+      g_mutex_unlock (&data->copy_lock);
+      g_idle_add (on_update_job, dialog_data_ref (data));
+
+      if (rc != 0)
+        {
+          error = g_error_new (G_IO_ERROR, g_io_error_from_errno (rc), "%s", strerror (rc));
+          g_prefix_error (&error, _("Error allocating space for disk image file: "));
+          goto out;
+        }
+    }
+
   page_size = sysconf (_SC_PAGESIZE);
   buffer_unaligned = g_new0 (guchar, buffer_size + page_size);
   buffer = (guchar*) (((gintptr) (buffer_unaligned + page_size)) & (~(page_size - 1)));



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