From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:47364) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNQKl-0005Zv-2R for qemu-devel@nongnu.org; Mon, 07 Nov 2011 09:38:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RNQKe-0006l2-Ju for qemu-devel@nongnu.org; Mon, 07 Nov 2011 09:37:59 -0500 Received: from mail-ww0-f53.google.com ([74.125.82.53]:57861) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNQKe-0006kn-FI for qemu-devel@nongnu.org; Mon, 07 Nov 2011 09:37:52 -0500 Received: by wwg7 with SMTP id 7so5960924wwg.10 for ; Mon, 07 Nov 2011 06:37:51 -0800 (PST) MIME-Version: 1.0 In-Reply-To: References: <1318866452-30026-1-git-send-email-stefanha@linux.vnet.ibm.com> <1318866452-30026-5-git-send-email-stefanha@linux.vnet.ibm.com> Date: Mon, 7 Nov 2011 14:37:51 +0000 Message-ID: From: Stefan Hajnoczi Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC 4/6] block: request overlap detection List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Zhi Yong Wu Cc: Kevin Wolf , Paolo Bonzini , Marcelo Tosatti , Stefan Hajnoczi , qemu-devel@nongnu.org On Mon, Nov 7, 2011 at 11:49 AM, Zhi Yong Wu wrote: > On Mon, Oct 17, 2011 at 11:47 PM, Stefan Hajnoczi > wrote: >> Detect overlapping requests and remember to align to cluster boundaries >> if the image format uses them. =A0This assumes that allocating I/O is >> performed in cluster granularity - which is true for qcow2, qed, etc. >> >> Signed-off-by: Stefan Hajnoczi >> --- >> =A0block.c | =A0 39 +++++++++++++++++++++++++++++++++++++-- >> =A01 files changed, 37 insertions(+), 2 deletions(-) >> >> diff --git a/block.c b/block.c >> index cc3202c..0c22741 100644 >> --- a/block.c >> +++ b/block.c >> @@ -1052,21 +1052,56 @@ static BdrvTrackedRequest *tracked_request_add(B= lockDriverState *bs, >> =A0 =A0 return req; >> =A0} >> >> +/** >> + * Round a region to cluster boundaries >> + */ >> +static void round_to_clusters(BlockDriverState *bs, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int64_t sec= tor_num, int nb_sectors, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int64_t *cl= uster_sector_num, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int *cluste= r_nb_sectors) >> +{ >> + =A0 =A0BlockDriverInfo bdi; >> + >> + =A0 =A0if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size =3D=3D 0) { >> + =A0 =A0 =A0 =A0*cluster_sector_num =3D sector_num; >> + =A0 =A0 =A0 =A0*cluster_nb_sectors =3D nb_sectors; >> + =A0 =A0} else { >> + =A0 =A0 =A0 =A0int64_t c =3D bdi.cluster_size / BDRV_SECTOR_SIZE; >> + =A0 =A0 =A0 =A0*cluster_sector_num =3D (sector_num / c) * c; > =A0 =A0 =A0 =A0 =A0 =A0 I can understand the above formula, but the one b= elow is > very magic. :) and can not be understood by me. >> + =A0 =A0 =A0 =A0*cluster_nb_sectors =3D ((sector_num % c) + nb_sectors = + c - 1) / c * c; I agree this is ugly. Here is what is going on: c =3D number of sectors per cluster cluster_sector_num =3D sector number rounded *down* to cluster boundary cluster_nb_sectors =3D number of sectors from cluster_sector_num to rounded up sector_num+nb_sectors So the magic expression is takes the original sector_num to sector_num+nb_sectors region: |---XXX|XXX---| Where |-----| is a cluster and XXXX is the region from sector_num to sector_num+nb_sectors, then the output should be: |RRRRRR|RRRRRR| Everything has been rounded to clusters. So here is the expression broken = down: *cluster_nb_sectors =3D ((sector_num % c) + nb_sectors + c - 1) / c * c; AAAAAAAAAAAAAA XXXXXXXXXX BBBBBBBBBBBBBB |AAAXXX|XXXBBB| A is actually equivalent to sector_num - cluster_sector_num. X is the original unrounded region. B is the rounding up to the next cluster bounary. Another way of writing this: *cluster_nb_sectors =3D ROUND_UP((sector_num - cluster_sector_num) + nb_sectors, c); I'll try to improve the code in the next revision. Stefan