From 932dcbcdbf8d8c8a868466924102083e50b9884f Mon Sep 17 00:00:00 2001
Message-Id: <932dcbcdbf8d8c8a868466924102083e50b9884f.1378813438.git.minovotn@redhat.com>
In-Reply-To: <b80f97e724da8388b544413d6a3dcac35d347d9b.1378813438.git.minovotn@redhat.com>
References: <b80f97e724da8388b544413d6a3dcac35d347d9b.1378813438.git.minovotn@redhat.com>
From: Jeffrey Cody <jcody@redhat.com>
Date: Wed, 28 Aug 2013 13:14:44 +0200
Subject: [PATCH 02/13] vpc: Read/write multiple sectors at once

RH-Author: Jeffrey Cody <jcody@redhat.com>
Message-id: <bc5e17a1ba36585a372a95be88904e2391711dda.1377694139.git.jcody@redhat.com>
Patchwork-id: 53837
O-Subject: [RHEL6.5 qemu-kvm PATCH 02/13] vpc: Read/write multiple sectors at once
Bugzilla: 999779
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>

From: Kevin Wolf <kwolf@redhat.com>

This changes the vpc block driver (for VHD) to read/write multiple sectors at
once instead of doing a request for each single sector.

Before this, running qemu-iotests for VPC took ages, now it's actually quite
reasonable to run it always (down from ~1 hour to 40 seconds for me).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6c6ea921ff9eebec514635aa7af893adf893fb12)
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 block/vpc.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 block/vpc.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index fd79547..2a1f536 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -380,23 +380,33 @@ fail:
 static int vpc_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
+    BDRVVPCState *s = bs->opaque;
     int ret;
     int64_t offset;
+    int64_t sectors, sectors_per_block;
 
     while (nb_sectors > 0) {
         offset = get_sector_offset(bs, sector_num, 0);
 
+        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
+        sectors = sectors_per_block - (sector_num % sectors_per_block);
+        if (sectors > nb_sectors) {
+            sectors = nb_sectors;
+        }
+
         if (offset == -1) {
-            memset(buf, 0, 512);
+            memset(buf, 0, sectors * BDRV_SECTOR_SIZE);
         } else {
-            ret = bdrv_pread(bs->file, offset, buf, 512);
-            if (ret != 512)
+            ret = bdrv_pread(bs->file, offset, buf,
+                sectors * BDRV_SECTOR_SIZE);
+            if (ret != sectors * BDRV_SECTOR_SIZE) {
                 return -1;
+            }
         }
 
-        nb_sectors--;
-        sector_num++;
-        buf += 512;
+        nb_sectors -= sectors;
+        sector_num += sectors;
+        buf += sectors * BDRV_SECTOR_SIZE;
     }
     return 0;
 }
@@ -415,25 +425,34 @@ static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num,
 static int vpc_write(BlockDriverState *bs, int64_t sector_num,
     const uint8_t *buf, int nb_sectors)
 {
+    BDRVVPCState *s = bs->opaque;
     int64_t offset;
+    int64_t sectors, sectors_per_block;
     int ret;
 
     while (nb_sectors > 0) {
         offset = get_sector_offset(bs, sector_num, 1);
 
+        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
+        sectors = sectors_per_block - (sector_num % sectors_per_block);
+        if (sectors > nb_sectors) {
+            sectors = nb_sectors;
+        }
+
         if (offset == -1) {
             offset = alloc_block(bs, sector_num);
             if (offset < 0)
                 return -1;
         }
 
-        ret = bdrv_pwrite(bs->file, offset, buf, 512);
-        if (ret != 512)
+        ret = bdrv_pwrite(bs->file, offset, buf, sectors * BDRV_SECTOR_SIZE);
+        if (ret != sectors * BDRV_SECTOR_SIZE) {
             return -1;
+        }
 
-        nb_sectors--;
-        sector_num++;
-        buf += 512;
+        nb_sectors -= sectors;
+        sector_num += sectors;
+        buf += sectors * BDRV_SECTOR_SIZE;
     }
 
     return 0;
-- 
1.7.11.7

