From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39710) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XRLNh-0000fz-7u for qemu-devel@nongnu.org; Tue, 09 Sep 2014 09:22:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XRLNa-00083e-Q3 for qemu-devel@nongnu.org; Tue, 09 Sep 2014 09:22:49 -0400 Received: from lputeaux-656-01-25-125.w80-12.abo.wanadoo.fr ([80.12.84.125]:53050 helo=paradis.irqsave.net) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XRLNa-00082S-GZ for qemu-devel@nongnu.org; Tue, 09 Sep 2014 09:22:42 -0400 Date: Tue, 9 Sep 2014 15:21:49 +0200 From: =?iso-8859-1?Q?Beno=EEt?= Canet Message-ID: <20140909132148.GD22473@irqsave.net> References: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v14 4/5] raw-posix: Add falloc and full preallocation option List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Hu Tao Cc: Kevin Wolf , Fam Zheng , "Richard W.M. Jones" , qemu-devel@nongnu.org, Max Reitz , Stefan Hajnoczi , Yasunori Goto The Tuesday 09 Sep 2014 =E0 11:54:30 (+0800), Hu Tao wrote : > This patch adds a new option preallocation for raw format, and implemen= ts > falloc and full preallocation. >=20 > Signed-off-by: Hu Tao > Reviewed-by: Max Reitz > --- > block/raw-posix.c | 93 +++++++++++++++++++++++++++++++++++++++++++----= -------- > qemu-doc.texi | 9 ++++++ > qemu-img.texi | 9 ++++++ > 3 files changed, 92 insertions(+), 19 deletions(-) >=20 > 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" > =20 > #if defined(__APPLE__) && (__MACH__) > #include > @@ -1365,6 +1366,9 @@ static int raw_create(const char *filename, QemuO= pts *opts, Error **errp) > int result =3D 0; > int64_t total_size =3D 0; > bool nocow =3D false; > + PreallocMode prealloc; > + char *buf =3D NULL; > + Error *local_err =3D NULL; > =20 > strstart(filename, "file:", &filename); > =20 > @@ -1372,37 +1376,83 @@ static int raw_create(const char *filename, Qem= uOpts *opts, Error **errp) > total_size =3D ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE= , 0), > BDRV_SECTOR_SIZE); > nocow =3D qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); > + buf =3D qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); > + prealloc =3D 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 =3D -EINVAL; > + goto out; > + } > =20 > fd =3D qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY= , > 0644); > if (fd < 0) { > result =3D -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 bt= rfs. > - * This is an optimisation. The FS_IOC_SETFLAGS ioctl retu= rn value > - * will be ignored since any failure of this operation sho= uld not > - * block the left work. > - */ > - int attr; > - if (ioctl(fd, FS_IOC_GETFLAGS, &attr) =3D=3D 0) { > - attr |=3D 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 v= alue > + * will be ignored since any failure of this operation should = not > + * block the left work. > + */ > + int attr; > + if (ioctl(fd, FS_IOC_GETFLAGS, &attr) =3D=3D 0) { > + attr |=3D FS_NOCOW_FL; > + ioctl(fd, FS_IOC_SETFLAGS, &attr); > } > +#endif > + } > =20 > - if (ftruncate(fd, total_size) !=3D 0) { > - result =3D -errno; > - error_setg_errno(errp, -result, "Could not resize file"); > + if (ftruncate(fd, total_size) !=3D 0) { > + result =3D -errno; > + error_setg_errno(errp, -result, "Could not resize file"); > + goto out_close; > + } > + > + if (prealloc =3D=3D PREALLOC_MODE_FALLOC) { > + /* posix_fallocate() doesn't set errno. */ > + result =3D -posix_fallocate(fd, 0, total_size); > + if (result !=3D 0) { > + error_setg_errno(errp, -result, > + "Could not preallocate data for the new f= ile"); Here you choose not to goto out_close but let the code flow lead to it. > } > - if (qemu_close(fd) !=3D 0) { > - result =3D -errno; > - error_setg_errno(errp, -result, "Could not close the new f= ile"); > + } else if (prealloc =3D=3D PREALLOC_MODE_FULL) { > + buf =3D g_malloc0(65536); > + int64_t num =3D 0, left =3D total_size; > + > + while (left > 0) { > + num =3D MIN(left, 65536); > + result =3D write(fd, buf, num); > + if (result < 0) { > + result =3D -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 woul= d 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 -=3D num; > } > + fsync(fd); > + g_free(buf); > + } else if (prealloc !=3D PREALLOC_MODE_OFF) { > + result =3D -EINVAL; > + error_setg(errp, "Unsupported preallocation mode: %s", > + PreallocMode_lookup[prealloc]); > } > + > +out_close: > + if (qemu_close(fd) !=3D 0 && result =3D=3D 0) { > + result =3D -errno; > + error_setg_errno(errp, -result, "Could not close the new file"= ); > + } > +out: > return result; > } > =20 > @@ -1585,6 +1635,11 @@ static QemuOptsList raw_create_opts =3D { > .type =3D QEMU_OPT_BOOL, > .help =3D "Turn off copy-on-write (valid only on btrfs)" > }, > + { > + .name =3D BLOCK_OPT_PREALLOC, > + .type =3D QEMU_OPT_STRING, > + .help =3D "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 s= ectors will reserve > space. Use @code{qemu-img info} to know the real size used by the > image or @code{ls -ls} on Unix/Linux. > =20 > +Supported options: > +@table @code > +@item preallocation > +Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{f= ull}). > +@code{falloc} mode preallocates space for image by calling posix_fallo= cate(). > +@code{full} mode preallocates space for image by writing zeros to unde= rlying > +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 s= ectors will reserve > space. Use @code{qemu-img info} to know the real size used by the > image or @code{ls -ls} on Unix/Linux. > =20 > +Supported options: > +@table @code > +@item preallocation > +Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{f= ull}). > +@code{falloc} mode preallocates space for image by calling posix_fallo= cate(). > +@code{full} mode preallocates space for image by writing zeros to unde= rlying > +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 > --=20 > 1.9.3 >=20 >=20