From nobody Sun May 5 21:19:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1488156414460983.7098252323976; Sun, 26 Feb 2017 16:46:54 -0800 (PST) Received: from localhost ([::1]:49678 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ci9Sm-00045g-6C for importer@patchew.org; Sun, 26 Feb 2017 19:46:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52108) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ci9Rs-0003nB-Le for qemu-devel@nongnu.org; Sun, 26 Feb 2017 19:45:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ci9Rr-0005r6-BY for qemu-devel@nongnu.org; Sun, 26 Feb 2017 19:45:56 -0500 Received: from hera.aquilenet.fr ([141.255.128.1]:52773) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ci9Rl-0005mX-6k; Sun, 26 Feb 2017 19:45:49 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 80B14B9C2; Mon, 27 Feb 2017 01:45:47 +0100 (CET) Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Q2_bdSjIQrAE; Mon, 27 Feb 2017 01:45:46 +0100 (CET) Received: from var.youpi.perso.aquilenet.fr (unknown [IPv6:2a01:cb19:181:c200:3602:86ff:fe2c:6a19]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 2473DB9BC; Mon, 27 Feb 2017 01:45:46 +0100 (CET) Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.88) (envelope-from ) id 1ci9Rh-0006Sw-Cy; Mon, 27 Feb 2017 01:45:45 +0100 X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Date: Mon, 27 Feb 2017 01:45:45 +0100 From: Samuel Thibault To: Kevin Wolf , Max Reitz Message-ID: <20170227004545.hzpr266jzturlxdh@var.youpi.perso.aquilenet.fr> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 141.255.128.1 Subject: [Qemu-devel] [PATCH] blk: Add discard=sparse mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" By default, on discard requests, the posix block backend punches holes but re-fallocates them to keep the allocated size intact. In some situations it is however convenient, when using sparse disk images, to see disk image sizes shrink on discard requests. This commit adds a discard=3Dsparse mode which does this, by disabling the fallocate call. Signed-off-by: Samuel Thibault diff --git a/block.c b/block.c index b663204f3f..e9cd83210a 100644 --- a/block.c +++ b/block.c @@ -665,12 +665,14 @@ static void bdrv_join_options(BlockDriverState *bs, Q= Dict *options, */ int bdrv_parse_discard_flags(const char *mode, int *flags) { - *flags &=3D ~BDRV_O_UNMAP; + *flags &=3D ~(BDRV_O_UNMAP | BDRV_O_SPARSE); =20 if (!strcmp(mode, "off") || !strcmp(mode, "ignore")) { /* do nothing */ } else if (!strcmp(mode, "on") || !strcmp(mode, "unmap")) { *flags |=3D BDRV_O_UNMAP; + } else if (!strcmp(mode, "sparse")) { + *flags |=3D BDRV_O_UNMAP | BDRV_O_SPARSE; } else { return -1; } diff --git a/block/file-posix.c b/block/file-posix.c index 4de1abd023..f9efadc5be 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1057,6 +1057,10 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIO= Data *aiocb) BDRVRawState *s =3D aiocb->bs->opaque; #endif =20 +#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_FALLOCATE) + int open_flags =3D aiocb->bs->open_flags; +#endif + if (aiocb->aio_type & QEMU_AIO_BLKDEV) { return handle_aiocb_write_zeroes_block(aiocb); } @@ -1079,7 +1083,7 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOD= ata *aiocb) #endif =20 #ifdef CONFIG_FALLOCATE_PUNCH_HOLE - if (s->has_discard && s->has_fallocate) { + if (s->has_discard && (s->has_fallocate || open_flags & BDRV_O_SPARSE)= ) { int ret =3D do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, aiocb->aio_offset, aiocb->aio_nbytes); @@ -1098,7 +1102,8 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOD= ata *aiocb) #endif =20 #ifdef CONFIG_FALLOCATE - if (s->has_fallocate && aiocb->aio_offset >=3D bdrv_getlength(aiocb->b= s)) { + if (s->has_fallocate && !(open_flags & BDRV_O_SPARSE) + && aiocb->aio_offset >=3D bdrv_getlength(aiocb->bs)) { int ret =3D do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_n= bytes); if (ret =3D=3D 0 || ret !=3D -ENOTSUP) { return ret; diff --git a/include/block/block.h b/include/block/block.h index bde5ebda18..103313bee0 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -97,6 +97,8 @@ typedef struct HDGeometry { select an appropriate protocol drive= r, ignoring the format layer */ #define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */ +#define BDRV_O_SPARSE 0x20000 /* make guest UNMAP/TRIM operations mak= e image + possibly sparse */ =20 #define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH) =20 diff --git a/qemu-nbd.texi b/qemu-nbd.texi index 9a84e81eed..8df4f58ddc 100644 --- a/qemu-nbd.texi +++ b/qemu-nbd.texi @@ -63,8 +63,8 @@ and @samp{native} (Linux only). @item --discard=3D@var{discard} Control whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap}) requests are ignored or passed to the filesystem. @var{discard} is one of -@samp{ignore} (or @samp{off}), @samp{unmap} (or @samp{on}). The default is -@samp{ignore}. +@samp{ignore} (or @samp{off}), @samp{unmap} (or @samp{on}), or @samp{spars= e}. +The default is @samp{ignore}. @item --detect-zeroes=3D@var{detect-zeroes} Control the automatic conversion of plain zero writes by the OS to driver-specific optimized zero write commands. @var{detect-zeroes} is one= of diff --git a/qemu-options.hx b/qemu-options.hx index bf458f83c3..f5c7455fd1 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -539,7 +539,7 @@ DEF("drive", HAS_ARG, QEMU_OPTION_drive, " [,serial=3Ds][,addr=3DA][,rerror=3Dignore|stop|report]\n" " [,werror=3Dignore|stop|report|enospc][,id=3Dname][,aio=3Dthrea= ds|native]\n" " [,readonly=3Don|off][,copy-on-read=3Don|off]\n" - " [,discard=3Dignore|unmap][,detect-zeroes=3Don|off|unmap]\n" + " [,discard=3Dignore|unmap|sparse][,detect-zeroes=3Don|off|unmap= ]\n" " [[,bps=3Db]|[[,bps_rd=3Dr][,bps_wr=3Dw]]]\n" " [[,iops=3Di]|[[,iops_rd=3Dr][,iops_wr=3Dw]]]\n" " [[,bps_max=3Dbm]|[[,bps_rd_max=3Drm][,bps_wr_max=3Dwm]]]\n" @@ -582,7 +582,7 @@ These options have the same definition as they have in = @option{-hdachs}. @item aio=3D@var{aio} @var{aio} is "threads", or "native" and selects between pthread based disk= I/O and native Linux AIO. @item discard=3D@var{discard} -@var{discard} is one of "ignore" (or "off") or "unmap" (or "on") and contr= ols whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap}) request= s are ignored or passed to the filesystem. Some machine types may not supp= ort discard requests. +@var{discard} is one of "ignore" (or "off") or "unmap" (or "on") or "spars= e" and controls whether @dfn{discard} (also known as @dfn{trim} or @dfn{unm= ap}) requests are ignored or passed to the filesystem. Some machine types = may not support discard requests. @item format=3D@var{format} Specify which disk @var{format} will be used rather than detecting the format. Can be used to specify format=3Draw to avoid interpreting