0a122b
From d83c96945764748dff98dbe37169ae7c65a3dac5 Mon Sep 17 00:00:00 2001
0a122b
From: Fam Zheng <famz@redhat.com>
0a122b
Date: Fri, 17 Jan 2014 03:07:52 +0100
0a122b
Subject: [PATCH 09/34] block: use BDS ref for block jobs
0a122b
0a122b
RH-Author: Fam Zheng <famz@redhat.com>
0a122b
Message-id: <1389928083-8921-8-git-send-email-famz@redhat.com>
0a122b
Patchwork-id: 56769
0a122b
O-Subject: [RHEL-7 qemu-kvm PATCH 07/18] block: use BDS ref for block jobs
0a122b
Bugzilla: 1041301
0a122b
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
0a122b
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
0a122b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
0a122b
Block jobs used drive_get_ref(drive_get_by_blockdev(bs)) to avoid BDS
0a122b
being deleted. Now we have BDS reference count, and block jobs don't
0a122b
care about dinfo, so replace them to get cleaner code. It is also the
0a122b
safe way when BDS has no drive info.
0a122b
0a122b
Signed-off-by: Fam Zheng <famz@redhat.com>
0a122b
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
(cherry picked from commit fa510ebffa1fd509323e2e0888e369e23adbb508)
0a122b
Signed-off-by: Fam Zheng <famz@redhat.com>
0a122b
0a122b
Conflicts:
0a122b
	blockdev.c
0a122b
0a122b
Conflict because drive-backup is not backported, and downstream has
0a122b
6270aec (block: optionally disable live block jobs).
0a122b
0a122b
Signed-off-by: Fam Zheng <famz@redhat.com>
0a122b
---
0a122b
 blockdev.c | 44 +++++++++++++++-----------------------------
0a122b
 blockjob.c |  1 +
0a122b
 2 files changed, 16 insertions(+), 29 deletions(-)
0a122b
0a122b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
0a122b
---
0a122b
 blockdev.c |   44 +++++++++++++++-----------------------------
0a122b
 blockjob.c |    1 +
0a122b
 2 files changed, 16 insertions(+), 29 deletions(-)
0a122b
0a122b
diff --git a/blockdev.c b/blockdev.c
0a122b
index 564262a..d795af2 100644
0a122b
--- a/blockdev.c
0a122b
+++ b/blockdev.c
0a122b
@@ -243,34 +243,34 @@ void drive_get_ref(DriveInfo *dinfo)
0a122b
 
0a122b
 typedef struct {
0a122b
     QEMUBH *bh;
0a122b
-    DriveInfo *dinfo;
0a122b
-} DrivePutRefBH;
0a122b
+    BlockDriverState *bs;
0a122b
+} BDRVPutRefBH;
0a122b
 
0a122b
 /* right now, this is only used from block_job_cb() */
0a122b
 #ifdef CONFIG_LIVE_BLOCK_OPS
0a122b
-static void drive_put_ref_bh(void *opaque)
0a122b
+static void bdrv_put_ref_bh(void *opaque)
0a122b
 {
0a122b
-    DrivePutRefBH *s = opaque;
0a122b
+    BDRVPutRefBH *s = opaque;
0a122b
 
0a122b
-    drive_put_ref(s->dinfo);
0a122b
+    bdrv_unref(s->bs);
0a122b
     qemu_bh_delete(s->bh);
0a122b
     g_free(s);
0a122b
 }
0a122b
 
0a122b
 /*
0a122b
- * Release a drive reference in a BH
0a122b
+ * Release a BDS reference in a BH
0a122b
  *
0a122b
- * It is not possible to use drive_put_ref() from a callback function when the
0a122b
- * callers still need the drive.  In such cases we schedule a BH to release the
0a122b
- * reference.
0a122b
+ * It is not safe to use bdrv_unref() from a callback function when the callers
0a122b
+ * still need the BlockDriverState.  In such cases we schedule a BH to release
0a122b
+ * the reference.
0a122b
  */
0a122b
-static void drive_put_ref_bh_schedule(DriveInfo *dinfo)
0a122b
+static void bdrv_put_ref_bh_schedule(BlockDriverState *bs)
0a122b
 {
0a122b
-    DrivePutRefBH *s;
0a122b
+    BDRVPutRefBH *s;
0a122b
 
0a122b
-    s = g_new(DrivePutRefBH, 1);
0a122b
-    s->bh = qemu_bh_new(drive_put_ref_bh, s);
0a122b
-    s->dinfo = dinfo;
0a122b
+    s = g_new(BDRVPutRefBH, 1);
0a122b
+    s->bh = qemu_bh_new(bdrv_put_ref_bh, s);
0a122b
+    s->bs = bs;
0a122b
     qemu_bh_schedule(s->bh);
0a122b
 }
0a122b
 #endif
0a122b
@@ -1423,7 +1423,7 @@ static void block_job_cb(void *opaque, int ret)
0a122b
     }
0a122b
     qobject_decref(obj);
0a122b
 
0a122b
-    drive_put_ref_bh_schedule(drive_get_by_blockdev(bs));
0a122b
+    bdrv_put_ref_bh_schedule(bs);
0a122b
 }
0a122b
 
0a122b
 void qmp_block_stream(const char *device, bool has_base,
0a122b
@@ -1460,11 +1460,6 @@ void qmp_block_stream(const char *device, bool has_base,
0a122b
         return;
0a122b
     }
0a122b
 
0a122b
-    /* Grab a reference so hotplug does not delete the BlockDriverState from
0a122b
-     * underneath us.
0a122b
-     */
0a122b
-    drive_get_ref(drive_get_by_blockdev(bs));
0a122b
-
0a122b
     trace_qmp_block_stream(bs, bs->job);
0a122b
 }
0a122b
 
0a122b
@@ -1521,10 +1516,6 @@ void qmp_block_commit(const char *device,
0a122b
         error_propagate(errp, local_err);
0a122b
         return;
0a122b
     }
0a122b
-    /* Grab a reference so hotplug does not delete the BlockDriverState from
0a122b
-     * underneath us.
0a122b
-     */
0a122b
-    drive_get_ref(drive_get_by_blockdev(bs));
0a122b
 }
0a122b
 
0a122b
 #define DEFAULT_MIRROR_BUF_SIZE   (10 << 20)
0a122b
@@ -1658,11 +1649,6 @@ void qmp_drive_mirror(const char *device, const char *target,
0a122b
         error_propagate(errp, local_err);
0a122b
         return;
0a122b
     }
0a122b
-
0a122b
-    /* Grab a reference so hotplug does not delete the BlockDriverState from
0a122b
-     * underneath us.
0a122b
-     */
0a122b
-    drive_get_ref(drive_get_by_blockdev(bs));
0a122b
 }
0a122b
 #endif
0a122b
 
0a122b
diff --git a/blockjob.c b/blockjob.c
0a122b
index c0a22d9..6d8c3a2 100644
0a122b
--- a/blockjob.c
0a122b
+++ b/blockjob.c
0a122b
@@ -45,6 +45,7 @@ void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
0a122b
         error_set(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
0a122b
         return NULL;
0a122b
     }
0a122b
+    bdrv_ref(bs);
0a122b
     bdrv_set_in_use(bs, 1);
0a122b
 
0a122b
     job = g_malloc0(job_type->instance_size);
0a122b
-- 
0a122b
1.7.1
0a122b