From: "Benoît Canet" <benoit.canet@irqsave.net>
To: Hu Tao <hutao@cn.fujitsu.com>
Cc: Kevin Wolf <kwolf@redhat.com>, Fam Zheng <famz@redhat.com>,
"Richard W.M. Jones" <rjones@redhat.com>,
qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
Yasunori Goto <y-goto@jp.fujitsu.com>
Subject: Re: [Qemu-devel] [PATCH v14 4/5] raw-posix: Add falloc and full preallocation option
Date: Tue, 9 Sep 2014 15:21:49 +0200 [thread overview]
Message-ID: <20140909132148.GD22473@irqsave.net> (raw)
In-Reply-To: <cd51c8c3dcb751020f58c94adfc9c85b19587070.1410232831.git.hutao@cn.fujitsu.com>
The Tuesday 09 Sep 2014 à 11:54:30 (+0800), Hu Tao wrote :
> This patch adds a new option preallocation for raw format, and implements
> falloc and full preallocation.
>
> Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
> Reviewed-by: Max Reitz <mreitz@redhat.com>
> ---
> block/raw-posix.c | 93 +++++++++++++++++++++++++++++++++++++++++++------------
> qemu-doc.texi | 9 ++++++
> qemu-img.texi | 9 ++++++
> 3 files changed, 92 insertions(+), 19 deletions(-)
>
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index 7208c05..27c854c 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -30,6 +30,7 @@
> #include "block/thread-pool.h"
> #include "qemu/iov.h"
> #include "raw-aio.h"
> +#include "qapi/util.h"
>
> #if defined(__APPLE__) && (__MACH__)
> #include <paths.h>
> @@ -1365,6 +1366,9 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
> int result = 0;
> int64_t total_size = 0;
> bool nocow = false;
> + PreallocMode prealloc;
> + char *buf = NULL;
> + Error *local_err = NULL;
>
> strstart(filename, "file:", &filename);
>
> @@ -1372,37 +1376,83 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
> total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
> BDRV_SECTOR_SIZE);
> nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
> + buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
> + prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
> + PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
> + &local_err);
> + g_free(buf);
> + if (local_err) {
> + error_propagate(errp, local_err);
> + result = -EINVAL;
> + goto out;
> + }
>
> fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
> 0644);
> if (fd < 0) {
> result = -errno;
> error_setg_errno(errp, -result, "Could not create file");
> - } else {
> - if (nocow) {
> + goto out;
> + }
> +
> + if (nocow) {
> #ifdef __linux__
> - /* Set NOCOW flag to solve performance issue on fs like btrfs.
> - * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
> - * will be ignored since any failure of this operation should not
> - * block the left work.
> - */
> - int attr;
> - if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
> - attr |= FS_NOCOW_FL;
> - ioctl(fd, FS_IOC_SETFLAGS, &attr);
> - }
> -#endif
> + /* Set NOCOW flag to solve performance issue on fs like btrfs.
> + * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
> + * will be ignored since any failure of this operation should not
> + * block the left work.
> + */
> + int attr;
> + if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
> + attr |= FS_NOCOW_FL;
> + ioctl(fd, FS_IOC_SETFLAGS, &attr);
> }
> +#endif
> + }
>
> - if (ftruncate(fd, total_size) != 0) {
> - result = -errno;
> - error_setg_errno(errp, -result, "Could not resize file");
> + if (ftruncate(fd, total_size) != 0) {
> + result = -errno;
> + error_setg_errno(errp, -result, "Could not resize file");
> + goto out_close;
> + }
> +
> + if (prealloc == PREALLOC_MODE_FALLOC) {
> + /* posix_fallocate() doesn't set errno. */
> + result = -posix_fallocate(fd, 0, total_size);
> + if (result != 0) {
> + error_setg_errno(errp, -result,
> + "Could not preallocate data for the new file");
Here you choose not to goto out_close but let the code flow lead to it.
> }
> - if (qemu_close(fd) != 0) {
> - result = -errno;
> - error_setg_errno(errp, -result, "Could not close the new file");
> + } else if (prealloc == PREALLOC_MODE_FULL) {
> + buf = g_malloc0(65536);
> + int64_t num = 0, left = total_size;
> +
> + while (left > 0) {
> + num = MIN(left, 65536);
> + result = write(fd, buf, num);
> + if (result < 0) {
> + result = -errno;
> + error_setg_errno(errp, -result,
> + "Could not write to the new file");
> + g_free(buf);
> + goto out_close;
As a consequence you could replace the two previous line by:
+ break;
The while loop would gently exit left would be decremented and fsync would
be done but we don't care these sides effects and buf would be freed.
Then the code would exit the if branch and reach out_close.
(I heard some people don't like exiting a loop with a goto).
> + }
> + left -= num;
> }
> + fsync(fd);
> + g_free(buf);
> + } else if (prealloc != PREALLOC_MODE_OFF) {
> + result = -EINVAL;
> + error_setg(errp, "Unsupported preallocation mode: %s",
> + PreallocMode_lookup[prealloc]);
> }
> +
> +out_close:
> + if (qemu_close(fd) != 0 && result == 0) {
> + result = -errno;
> + error_setg_errno(errp, -result, "Could not close the new file");
> + }
> +out:
> return result;
> }
>
> @@ -1585,6 +1635,11 @@ static QemuOptsList raw_create_opts = {
> .type = QEMU_OPT_BOOL,
> .help = "Turn off copy-on-write (valid only on btrfs)"
> },
> + {
> + .name = BLOCK_OPT_PREALLOC,
> + .type = QEMU_OPT_STRING,
> + .help = "Preallocation mode (allowed values: off, falloc, full)"
> + },
> { /* end of list */ }
> }
> };
> diff --git a/qemu-doc.texi b/qemu-doc.texi
> index 2b232ae..1f289d6 100644
> --- a/qemu-doc.texi
> +++ b/qemu-doc.texi
> @@ -527,6 +527,15 @@ Linux or NTFS on Windows), then only the written sectors will reserve
> space. Use @code{qemu-img info} to know the real size used by the
> image or @code{ls -ls} on Unix/Linux.
>
> +Supported options:
> +@table @code
> +@item preallocation
> +Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
> +@code{falloc} mode preallocates space for image by calling posix_fallocate().
> +@code{full} mode preallocates space for image by writing zeros to underlying
> +storage.
> +@end table
> +
> @item qcow2
> QEMU image format, the most versatile format. Use it to have smaller
> images (useful if your filesystem does not supports holes, for example
> diff --git a/qemu-img.texi b/qemu-img.texi
> index cc4668e..d64d05e 100644
> --- a/qemu-img.texi
> +++ b/qemu-img.texi
> @@ -419,6 +419,15 @@ Linux or NTFS on Windows), then only the written sectors will reserve
> space. Use @code{qemu-img info} to know the real size used by the
> image or @code{ls -ls} on Unix/Linux.
>
> +Supported options:
> +@table @code
> +@item preallocation
> +Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
> +@code{falloc} mode preallocates space for image by calling posix_fallocate().
> +@code{full} mode preallocates space for image by writing zeros to underlying
> +storage.
> +@end table
> +
> @item qcow2
> QEMU image format, the most versatile format. Use it to have smaller
> images (useful if your filesystem does not supports holes, for example
> --
> 1.9.3
>
>
next prev parent reply other threads:[~2014-09-09 13:22 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-09 3:54 [Qemu-devel] [PATCH v14 0/5] qcow2, raw: add preallocation=full and preallocation=falloc Hu Tao
2014-09-09 3:54 ` [Qemu-devel] [PATCH v14 1/5] block: round up file size to nearest sector Hu Tao
2014-09-09 12:12 ` Benoît Canet
2014-09-10 1:50 ` Hu Tao
2014-09-10 2:36 ` Hu Tao
2014-09-09 3:54 ` [Qemu-devel] [PATCH v14 2/5] block: don't convert file size to sector size Hu Tao
2014-09-09 12:26 ` Benoît Canet
2014-09-09 3:54 ` [Qemu-devel] [PATCH v14 3/5] qapi: introduce PreallocMode and new PreallocModes full and falloc Hu Tao
2014-09-09 12:42 ` Eric Blake
2014-09-10 1:44 ` Hu Tao
2014-09-09 12:45 ` Benoît Canet
2014-09-10 1:41 ` Hu Tao
2014-09-09 3:54 ` [Qemu-devel] [PATCH v14 4/5] raw-posix: Add falloc and full preallocation option Hu Tao
2014-09-09 13:21 ` Benoît Canet [this message]
2014-09-10 2:02 ` Hu Tao
2014-09-09 3:54 ` [Qemu-devel] [PATCH v14 5/5] qcow2: " Hu Tao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140909132148.GD22473@irqsave.net \
--to=benoit.canet@irqsave.net \
--cc=famz@redhat.com \
--cc=hutao@cn.fujitsu.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rjones@redhat.com \
--cc=stefanha@redhat.com \
--cc=y-goto@jp.fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).