From: Kevin Wolf <kwolf@redhat.com>
To: anthony@codemonkey.ws
Cc: kwolf@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 22/41] block: per caller dirty bitmap
Date: Fri, 29 Nov 2013 17:45:37 +0100 [thread overview]
Message-ID: <1385743555-27888-23-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1385743555-27888-1-git-send-email-kwolf@redhat.com>
From: Fam Zheng <famz@redhat.com>
Previously a BlockDriverState has only one dirty bitmap, so only one
caller (e.g. a block job) can keep track of writing. This changes the
dirty bitmap to a list and creates a BdrvDirtyBitmap for each caller, the
lifecycle is managed with these new functions:
bdrv_create_dirty_bitmap
bdrv_release_dirty_bitmap
Where BdrvDirtyBitmap is a linked list wrapper structure of HBitmap.
In place of bdrv_set_dirty_tracking, a BdrvDirtyBitmap pointer argument
is added to these functions, since each caller has its own dirty bitmap:
bdrv_get_dirty
bdrv_dirty_iter_init
bdrv_get_dirty_count
bdrv_set_dirty and bdrv_reset_dirty prototypes are unchanged but will
internally walk the list of all dirty bitmaps and set them one by one.
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block-migration.c | 22 +++++++++----
block.c | 83 ++++++++++++++++++++++++++++-------------------
block/mirror.c | 23 +++++++------
block/qapi.c | 8 -----
include/block/block.h | 11 ++++---
include/block/block_int.h | 2 +-
6 files changed, 86 insertions(+), 63 deletions(-)
diff --git a/block-migration.c b/block-migration.c
index fc4ef93..897fdba 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -58,6 +58,7 @@ typedef struct BlkMigDevState {
/* Protected by block migration lock. */
unsigned long *aio_bitmap;
int64_t completed_sectors;
+ BdrvDirtyBitmap *dirty_bitmap;
} BlkMigDevState;
typedef struct BlkMigBlock {
@@ -309,12 +310,21 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
/* Called with iothread lock taken. */
-static void set_dirty_tracking(int enable)
+static void set_dirty_tracking(void)
{
BlkMigDevState *bmds;
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
- bdrv_set_dirty_tracking(bmds->bs, enable ? BLOCK_SIZE : 0);
+ bmds->dirty_bitmap = bdrv_create_dirty_bitmap(bmds->bs, BLOCK_SIZE);
+ }
+}
+
+static void unset_dirty_tracking(void)
+{
+ BlkMigDevState *bmds;
+
+ QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
+ bdrv_release_dirty_bitmap(bmds->bs, bmds->dirty_bitmap);
}
}
@@ -432,7 +442,7 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
} else {
blk_mig_unlock();
}
- if (bdrv_get_dirty(bmds->bs, sector)) {
+ if (bdrv_get_dirty(bmds->bs, bmds->dirty_bitmap, sector)) {
if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
nr_sectors = total_sectors - sector;
@@ -554,7 +564,7 @@ static int64_t get_remaining_dirty(void)
int64_t dirty = 0;
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
- dirty += bdrv_get_dirty_count(bmds->bs);
+ dirty += bdrv_get_dirty_count(bmds->bs, bmds->dirty_bitmap);
}
return dirty << BDRV_SECTOR_BITS;
@@ -569,7 +579,7 @@ static void blk_mig_cleanup(void)
bdrv_drain_all();
- set_dirty_tracking(0);
+ unset_dirty_tracking();
blk_mig_lock();
while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
@@ -604,7 +614,7 @@ static int block_save_setup(QEMUFile *f, void *opaque)
init_blk_migration(f);
/* start track dirty blocks */
- set_dirty_tracking(1);
+ set_dirty_tracking();
qemu_mutex_unlock_iothread();
ret = flush_blks(f);
diff --git a/block.c b/block.c
index e22b55f..d792d53 100644
--- a/block.c
+++ b/block.c
@@ -49,6 +49,11 @@
#include <windows.h>
#endif
+struct BdrvDirtyBitmap {
+ HBitmap *bitmap;
+ QLIST_ENTRY(BdrvDirtyBitmap) list;
+};
+
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
@@ -318,6 +323,7 @@ BlockDriverState *bdrv_new(const char *device_name)
BlockDriverState *bs;
bs = g_malloc0(sizeof(BlockDriverState));
+ QLIST_INIT(&bs->dirty_bitmaps);
pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
if (device_name[0] != '\0') {
QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
@@ -1617,7 +1623,7 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
bs_dest->iostatus = bs_src->iostatus;
/* dirty bitmap */
- bs_dest->dirty_bitmap = bs_src->dirty_bitmap;
+ bs_dest->dirty_bitmaps = bs_src->dirty_bitmaps;
/* reference count */
bs_dest->refcnt = bs_src->refcnt;
@@ -1650,7 +1656,7 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
/* bs_new must be anonymous and shouldn't have anything fancy enabled */
assert(bs_new->device_name[0] == '\0');
- assert(bs_new->dirty_bitmap == NULL);
+ assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
assert(bs_new->job == NULL);
assert(bs_new->dev == NULL);
assert(bs_new->in_use == 0);
@@ -1711,6 +1717,7 @@ static void bdrv_delete(BlockDriverState *bs)
assert(!bs->job);
assert(!bs->in_use);
assert(!bs->refcnt);
+ assert(QLIST_EMPTY(&bs->dirty_bitmaps));
bdrv_close(bs);
@@ -2858,9 +2865,7 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
ret = bdrv_co_flush(bs);
}
- if (bs->dirty_bitmap) {
- bdrv_set_dirty(bs, sector_num, nb_sectors);
- }
+ bdrv_set_dirty(bs, sector_num, nb_sectors);
if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
bs->wr_highest_sector = sector_num + nb_sectors - 1;
@@ -3431,7 +3436,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
- assert(!bs->dirty_bitmap);
+ assert(QLIST_EMPTY(&bs->dirty_bitmaps));
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
}
@@ -4296,9 +4301,7 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
return -EROFS;
}
- if (bs->dirty_bitmap) {
- bdrv_reset_dirty(bs, sector_num, nb_sectors);
- }
+ bdrv_reset_dirty(bs, sector_num, nb_sectors);
/* Do nothing if disabled. */
if (!(bs->open_flags & BDRV_O_UNMAP)) {
@@ -4490,58 +4493,70 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
return true;
}
-void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity)
+BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity)
{
int64_t bitmap_size;
+ BdrvDirtyBitmap *bitmap;
assert((granularity & (granularity - 1)) == 0);
- if (granularity) {
- granularity >>= BDRV_SECTOR_BITS;
- assert(!bs->dirty_bitmap);
- bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
- bs->dirty_bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
- } else {
- if (bs->dirty_bitmap) {
- hbitmap_free(bs->dirty_bitmap);
- bs->dirty_bitmap = NULL;
+ granularity >>= BDRV_SECTOR_BITS;
+ assert(granularity);
+ bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
+ bitmap = g_malloc0(sizeof(BdrvDirtyBitmap));
+ bitmap->bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
+ QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
+ return bitmap;
+}
+
+void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
+{
+ BdrvDirtyBitmap *bm, *next;
+ QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
+ if (bm == bitmap) {
+ QLIST_REMOVE(bitmap, list);
+ hbitmap_free(bitmap->bitmap);
+ g_free(bitmap);
+ return;
}
}
}
-int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
+int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector)
{
- if (bs->dirty_bitmap) {
- return hbitmap_get(bs->dirty_bitmap, sector);
+ if (bitmap) {
+ return hbitmap_get(bitmap->bitmap, sector);
} else {
return 0;
}
}
-void bdrv_dirty_iter_init(BlockDriverState *bs, HBitmapIter *hbi)
+void bdrv_dirty_iter_init(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap, HBitmapIter *hbi)
{
- hbitmap_iter_init(hbi, bs->dirty_bitmap, 0);
+ hbitmap_iter_init(hbi, bitmap->bitmap, 0);
}
void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
int nr_sectors)
{
- hbitmap_set(bs->dirty_bitmap, cur_sector, nr_sectors);
+ BdrvDirtyBitmap *bitmap;
+ QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
+ hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
+ }
}
-void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
- int nr_sectors)
+void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors)
{
- hbitmap_reset(bs->dirty_bitmap, cur_sector, nr_sectors);
+ BdrvDirtyBitmap *bitmap;
+ QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
+ hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
+ }
}
-int64_t bdrv_get_dirty_count(BlockDriverState *bs)
+int64_t bdrv_get_dirty_count(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
{
- if (bs->dirty_bitmap) {
- return hbitmap_count(bs->dirty_bitmap);
- } else {
- return 0;
- }
+ return hbitmap_count(bitmap->bitmap);
}
/* Get a reference to bs */
diff --git a/block/mirror.c b/block/mirror.c
index 7b95acf..6dc27ad 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -39,6 +39,7 @@ typedef struct MirrorBlockJob {
int64_t granularity;
size_t buf_size;
unsigned long *cow_bitmap;
+ BdrvDirtyBitmap *dirty_bitmap;
HBitmapIter hbi;
uint8_t *buf;
QSIMPLEQ_HEAD(, MirrorBuffer) buf_free;
@@ -145,9 +146,10 @@ static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
s->sector_num = hbitmap_iter_next(&s->hbi);
if (s->sector_num < 0) {
- bdrv_dirty_iter_init(source, &s->hbi);
+ bdrv_dirty_iter_init(source, s->dirty_bitmap, &s->hbi);
s->sector_num = hbitmap_iter_next(&s->hbi);
- trace_mirror_restart_iter(s, bdrv_get_dirty_count(source));
+ trace_mirror_restart_iter(s,
+ bdrv_get_dirty_count(source, s->dirty_bitmap));
assert(s->sector_num >= 0);
}
@@ -183,7 +185,7 @@ static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
do {
int added_sectors, added_chunks;
- if (!bdrv_get_dirty(source, next_sector) ||
+ if (!bdrv_get_dirty(source, s->dirty_bitmap, next_sector) ||
test_bit(next_chunk, s->in_flight_bitmap)) {
assert(nb_sectors > 0);
break;
@@ -249,7 +251,8 @@ static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
/* Advance the HBitmapIter in parallel, so that we do not examine
* the same sector twice.
*/
- if (next_sector > hbitmap_next_sector && bdrv_get_dirty(source, next_sector)) {
+ if (next_sector > hbitmap_next_sector
+ && bdrv_get_dirty(source, s->dirty_bitmap, next_sector)) {
hbitmap_next_sector = hbitmap_iter_next(&s->hbi);
}
@@ -355,7 +358,7 @@ static void coroutine_fn mirror_run(void *opaque)
}
}
- bdrv_dirty_iter_init(bs, &s->hbi);
+ bdrv_dirty_iter_init(bs, s->dirty_bitmap, &s->hbi);
last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
for (;;) {
uint64_t delay_ns;
@@ -367,7 +370,7 @@ static void coroutine_fn mirror_run(void *opaque)
goto immediate_exit;
}
- cnt = bdrv_get_dirty_count(bs);
+ cnt = bdrv_get_dirty_count(bs, s->dirty_bitmap);
/* Note that even when no rate limit is applied we need to yield
* periodically with no pending I/O so that qemu_aio_flush() returns.
@@ -409,7 +412,7 @@ static void coroutine_fn mirror_run(void *opaque)
should_complete = s->should_complete ||
block_job_is_cancelled(&s->common);
- cnt = bdrv_get_dirty_count(bs);
+ cnt = bdrv_get_dirty_count(bs, s->dirty_bitmap);
}
}
@@ -424,7 +427,7 @@ static void coroutine_fn mirror_run(void *opaque)
*/
trace_mirror_before_drain(s, cnt);
bdrv_drain_all();
- cnt = bdrv_get_dirty_count(bs);
+ cnt = bdrv_get_dirty_count(bs, s->dirty_bitmap);
}
ret = 0;
@@ -471,7 +474,7 @@ immediate_exit:
qemu_vfree(s->buf);
g_free(s->cow_bitmap);
g_free(s->in_flight_bitmap);
- bdrv_set_dirty_tracking(bs, 0);
+ bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
bdrv_iostatus_disable(s->target);
if (s->should_complete && ret == 0) {
if (bdrv_get_flags(s->target) != bdrv_get_flags(s->common.bs)) {
@@ -575,7 +578,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
s->granularity = granularity;
s->buf_size = MAX(buf_size, granularity);
- bdrv_set_dirty_tracking(bs, granularity);
+ s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity);
bdrv_set_enable_write_cache(s->target, true);
bdrv_set_on_error(s->target, on_target_error, on_target_error);
bdrv_iostatus_enable(s->target);
diff --git a/block/qapi.c b/block/qapi.c
index 5880b3e..6b0cdcf 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -204,14 +204,6 @@ void bdrv_query_info(BlockDriverState *bs,
info->io_status = bs->iostatus;
}
- if (bs->dirty_bitmap) {
- info->has_dirty = true;
- info->dirty = g_malloc0(sizeof(*info->dirty));
- info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE;
- info->dirty->granularity =
- ((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bs->dirty_bitmap));
- }
-
if (bs->drv) {
info->has_inserted = true;
info->inserted = g_malloc0(sizeof(*info->inserted));
diff --git a/include/block/block.h b/include/block/block.h
index 4d9e67c..33ae9a9 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -419,12 +419,15 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size);
bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
struct HBitmapIter;
-void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity);
-int bdrv_get_dirty(BlockDriverState *bs, int64_t sector);
+typedef struct BdrvDirtyBitmap BdrvDirtyBitmap;
+BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity);
+void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap);
+int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector);
void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
-void bdrv_dirty_iter_init(BlockDriverState *bs, struct HBitmapIter *hbi);
-int64_t bdrv_get_dirty_count(BlockDriverState *bs);
+void bdrv_dirty_iter_init(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi);
+int64_t bdrv_get_dirty_count(BlockDriverState *bs, BdrvDirtyBitmap *bitmap);
void bdrv_enable_copy_on_read(BlockDriverState *bs);
void bdrv_disable_copy_on_read(BlockDriverState *bs);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 95140b6..3c5e9cb 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -318,7 +318,7 @@ struct BlockDriverState {
bool iostatus_enabled;
BlockDeviceIoStatus iostatus;
char device_name[32];
- HBitmap *dirty_bitmap;
+ QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps;
int refcnt;
int in_use; /* users other than guest access, eg. block migration */
QTAILQ_ENTRY(BlockDriverState) list;
--
1.8.1.4
next prev parent reply other threads:[~2013-11-29 16:47 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-29 16:45 [Qemu-devel] [PULL 00/41] Block patches for 2.0 (flushing block-next) Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 01/41] block: make BdrvRequestFlags public Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 02/41] block: add flags to bdrv_*_write_zeroes Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 03/41] block: introduce BDRV_REQ_MAY_UNMAP request flag Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 04/41] block: add logical block provisioning info to BlockDriverInfo Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 05/41] block: add wrappers for logical block provisioning information Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 06/41] block/iscsi: add .bdrv_get_info Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 07/41] block: add BlockLimits structure to BlockDriverState Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 08/41] block/raw: copy BlockLimits on raw_open Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 09/41] block: honour BlockLimits in bdrv_co_do_write_zeroes Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 10/41] block: honour BlockLimits in bdrv_co_discard Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 11/41] iscsi: set limits in BlockDriverState Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 12/41] iscsi: simplify iscsi_co_discard Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 13/41] iscsi: add bdrv_co_write_zeroes Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 14/41] block: introduce bdrv_make_zero Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 15/41] block/get_block_status: fix BDRV_BLOCK_ZERO for unallocated blocks Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 16/41] qemu-img: add support for fully allocated images Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 17/41] qemu-img: conditionally zero out target on convert Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 18/41] util/error: Save errno from clobbering Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 19/41] Test coroutine execution order Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 20/41] sheepdog: implement .bdrv_get_allocated_file_size Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 21/41] block/stream: Don't stream unbacked devices Kevin Wolf
2013-11-29 16:45 ` Kevin Wolf [this message]
2013-11-29 16:45 ` [Qemu-devel] [PULL 23/41] qapi: Change BlockDirtyInfo to list Kevin Wolf
2013-11-30 20:38 ` Eric Blake
2013-12-02 10:29 ` Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 24/41] COW: Speed up writes Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 25/41] COW: Extend checking allocated bits to beyond one sector Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 26/41] MAINTAINERS: add sheepdog development mailing list Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 27/41] qdict: Fix memory leak in qdict_do_flatten() Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 28/41] qdict: Optimise qdict_do_flatten() Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 29/41] sheepdog: refactor do_sd_create() Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 30/41] sheepdog: support user-defined redundancy option Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 31/41] qemu-iotests: Drop local version of cancel_and_wait from 040 Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 32/41] blkdebug: add "remove_break" command Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 33/41] qemu-iotest: Add pause_drive and resume_drive methods Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 34/41] qemu-iotests: Make test case 030, 040 and 055 deterministic Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 35/41] block: Enable BDRV_O_SNAPSHOT with driver-specific options Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 36/41] qemu-iotests: Test snapshot mode Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 37/41] block: Use BDRV_O_NO_BACKING where appropriate Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 38/41] qemu-iotests: Filter qemu-io output in 025 Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 40/41] vmdk: Allow read only open of VMDK version 3 Kevin Wolf
2013-11-29 16:45 ` [Qemu-devel] [PULL 41/41] qemu-iotests: Add sample image and test for " Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1385743555-27888-23-git-send-email-kwolf@redhat.com \
--to=kwolf@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).