---
v2 -> v3:
- Add description of cache=volatile
- Squash aio noop noop patch into this one
---
block.c | 28 ++++++++++++++++++++++++++++
block.h | 1 +
qemu-config.c | 2 +-
qemu-options.hx | 13 ++++++++++---
vl.c | 3 +++
5 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index 48305b7..b742965 100644
--- a/block.c
+++ b/block.c
@@ -50,6 +50,8 @@ static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState
*bs,
BlockDriverCompletionFunc *cb, void *opaque);
static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
+static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
+ BlockDriverCompletionFunc *cb, void *opaque);
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
@@ -1306,6 +1308,10 @@ const char *bdrv_get_device_name(BlockDriverState *bs)
void bdrv_flush(BlockDriverState *bs)
{
+ if (bs->open_flags& BDRV_O_NO_FLUSH) {
+ return;
+ }
+
if (bs->drv&& bs->drv->bdrv_flush)
bs->drv->bdrv_flush(bs);
}
@@ -2082,6 +2088,10 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
{
BlockDriver *drv = bs->drv;
+ if (bs->open_flags& BDRV_O_NO_FLUSH) {
+ return bdrv_aio_noop_em(bs, cb, opaque);
+ }
+
if (!drv)
return NULL;
return drv->bdrv_aio_flush(bs, cb, opaque);
@@ -2196,6 +2206,24 @@ static BlockDriverAIOCB
*bdrv_aio_flush_em(BlockDriverState *bs,
return&acb->common;
}
+static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+ BlockDriverAIOCBSync *acb;
+
+ acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
+ acb->is_write = 1; /* don't bounce in the completion hadler */
+ acb->qiov = NULL;
+ acb->bounce = NULL;
+ acb->ret = 0;
+
+ if (!acb->bh)
+ acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
+
+ qemu_bh_schedule(acb->bh);
+ return&acb->common;
+}
+
/**************************************************************/
/* sync block device emulation */
diff --git a/block.h b/block.h
index f87d24e..8032b6b 100644
--- a/block.h
+++ b/block.h
@@ -33,6 +33,7 @@ typedef struct QEMUSnapshotInfo {
#define BDRV_O_CACHE_WB 0x0040 /* use write-back caching */
#define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the thread
pool */
#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
+#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB)
diff --git a/qemu-config.c b/qemu-config.c
index d500885..bf3d493 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -54,7 +54,7 @@ QemuOptsList qemu_drive_opts = {
},{
.name = "cache",
.type = QEMU_OPT_STRING,
- .help = "host cache usage (none, writeback, writethrough)",
+ .help = "host cache usage (none, writeback, writethrough,
volatile)",
},{
.name = "aio",
.type = QEMU_OPT_STRING,
diff --git a/qemu-options.hx b/qemu-options.hx
index 12f6b51..6dedb4a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -118,8 +118,9 @@ ETEXI
DEF("drive", HAS_ARG, QEMU_OPTION_drive,
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
" [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
- " [,cache=writethrough|writeback|none][,format=f][,serial=s]\n"
- " [,addr=A][,id=name][,aio=threads|native][,readonly=on|off]\n"
+ " [,cache=writethrough|writeback|volatile|none][,format=f]\n"
+ " [,serial=s][,addr=A][,id=name][,aio=threads|native]\n"
+ " [,readonly=on|off]\n"
" use 'file' as a drive image\n", QEMU_ARCH_ALL)
STEXI
@item -drive @var{option}[,@var{option}[,@var{option}[,...]]]
@@ -148,7 +149,7 @@ These options have the same definition as they have in
@option{-hdachs}.
@item address@hidden
@var{snapshot} is "on" or "off" and allows to enable snapshot for given drive
(see @option{-snapshot}).
@item address@hidden
address@hidden is "none", "writeback", or "writethrough" and controls how the
host cache is used to access block data.
address@hidden is "none", "writeback", "volatile", or "writethrough" and
controls how the host cache is used to access block data.
@item address@hidden
@var{aio} is "threads", or "native" and selects between pthread based disk
I/O and native Linux AIO.
@item address@hidden
@@ -180,6 +181,12 @@ Some block drivers perform badly with
@option{cache=writethrough}, most notably,
qcow2. If performance is more important than correctness,
@option{cache=writeback} should be used with qcow2.
+In case you don't care about data integrity over host failures, use
+cache=volatile. This option tells qemu that it never needs to write any data
+to the disk but can instead keeps things in cache. If anything goes wrong,
+like your host losing power, the disk storage getting disconnected accidently,
+etc. you're image will most probably be rendered unusable.
+
Instead of @option{-cdrom} you can use:
@example
qemu -drive file=file,index=2,media=cdrom
diff --git a/vl.c b/vl.c
index 85bcc84..c8abce6 100644
--- a/vl.c
+++ b/vl.c
@@ -913,6 +913,9 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
bdrv_flags |= BDRV_O_NOCACHE;
} else if (!strcmp(buf, "writeback")) {
bdrv_flags |= BDRV_O_CACHE_WB;
+ } else if (!strcmp(buf, "volatile")) {
+ bdrv_flags |= BDRV_O_CACHE_WB;
+ bdrv_flags |= BDRV_O_NO_FLUSH;
} else if (!strcmp(buf, "writethrough")) {
/* this is the default */
} else {