summaryrefslogtreecommitdiff
path: root/block/io.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-07-19 11:47:06 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-07-19 11:47:07 +0100
commitad31cd4c6945d7e0f0546d92d29dcd12325b4e4a (patch)
tree72a1e32a2910d60ba0604185b9ea4d2057eee9c4 /block/io.c
parent0c1b58f25025cc09463aae235162b19ff45c37b7 (diff)
parent3ff2f67a7c24183fcbcfe1332e5223ac6f96438c (diff)
downloadqemu-ad31cd4c6945d7e0f0546d92d29dcd12325b4e4a.tar.gz
qemu-ad31cd4c6945d7e0f0546d92d29dcd12325b4e4a.tar.bz2
qemu-ad31cd4c6945d7e0f0546d92d29dcd12325b4e4a.zip
Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
# gpg: Signature made Mon 18 Jul 2016 23:53:15 BST # gpg: using RSA key 0x7DEF8106AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" # Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB # Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E * remotes/jnsnow/tags/ide-pull-request: block: ignore flush requests when storage is clean tests: in IDE and AHCI tests perform DMA write before flushing ide: set retry_unit for PIO and FLUSH requests ide: refactor retry_unit set and clear into separate function Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block/io.c')
-rw-r--r--block/io.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/block/io.c b/block/io.c
index 2887394633..cfda7148d8 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1303,6 +1303,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
}
bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
+ ++bs->write_gen;
bdrv_set_dirty(bs, start_sector, end_sector - start_sector);
if (bs->wr_highest_offset < offset + bytes) {
@@ -2236,6 +2237,15 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
tracked_request_begin(&req, bs, 0, 0, BDRV_TRACKED_FLUSH);
+ int current_gen = bs->write_gen;
+
+ /* Wait until any previous flushes are completed */
+ while (bs->flush_started_gen != bs->flushed_gen) {
+ qemu_co_queue_wait(&bs->flush_queue);
+ }
+
+ bs->flush_started_gen = current_gen;
+
/* Write back all layers by calling one driver function */
if (bs->drv->bdrv_co_flush) {
ret = bs->drv->bdrv_co_flush(bs);
@@ -2256,6 +2266,11 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
goto flush_parent;
}
+ /* Check if we really need to flush anything */
+ if (bs->flushed_gen == current_gen) {
+ goto flush_parent;
+ }
+
BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK);
if (bs->drv->bdrv_co_flush_to_disk) {
ret = bs->drv->bdrv_co_flush_to_disk(bs);
@@ -2286,6 +2301,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
*/
ret = 0;
}
+
if (ret < 0) {
goto out;
}
@@ -2296,6 +2312,10 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
flush_parent:
ret = bs->file ? bdrv_co_flush(bs->file->bs) : 0;
out:
+ /* Notify any pending flushes that we have completed */
+ bs->flushed_gen = current_gen;
+ qemu_co_queue_restart_all(&bs->flush_queue);
+
tracked_request_end(&req);
return ret;
}
@@ -2421,6 +2441,7 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
}
ret = 0;
out:
+ ++bs->write_gen;
bdrv_set_dirty(bs, req.offset >> BDRV_SECTOR_BITS,
req.bytes >> BDRV_SECTOR_BITS);
tracked_request_end(&req);