All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation
@ 2017-02-03 19:50 Nir Soffer
  2017-02-16 17:38 ` Nir Soffer
  2017-02-16 17:52 ` Kevin Wolf
  0 siblings, 2 replies; 6+ messages in thread
From: Nir Soffer @ 2017-02-03 19:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, qemu-block, Nir Soffer

When using file system that does not support fallocate() (e.g. NFS <
4.2), truncating the file only when preallocation=OFF speeds up creating
raw file.

Here is example run, tested on Fedora 24 machine, creating raw file on
NFS version 3 server.

$ time ./qemu-img-master create -f raw -o preallocation=falloc mnt/test 1g
Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc

real	0m21.185s
user	0m0.022s
sys	0m0.574s

$ time ./qemu-img-fix create -f raw -o preallocation=falloc mnt/test 1g
Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc

real	0m11.601s
user	0m0.016s
sys	0m0.525s

$ time dd if=/dev/zero of=mnt/test bs=1M count=1024 oflag=direct
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 15.6627 s, 68.6 MB/s

real	0m16.104s
user	0m0.009s
sys	0m0.220s

Running with strace we can see that without this change we do one
pread() and one pwrite() for each block. With this change, we do only
one pwrite() per block.

$ strace ./qemu-img-master 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

This happens because posix_fallocate is checking if each block is
allocated before writing a byte to the block, and when truncating the
file before preallocation, all blocks are unallocated.

Signed-off-by: Nir Soffer <nirsof@gmail.com>
---

I sent this a week ago:
http://lists.nongnu.org/archive/html/qemu-devel/2017-01/msg06123.html

Sending again with improved commit message.

 block/file-posix.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 2134e0e..442f080 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1591,12 +1591,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:
