提交 c29d0929 编写于 作者: D Daniel Veillard

use posix_fallocate() to allocate diskspace faster

* src/libvirt_private.syms src/storage_backend_fs.c src/util.c
  src/util.h: use posix_fallocate() on supported systems to
  allocate diskspace faster, patches by Amit Shah
Daniel
上级 92d313eb
......@@ -65,6 +65,7 @@ Patches have also been contributed by:
Maximilian Wilhelm <max@rfc2324.org>
Ryota Ozaki <ozaki.ryota@gmail.com>
Pritesh Kothari <Pritesh.Kothari@Sun.COM>
Amit Shah <amit.shah@redhat.com>
[....send patches to get your name here....]
......
Fri Mar 20 13:16:01 CET 2009 Daniel Veillard <veillard@redhat.com>
* src/libvirt_private.syms src/storage_backend_fs.c src/util.c
src/util.h: use posix_fallocate() on supported systems to
allocate diskspace faster, patches by Amit Shah
Fri Mar 20 11:41:40 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Fix test breakage on x86_64 from previous change
......
......@@ -72,7 +72,7 @@ dnl Use --disable-largefile if you don't want this.
AC_SYS_LARGEFILE
dnl Availability of various common functions (non-fatal if missing).
AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid])
AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid posix_fallocate mmap])
dnl Availability of various not common threadsafe functions
AC_CHECK_FUNCS([strerror_r strtok_r getmntent_r getgrnam_r getpwuid_r])
......
......@@ -308,6 +308,7 @@ virStrToLong_ui;
virFileLinkPointsTo;
saferead;
safewrite;
safezero;
virMacAddrCompare;
virEnumFromString;
virEnumToString;
......
......@@ -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 512MiB: 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;
}
}
......
......@@ -39,6 +39,9 @@
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#if HAVE_MMAP
#include <sys/mman.h>
#endif
#include <string.h>
#include <signal.h>
#if HAVE_TERMIOS_H
......@@ -117,6 +120,71 @@ ssize_t safewrite(int fd, const void *buf, size_t count)
return nwritten;
}
#ifdef HAVE_POSIX_FALLOCATE
int safezero(int fd, int flags, off_t offset, off_t len)
{
return posix_fallocate(fd, offset, len);
}
#else
#ifdef HAVE_MMAP
int safezero(int fd, int flags, off_t offset, off_t len)
{
int r;
char *buf;
/* memset wants the mmap'ed file to be present on disk so create a
* sparse file
*/
r = ftruncate(fd, len);
if (r < 0)
return -errno;
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
if (buf == MAP_FAILED)
return -errno;
memset(buf, 0, len);
munmap(buf, len);
return 0;
}
#else /* HAVE_MMAP */
int safezero(int fd, int flags, off_t offset, off_t len)
{
int r;
char *buf;
unsigned long long remain, bytes;
/* Split up the write in small chunks so as not to allocate lots of RAM */
remain = len;
bytes = 1024 * 1024;
r = VIR_ALLOC_N(buf, bytes);
if (r < 0)
return -ENOMEM;
while (remain) {
if (bytes > remain)
bytes = remain;
r = safewrite(fd, buf, len);
if (r < 0) {
VIR_FREE(buf);
return r;
}
/* safewrite() guarantees all data will be written */
remain -= bytes;
}
VIR_FREE(buf);
return 0;
}
#endif /* HAVE_MMAP */
#endif /* HAVE_POSIX_FALLOCATE */
#ifndef PROXY
int virFileStripSuffix(char *str,
......
......@@ -31,6 +31,7 @@
int saferead(int fd, void *buf, size_t count);
ssize_t safewrite(int fd, const void *buf, size_t count);
int safezero(int fd, int flags, off_t offset, off_t len);
enum {
VIR_EXEC_NONE = 0,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册