qemu-img: Do not truncate before preallocation
PATCH 1/1 qemu-img: Do not truncate before preallocation
From: Nir Soffer <[email protected]>
When using file system that does not support fallocate(), posix_fallocate() fallback to emulation mode. In this mode, when preallocating blocks before file end, posix_preallocate is calling one pread() and one pwrite() per block. But when preallocation blocks after file end, it calls only one pwrite per block.
Truncating the file only when preallocation=OFF speeds up creating raw file in this situation.
Here are example run with without and with this change, tested on Fedora 25 VM, creating a raw image on NFS version 3 mount over 1G nic:
$ time ./qemu-img create -f raw -o preallocation=falloc mnt/test 1g Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
real 0m17.083s
user 0m0.020s
sys 0m0.404s
$ rm mnt/test $ time ./qemu-img create -f raw -o preallocation=falloc mnt/test 1g Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
real 0m12.372s
user 0m0.020s
sys 0m0.376s
$ strace ./qemu-img-up create -f raw -o preallocation=falloc mnt/test 8192 ... pread64(9, "\0", 1, 4095) = 1 pwrite64(9, "\0", 1, 4095) = 1 pread64(9, "\0", 1, 8191) = 1 pwrite64(9, "\0", 1, 8191) = 1
$ strace ./qemu-img-fix create -f raw -o preallocation=falloc mnt/test 8192 ... pwrite64(9, "\0", 1, 4095) = 1 pwrite64(9, "\0", 1, 8191) = 1
Signed-off-by Nir Soffer <[email protected]>
--- block/file-posix.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
block/file-posix.c +4 -7
@@ -1588,12 +1588,6 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)#endif } -if (ftruncate (fd, total_size) !=0 ) { - result = -errno; -error_setg_errno (errp, -result,"Could not resize file" ); - goto out_close; - } -switch (prealloc) {#ifdef CONFIG_POSIX_FALLOCATE case PREALLOC_MODE_FALLOC :
@@ -1633,6 +1627,10 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)break ; }case PREALLOC_MODE_OFF : +if (ftruncate (fd, total_size) !=0 ) { + result = -errno; +error_setg_errno (errp, -result,"Could not resize file" ); + }break ;default : result = -EINVAL ;
@@ -1641,7 +1639,6 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)break ; } -out_close:if (qemu_close (fd) !=0 && result ==0 ) { result = -errno;error_setg_errno (errp, -result,"Could not close the new file" );
Signature · 1 line
2.9.3