@@ -1636,6 +1630,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;
@@ -1644,7 +1642,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");
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation
  2017-02-03 19:50 [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation Nir Soffer
@ 2017-02-16 17:38 ` Nir Soffer
  2017-02-16 17:52 ` Kevin Wolf
  1 sibling, 0 replies; 6+ messages in thread
From: Nir Soffer @ 2017-02-16 17:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, qemu-block, Nir Soffer

Ping

On Fri, Feb 3, 2017 at 9:50 PM, Nir Soffer <nirsof@gmail.com> wrote:
> When using file system that does not support fallocate() (e.g. NFS <
> 4.2), truncating the file only when preallocation=OFF speeds up creating
> raw file.
>
> Here is example run, tested on Fedora 24 machine, creating raw file on
> NFS version 3 server.
>
> $ time ./qemu-img-master create -f raw -o preallocation=falloc mnt/test 1g
> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
>
> real    0m21.185s
> user    0m0.022s
> sys     0m0.574s
>
> $ time ./qemu-img-fix create -f raw -o preallocation=falloc mnt/test 1g
> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
>
> real    0m11.601s
> user    0m0.016s
> sys     0m0.525s
>
> $ time dd if=/dev/zero of=mnt/test bs=1M count=1024 oflag=direct
> 1024+0 records in
> 1024+0 records out
> 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 15.6627 s, 68.6 MB/s
>
> real    0m16.104s
> user    0m0.009s
> sys     0m0.220s
>
> Running with strace we can see that without this change we do one
> pread() and one pwrite() for each block. With this change, we do only
> one pwrite() per block.
>
> $ strace ./qemu-img-master 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
>
> This happens because posix_fallocate is checking if each block is
> allocated before writing a byte to the block, and when truncating the
> file before preallocation, all blocks are unallocated.
>
> Signed-off-by: Nir Soffer <nirsof@gmail.com>
> ---
>
> I sent this a week ago:
> http://lists.nongnu.org/archive/html/qemu-devel/2017-01/msg06123.html
>
> Sending again with improved commit message.
>
>  block/file-posix.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 2134e0e..442f080 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1591,12 +1591,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:
> @@ -1636,6 +1630,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;
> @@ -1644,7 +1642,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");
> --
> 2.9.3
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation
  2017-02-03 19:50 [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation Nir Soffer
  2017-02-16 17:38 ` Nir Soffer
@ 2017-02-16 17:52 ` Kevin Wolf
  2017-02-16 18:23   ` Nir Soffer
  1 sibling, 1 reply; 6+ messages in thread
From: Kevin Wolf @ 2017-02-16 17:52 UTC (permalink / raw)
  To: Nir Soffer; +Cc: qemu-devel, qemu-block

Am 03.02.2017 um 20:50 hat Nir Soffer geschrieben:
> When using file system that does not support fallocate() (e.g. NFS <
> 4.2), truncating the file only when preallocation=OFF speeds up creating
> raw file.
> 
> Here is example run, tested on Fedora 24 machine, creating raw file on
> NFS version 3 server.
> 
> $ time ./qemu-img-master create -f raw -o preallocation=falloc mnt/test 1g
> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
> 
> real	0m21.185s
> user	0m0.022s
> sys	0m0.574s
> 
> $ time ./qemu-img-fix create -f raw -o preallocation=falloc mnt/test 1g
> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
> 
> real	0m11.601s
> user	0m0.016s
> sys	0m0.525s
> 
> $ time dd if=/dev/zero of=mnt/test bs=1M count=1024 oflag=direct
> 1024+0 records in
> 1024+0 records out
> 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 15.6627 s, 68.6 MB/s
> 
> real	0m16.104s
> user	0m0.009s
> sys	0m0.220s
> 
> Running with strace we can see that without this change we do one
> pread() and one pwrite() for each block. With this change, we do only
> one pwrite() per block.
> 
> $ strace ./qemu-img-master 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
> 
> This happens because posix_fallocate is checking if each block is
> allocated before writing a byte to the block, and when truncating the
> file before preallocation, all blocks are unallocated.
> 
> Signed-off-by: Nir Soffer <nirsof@gmail.com>

Thanks, applied to the block branch.

I'm not completely sure if doing an ftruncate() first couldn't improve
PREALLOC_MODE_FULL somewhat in some cases, but I agree that the patch
should still result in correct images.

KEvin

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation
  2017-02-16 17:52 ` Kevin Wolf
@ 2017-02-16 18:23   ` Nir Soffer
  2017-02-16 18:36     ` Kevin Wolf
  0 siblings, 1 reply; 6+ messages in thread
From: Nir Soffer @ 2017-02-16 18:23 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, qemu-block

On Thu, Feb 16, 2017 at 7:52 PM, Kevin Wolf <kwolf@redhat.com> wrote:
> Am 03.02.2017 um 20:50 hat Nir Soffer geschrieben:
>> When using file system that does not support fallocate() (e.g. NFS <
>> 4.2), truncating the file only when preallocation=OFF speeds up creating
>> raw file.
>>
>> Here is example run, tested on Fedora 24 machine, creating raw file on
>> NFS version 3 server.
>>
>> $ time ./qemu-img-master create -f raw -o preallocation=falloc mnt/test 1g
>> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
>>
>> real  0m21.185s
>> user  0m0.022s
>> sys   0m0.574s
>>
>> $ time ./qemu-img-fix create -f raw -o preallocation=falloc mnt/test 1g
>> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
>>
>> real  0m11.601s
>> user  0m0.016s
>> sys   0m0.525s
>>
>> $ time dd if=/dev/zero of=mnt/test bs=1M count=1024 oflag=direct
>> 1024+0 records in
>> 1024+0 records out
>> 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 15.6627 s, 68.6 MB/s
>>
>> real  0m16.104s
>> user  0m0.009s
>> sys   0m0.220s
>>
>> Running with strace we can see that without this change we do one
>> pread() and one pwrite() for each block. With this change, we do only
>> one pwrite() per block.
>>
>> $ strace ./qemu-img-master 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
>>
>> This happens because posix_fallocate is checking if each block is
>> allocated before writing a byte to the block, and when truncating the
>> file before preallocation, all blocks are unallocated.
>>
>> Signed-off-by: Nir Soffer <nirsof@gmail.com>
>
> Thanks, applied to the block branch.
>
> I'm not completely sure if doing an ftruncate() first couldn't improve
> PREALLOC_MODE_FULL somewhat in some cases, but I agree that the patch
> should still result in correct images.

Good point, I'll do some tests with full mode to check this.

Do you know which cases can benefit from ftruncate() before full preallocation?

Nir

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation
  2017-02-16 18:23   ` Nir Soffer
@ 2017-02-16 18:36     ` Kevin Wolf
  0 siblings, 0 replies; 6+ messages in thread
From: Kevin Wolf @ 2017-02-16 18:36 UTC (permalink / raw)
  To: Nir Soffer; +Cc: qemu-devel, qemu-block

Am 16.02.2017 um 19:23 hat Nir Soffer geschrieben:
> On Thu, Feb 16, 2017 at 7:52 PM, Kevin Wolf <kwolf@redhat.com> wrote:
> > Am 03.02.2017 um 20:50 hat Nir Soffer geschrieben:
> >> When using file system that does not support fallocate() (e.g. NFS <
> >> 4.2), truncating the file only when preallocation=OFF speeds up creating
> >> raw file.
> >>
> >> Here is example run, tested on Fedora 24 machine, creating raw file on
> >> NFS version 3 server.
> >>
> >> $ time ./qemu-img-master create -f raw -o preallocation=falloc mnt/test 1g
> >> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
> >>
> >> real  0m21.185s
> >> user  0m0.022s
> >> sys   0m0.574s
> >>
> >> $ time ./qemu-img-fix create -f raw -o preallocation=falloc mnt/test 1g
> >> Formatting 'mnt/test', fmt=raw size=1073741824 preallocation=falloc
> >>
> >> real  0m11.601s
> >> user  0m0.016s
> >> sys   0m0.525s
> >>
> >> $ time dd if=/dev/zero of=mnt/test bs=1M count=1024 oflag=direct
> >> 1024+0 records in
> >> 1024+0 records out
> >> 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 15.6627 s, 68.6 MB/s
> >>
> >> real  0m16.104s
> >> user  0m0.009s
> >> sys   0m0.220s
> >>
> >> Running with strace we can see that without this change we do one
> >> pread() and one pwrite() for each block. With this change, we do only
> >> one pwrite() per block.
> >>
> >> $ strace ./qemu-img-master 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
> >>
> >> This happens because posix_fallocate is checking if each block is
> >> allocated before writing a byte to the block, and when truncating the
> >> file before preallocation, all blocks are unallocated.
> >>
> >> Signed-off-by: Nir Soffer <nirsof@gmail.com>
> >
> > Thanks, applied to the block branch.
> >
> > I'm not completely sure if doing an ftruncate() first couldn't improve
> > PREALLOC_MODE_FULL somewhat in some cases, but I agree that the patch
> > should still result in correct images.
> 
> Good point, I'll do some tests with full mode to check this.
> 
> Do you know which cases can benefit from ftruncate() before full preallocation?

Knowing the final size from the beginning could allow the file system
driver to do less allocations and possibly avoid fragmentation of the
file. I'm not sure if that's easily measurable, though.

I'd also expect that with XFS, you'll see no or less preallocation.
'du' often shows values much larger than the actual image size on XFS
because the file was growing a lot, so without having the actual size,
XFS takes a guess and does some generous preallocation.

Kevin

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation
@ 2017-01-27 23:45 Nir Soffer
  0 siblings, 0 replies; 6+ messages in thread
From: Nir Soffer @ 2017-01-27 23:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Nir Soffer, Nir Soffer

From: Nir Soffer <nsoffer@redhat.com>

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 <nirsof@gmail.com>
---
 block/file-posix.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 28b47d9..d7f6129 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -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");
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-02-16 18:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-03 19:50 [Qemu-devel] [PATCH] qemu-img: Do not truncate before preallocation Nir Soffer
2017-02-16 17:38 ` Nir Soffer
2017-02-16 17:52 ` Kevin Wolf
2017-02-16 18:23   ` Nir Soffer
2017-02-16 18:36     ` Kevin Wolf
  -- strict thread matches above, loose matches on Subject: below --
2017-01-27 23:45 Nir Soffer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.