218e99
From 69813093427b02a4a0e02264abd1f851f2b49249 Mon Sep 17 00:00:00 2001
218e99
From: Paolo Bonzini <pbonzini@redhat.com>
218e99
Date: Thu, 7 Nov 2013 07:23:45 +0100
218e99
Subject: [PATCH 26/81] block/get_block_status: avoid redundant callouts on raw devices
218e99
218e99
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
218e99
Message-id: <1382084091-16636-27-git-send-email-pbonzini@redhat.com>
218e99
Patchwork-id: 55009
218e99
O-Subject: [RHEL 7.0 qemu-kvm PATCH 26/26] block/get_block_status: avoid redundant callouts on raw devices
218e99
Bugzilla: 989646
218e99
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
218e99
RH-Acked-by: Max Reitz <mreitz@redhat.com>
218e99
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
218e99
218e99
From: Peter Lieven <pl@kamp.de>
218e99
218e99
if a raw device like an iscsi target or host device is used
218e99
the current implementation makes a second call out to get
218e99
the block status of bs->file.
218e99
218e99
Signed-off-by: Peter Lieven <pl@kamp.de>
218e99
Reviewed-by: Eric Blake <eblake@redhat.com>
218e99
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
218e99
(cherry picked from commit 92bc50a5ad7fbc9a0bd17240eaea5027a100ca79)
218e99
218e99
Conflicts:
218e99
	block/raw_bsd.c
218e99
218e99
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
218e99
---
218e99
 block.c               |    6 ++++++
218e99
 block/raw.c           |    4 +++-
218e99
 include/block/block.h |    4 ++++
218e99
 3 files changed, 13 insertions(+), 1 deletions(-)
218e99
218e99
diff --git a/block.c b/block.c
218e99
index 5c49461..fdff92f 100644
218e99
--- a/block.c
218e99
+++ b/block.c
218e99
@@ -3073,6 +3073,12 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
218e99
         return ret;
218e99
     }
218e99
 
218e99
+    if (ret & BDRV_BLOCK_RAW) {
218e99
+        assert(ret & BDRV_BLOCK_OFFSET_VALID);
218e99
+        return bdrv_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
218e99
+                                     *pnum, pnum);
218e99
+    }
218e99
+
218e99
     if (!(ret & BDRV_BLOCK_DATA)) {
218e99
         if (bdrv_has_zero_init(bs)) {
218e99
             ret |= BDRV_BLOCK_ZERO;
218e99
diff --git a/block/raw.c b/block/raw.c
218e99
index 844a222..7d82cf3 100644
218e99
--- a/block/raw.c
218e99
+++ b/block/raw.c
218e99
@@ -39,7 +39,9 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
218e99
                                             int64_t sector_num,
218e99
                                             int nb_sectors, int *pnum)
218e99
 {
218e99
-    return bdrv_get_block_status(bs->file, sector_num, nb_sectors, pnum);
218e99
+    *pnum = nb_sectors;
218e99
+    return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
218e99
+           (sector_num << BDRV_SECTOR_BITS);
218e99
 }
218e99
 
218e99
 static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
218e99
diff --git a/include/block/block.h b/include/block/block.h
218e99
index 01f5c65..bc1f5f6 100644
218e99
--- a/include/block/block.h
218e99
+++ b/include/block/block.h
218e99
@@ -95,6 +95,9 @@ typedef struct BlockDevOps {
218e99
 /* BDRV_BLOCK_DATA: data is read from bs->file or another file
218e99
  * BDRV_BLOCK_ZERO: sectors read as zero
218e99
  * BDRV_BLOCK_OFFSET_VALID: sector stored in bs->file as raw data
218e99
+ * BDRV_BLOCK_RAW: used internally to indicate that the request
218e99
+ *                 was answered by the raw driver and that one
218e99
+ *                 should look in bs->file directly.
218e99
  *
218e99
  * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 represent the offset in
218e99
  * bs->file where sector data can be read from as raw data.
218e99
@@ -116,6 +119,7 @@ typedef struct BlockDevOps {
218e99
 #define BDRV_BLOCK_DATA         1
218e99
 #define BDRV_BLOCK_ZERO         2
218e99
 #define BDRV_BLOCK_OFFSET_VALID 4
218e99
+#define BDRV_BLOCK_RAW          8
218e99
 #define BDRV_BLOCK_OFFSET_MASK  BDRV_SECTOR_MASK
218e99
 
218e99
 typedef enum {
218e99
-- 
218e99
1.7.1
218e99