Commit d96d3022 authored by David Zeuthen's avatar David Zeuthen
Browse files

Use fallocate(2) rather than posix_fallocate(3)



The latter simulates fallocate(2) if the underlying FS doesn't support
it. This is unwanted and slow, especially on e.g. CIFS or NFS.
Signed-off-by: default avatarDavid Zeuthen <zeuthen@gmail.com>
parent 9a66247b
......@@ -77,6 +77,26 @@ CC_CHECK_CFLAGS_APPEND([ \
-fno-strict-aliasing \
])
AC_MSG_CHECKING([for valid fallocate() function])
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
#include <unistd.h>
#include <sys/types.h>
#include <linux/falloc.h>
#include <fcntl.h>
]],[[
long ret;
ret = fallocate(0, FALLOC_FL_KEEP_SIZE, 0xfffffffful, 0xfffffffful);
if (ret != 0) {
return 1;
}
]])],[
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_FALLOCATE,1,[Have valid fallocate() function])],[
AC_MSG_RESULT([no])])
# ***************************
# Check for required packages
# ***************************
......
......@@ -9,6 +9,9 @@
#include "config.h"
#define _GNU_SOURCE
#include <fcntl.h>
#include <glib/gi18n.h>
#include <gio/gunixfdlist.h>
#include <gio/gunixinputstream.h>
......@@ -727,36 +730,47 @@ 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 supported, allocate space at once to ensure blocks are laid
* out contigously, see http://lwn.net/Articles/226710/
*/
#ifdef HAVE_FALLOCATE
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);
rc = fallocate (output_fd,
0, /* mode */
(off_t) 0,
(off_t) block_device_size);
if (rc != 0)
{
if (errno == ENOSYS || errno == EOPNOTSUPP)
{
/* If the kernel or filesystem does not support it, too
* bad. Just continue.
*/
}
else
{
error = g_error_new (G_IO_ERROR, g_io_error_from_errno (errno), "%s", strerror (errno));
g_prefix_error (&error, _("Error allocating space for disk image file: "));
goto out;
}
}
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;
}
}
#endif
page_size = sysconf (_SC_PAGESIZE);
buffer_unaligned = g_new0 (guchar, buffer_size + page_size);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment