Merge remote-tracking branch 'kwolf/for-anthony' into staging

This commit is contained in:
Anthony Liguori 2011-10-26 10:29:24 -05:00
commit e86d9b12b5
36 changed files with 527 additions and 295 deletions

262
block.c
View File

@ -53,17 +53,12 @@ static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
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 coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov);
static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov);
static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
@ -203,9 +198,6 @@ void bdrv_register(BlockDriver *bdrv)
}
}
if (!bdrv->bdrv_aio_flush)
bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
}
@ -1027,11 +1019,6 @@ static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
nb_sectors * BDRV_SECTOR_SIZE);
}
static inline bool bdrv_has_async_flush(BlockDriver *drv)
{
return drv->bdrv_aio_flush != bdrv_aio_flush_em;
}
typedef struct RwCo {
BlockDriverState *bs;
int64_t sector_num;
@ -1759,33 +1746,6 @@ const char *bdrv_get_device_name(BlockDriverState *bs)
return bs->device_name;
}
int bdrv_flush(BlockDriverState *bs)
{
if (bs->open_flags & BDRV_O_NO_FLUSH) {
return 0;
}
if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) {
return bdrv_co_flush_em(bs);
}
if (bs->drv && bs->drv->bdrv_flush) {
return bs->drv->bdrv_flush(bs);
}
/*
* Some block drivers always operate in either writethrough or unsafe mode
* and don't support bdrv_flush therefore. Usually qemu doesn't know how
* the server works (because the behaviour is hardcoded or depends on
* server-side configuration), so we can't ensure that everything is safe
* on disk. Returning an error doesn't work because that would break guests
* even if the server operates in writethrough mode.
*
* Let's hope the user knows what he's doing.
*/
return 0;
}
void bdrv_flush_all(void)
{
BlockDriverState *bs;
@ -1808,17 +1768,6 @@ int bdrv_has_zero_init(BlockDriverState *bs)
return 1;
}
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
{
if (!bs->drv) {
return -ENOMEDIUM;
}
if (!bs->drv->bdrv_discard) {
return 0;
}
return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
}
/*
* Returns true iff the specified sector is present in the disk image. Drivers
* not implementing the functionality are assumed to not support backing files,
@ -2610,22 +2559,6 @@ fail:
return -1;
}
BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
BlockDriver *drv = bs->drv;
trace_bdrv_aio_flush(bs, opaque);
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);
}
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
{
acb->pool->cancel(acb);
@ -2735,7 +2668,7 @@ static AIOPool bdrv_em_co_aio_pool = {
.cancel = bdrv_aio_co_cancel_em,
};
static void bdrv_co_rw_bh(void *opaque)
static void bdrv_co_em_bh(void *opaque)
{
BlockDriverAIOCBCoroutine *acb = opaque;
@ -2758,7 +2691,7 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
acb->req.nb_sectors, acb->req.qiov);
}
acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
qemu_bh_schedule(acb->bh);
}
@ -2785,41 +2718,56 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
return &acb->common;
}
static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
{
BlockDriverAIOCBCoroutine *acb = opaque;
BlockDriverState *bs = acb->common.bs;
acb->req.error = bdrv_co_flush(bs);
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
qemu_bh_schedule(acb->bh);
}
BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
BlockDriverAIOCBSync *acb;
trace_bdrv_aio_flush(bs, opaque);
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;
Coroutine *co;
BlockDriverAIOCBCoroutine *acb;
if (!acb->bh)
acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
qemu_coroutine_enter(co, acb);
bdrv_flush(bs);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
{
BlockDriverAIOCBCoroutine *acb = opaque;
BlockDriverState *bs = acb->common.bs;
acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
qemu_bh_schedule(acb->bh);
}
BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
BlockDriverAIOCBSync *acb;
Coroutine *co;
BlockDriverAIOCBCoroutine *acb;
acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
acb->is_write = 1; /* don't bounce in the completion handler */
acb->qiov = NULL;
acb->bounce = NULL;
acb->ret = 0;
trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
if (!acb->bh) {
acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
}
acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
acb->req.sector = sector_num;
acb->req.nb_sectors = nb_sectors;
co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
qemu_coroutine_enter(co, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
@ -2916,19 +2864,131 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
}
static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs)
static void coroutine_fn bdrv_flush_co_entry(void *opaque)
{
CoroutineIOCompletion co = {
.coroutine = qemu_coroutine_self(),
};
BlockDriverAIOCB *acb;
RwCo *rwco = opaque;
acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
if (!acb) {
return -EIO;
rwco->ret = bdrv_co_flush(rwco->bs);
}
int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
{
if (bs->open_flags & BDRV_O_NO_FLUSH) {
return 0;
} else if (!bs->drv) {
return 0;
} else if (bs->drv->bdrv_co_flush) {
return bs->drv->bdrv_co_flush(bs);
} else if (bs->drv->bdrv_aio_flush) {
BlockDriverAIOCB *acb;
CoroutineIOCompletion co = {
.coroutine = qemu_coroutine_self(),
};
acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
if (acb == NULL) {
return -EIO;
} else {
qemu_coroutine_yield();
return co.ret;
}
} else {
/*
* Some block drivers always operate in either writethrough or unsafe
* mode and don't support bdrv_flush therefore. Usually qemu doesn't
* know how the server works (because the behaviour is hardcoded or
* depends on server-side configuration), so we can't ensure that
* everything is safe on disk. Returning an error doesn't work because
* that would break guests even if the server operates in writethrough
* mode.
*
* Let's hope the user knows what he's doing.
*/
return 0;
}
qemu_coroutine_yield();
return co.ret;
}
int bdrv_flush(BlockDriverState *bs)
{
Coroutine *co;
RwCo rwco = {
.bs = bs,
.ret = NOT_DONE,
};
if (qemu_in_coroutine()) {
/* Fast-path if already in coroutine context */
bdrv_flush_co_entry(&rwco);
} else {
co = qemu_coroutine_create(bdrv_flush_co_entry);
qemu_coroutine_enter(co, &rwco);
while (rwco.ret == NOT_DONE) {
qemu_aio_wait();
}
}
return rwco.ret;
}
static void coroutine_fn bdrv_discard_co_entry(void *opaque)
{
RwCo *rwco = opaque;
rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
}
int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
{
if (!bs->drv) {
return -ENOMEDIUM;
} else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
return -EIO;
} else if (bs->read_only) {
return -EROFS;
} else if (bs->drv->bdrv_co_discard) {
return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
} else if (bs->drv->bdrv_aio_discard) {
BlockDriverAIOCB *acb;
CoroutineIOCompletion co = {
.coroutine = qemu_coroutine_self(),
};
acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
bdrv_co_io_em_complete, &co);
if (acb == NULL) {
return -EIO;
} else {
qemu_coroutine_yield();
return co.ret;
}
} else {
return 0;
}
}
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
{
Coroutine *co;
RwCo rwco = {
.bs = bs,
.sector_num = sector_num,
.nb_sectors = nb_sectors,
.ret = NOT_DONE,
};
if (qemu_in_coroutine()) {
/* Fast-path if already in coroutine context */
bdrv_discard_co_entry(&rwco);
} else {
co = qemu_coroutine_create(bdrv_discard_co_entry);
qemu_coroutine_enter(co, &rwco);
while (rwco.ret == NOT_DONE) {
qemu_aio_wait();
}
}
return rwco.ret;
}
/**************************************************************/

View File

@ -166,6 +166,9 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque);
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
typedef struct BlockRequest {
@ -191,10 +194,12 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
/* Ensure contents are flushed to disk. */
int bdrv_flush(BlockDriverState *bs);
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
void bdrv_flush_all(void);
void bdrv_close_all(void);
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
int bdrv_has_zero_init(BlockDriverState *bs);
int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
int *pnum);

View File

@ -397,11 +397,6 @@ static void blkdebug_close(BlockDriverState *bs)
}
}
static int blkdebug_flush(BlockDriverState *bs)
{
return bdrv_flush(bs->file);
}
static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
@ -454,7 +449,6 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_file_open = blkdebug_open,
.bdrv_close = blkdebug_close,
.bdrv_flush = blkdebug_flush,
.bdrv_aio_readv = blkdebug_aio_readv,
.bdrv_aio_writev = blkdebug_aio_writev,

View File

@ -116,14 +116,6 @@ static void blkverify_close(BlockDriverState *bs)
s->test_file = NULL;
}
static int blkverify_flush(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;
/* Only flush test file, the raw file is not important */
return bdrv_flush(s->test_file);
}
static int64_t blkverify_getlength(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;
@ -368,7 +360,6 @@ static BlockDriver bdrv_blkverify = {
.bdrv_file_open = blkverify_open,
.bdrv_close = blkverify_close,
.bdrv_flush = blkverify_flush,
.bdrv_aio_readv = blkverify_aio_readv,
.bdrv_aio_writev = blkverify_aio_writev,

View File

@ -80,6 +80,7 @@ struct bochs_header {
};
typedef struct BDRVBochsState {
CoMutex lock;
uint32_t *catalog_bitmap;
int catalog_size;
@ -150,6 +151,7 @@ static int bochs_open(BlockDriverState *bs, int flags)
s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
qemu_co_mutex_init(&s->lock);
return 0;
fail:
return -1;
@ -207,6 +209,17 @@ static int bochs_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int bochs_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVBochsState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = bochs_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static void bochs_close(BlockDriverState *bs)
{
BDRVBochsState *s = bs->opaque;
@ -218,7 +231,7 @@ static BlockDriver bdrv_bochs = {
.instance_size = sizeof(BDRVBochsState),
.bdrv_probe = bochs_probe,
.bdrv_open = bochs_open,
.bdrv_read = bochs_read,
.bdrv_read = bochs_co_read,
.bdrv_close = bochs_close,
};

View File

@ -27,6 +27,7 @@
#include <zlib.h>
typedef struct BDRVCloopState {
CoMutex lock;
uint32_t block_size;
uint32_t n_blocks;
uint64_t* offsets;
@ -93,6 +94,7 @@ static int cloop_open(BlockDriverState *bs, int flags)
s->sectors_per_block = s->block_size/512;
bs->total_sectors = s->n_blocks*s->sectors_per_block;
qemu_co_mutex_init(&s->lock);
return 0;
cloop_close:
@ -144,6 +146,17 @@ static int cloop_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int cloop_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVCloopState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = cloop_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static void cloop_close(BlockDriverState *bs)
{
BDRVCloopState *s = bs->opaque;
@ -159,7 +172,7 @@ static BlockDriver bdrv_cloop = {
.instance_size = sizeof(BDRVCloopState),
.bdrv_probe = cloop_probe,
.bdrv_open = cloop_open,
.bdrv_read = cloop_read,
.bdrv_read = cloop_co_read,
.bdrv_close = cloop_close,
};

View File

@ -42,6 +42,7 @@ struct cow_header_v2 {
};
typedef struct BDRVCowState {
CoMutex lock;
int64_t cow_sectors_offset;
} BDRVCowState;
@ -84,6 +85,7 @@ static int cow_open(BlockDriverState *bs, int flags)
bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
s->cow_sectors_offset = (bitmap_size + 511) & ~511;
qemu_co_mutex_init(&s->lock);
return 0;
fail:
return -1;
@ -199,6 +201,17 @@ static int cow_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int cow_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVCowState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = cow_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static int cow_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
@ -213,6 +226,17 @@ static int cow_write(BlockDriverState *bs, int64_t sector_num,
return cow_update_bitmap(bs, sector_num, nb_sectors);
}
static coroutine_fn int cow_co_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
int ret;
BDRVCowState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = cow_write(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static void cow_close(BlockDriverState *bs)
{
}
@ -282,9 +306,9 @@ exit:
return ret;
}
static int cow_flush(BlockDriverState *bs)
static coroutine_fn int cow_co_flush(BlockDriverState *bs)
{
return bdrv_flush(bs->file);
return bdrv_co_flush(bs->file);
}
static QEMUOptionParameter cow_create_options[] = {
@ -306,11 +330,11 @@ static BlockDriver bdrv_cow = {
.instance_size = sizeof(BDRVCowState),
.bdrv_probe = cow_probe,
.bdrv_open = cow_open,
.bdrv_read = cow_read,
.bdrv_write = cow_write,
.bdrv_read = cow_co_read,
.bdrv_write = cow_co_write,
.bdrv_close = cow_close,
.bdrv_create = cow_create,
.bdrv_flush = cow_flush,
.bdrv_co_flush = cow_co_flush,
.bdrv_is_allocated = cow_is_allocated,
.create_options = cow_create_options,

View File

@ -28,6 +28,7 @@
#include <zlib.h>
typedef struct BDRVDMGState {
CoMutex lock;
/* each chunk contains a certain number of sectors,
* offsets[i] is the offset in the .dmg file,
* lengths[i] is the length of the compressed chunk,
@ -177,6 +178,7 @@ static int dmg_open(BlockDriverState *bs, int flags)
s->current_chunk = s->n_chunks;
qemu_co_mutex_init(&s->lock);
return 0;
fail:
return -1;
@ -280,6 +282,17 @@ static int dmg_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int dmg_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVDMGState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = dmg_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static void dmg_close(BlockDriverState *bs)
{
BDRVDMGState *s = bs->opaque;
@ -300,7 +313,7 @@ static BlockDriver bdrv_dmg = {
.instance_size = sizeof(BDRVDMGState),
.bdrv_probe = dmg_probe,
.bdrv_open = dmg_open,
.bdrv_read = dmg_read,
.bdrv_read = dmg_co_read,
.bdrv_close = dmg_close,
};

View File

@ -47,6 +47,7 @@
#endif
typedef struct BDRVNBDState {
CoMutex lock;
int sock;
uint32_t nbdflags;
off_t size;
@ -175,6 +176,7 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
*/
result = nbd_establish_connection(bs);
qemu_co_mutex_init(&s->lock);
return result;
}
@ -238,6 +240,28 @@ static int nbd_write(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int nbd_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVNBDState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = nbd_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static coroutine_fn int nbd_co_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
int ret;
BDRVNBDState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = nbd_write(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static void nbd_close(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;
@ -258,8 +282,8 @@ static BlockDriver bdrv_nbd = {
.format_name = "nbd",
.instance_size = sizeof(BDRVNBDState),
.bdrv_file_open = nbd_open,
.bdrv_read = nbd_read,
.bdrv_write = nbd_write,
.bdrv_read = nbd_co_read,
.bdrv_write = nbd_co_write,
.bdrv_close = nbd_close,
.bdrv_getlength = nbd_getlength,
.protocol_name = "nbd",

View File

@ -46,6 +46,7 @@ struct parallels_header {
} QEMU_PACKED;
typedef struct BDRVParallelsState {
CoMutex lock;
uint32_t *catalog_bitmap;
int catalog_size;
@ -95,6 +96,7 @@ static int parallels_open(BlockDriverState *bs, int flags)
for (i = 0; i < s->catalog_size; i++)
le32_to_cpus(&s->catalog_bitmap[i]);
qemu_co_mutex_init(&s->lock);
return 0;
fail:
if (s->catalog_bitmap)
@ -134,6 +136,17 @@ static int parallels_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int parallels_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVParallelsState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = parallels_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static void parallels_close(BlockDriverState *bs)
{
BDRVParallelsState *s = bs->opaque;
@ -145,7 +158,7 @@ static BlockDriver bdrv_parallels = {
.instance_size = sizeof(BDRVParallelsState),
.bdrv_probe = parallels_probe,
.bdrv_open = parallels_open,
.bdrv_read = parallels_read,
.bdrv_read = parallels_co_read,
.bdrv_close = parallels_close,
};

View File

@ -781,15 +781,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static int qcow_flush(BlockDriverState *bs)
static coroutine_fn int qcow_co_flush(BlockDriverState *bs)
{
return bdrv_flush(bs->file);
}
static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
return bdrv_aio_flush(bs->file, cb, opaque);
return bdrv_co_flush(bs->file);
}
static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
@ -826,13 +820,12 @@ static BlockDriver bdrv_qcow = {
.bdrv_open = qcow_open,
.bdrv_close = qcow_close,
.bdrv_create = qcow_create,
.bdrv_flush = qcow_flush,
.bdrv_is_allocated = qcow_is_allocated,
.bdrv_set_key = qcow_set_key,
.bdrv_make_empty = qcow_make_empty,
.bdrv_co_readv = qcow_co_readv,
.bdrv_co_writev = qcow_co_writev,
.bdrv_aio_flush = qcow_aio_flush,
.bdrv_co_readv = qcow_co_readv,
.bdrv_co_writev = qcow_co_writev,
.bdrv_co_flush = qcow_co_flush,
.bdrv_write_compressed = qcow_write_compressed,
.bdrv_get_info = qcow_get_info,

View File

@ -568,8 +568,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
}
cluster_offset = be64_to_cpu(l2_table[l2_index]);
if (cluster_offset & QCOW_OFLAG_COPIED)
return cluster_offset & ~QCOW_OFLAG_COPIED;
if (cluster_offset & QCOW_OFLAG_COPIED) {
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
return 0;
}
if (cluster_offset)
qcow2_free_any_clusters(bs, cluster_offset, 1);

View File

@ -978,11 +978,17 @@ static int qcow2_make_empty(BlockDriverState *bs)
return 0;
}
static int qcow2_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
static coroutine_fn int qcow2_co_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors)
{
return qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
int ret;
BDRVQcowState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
@ -1053,8 +1059,8 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
Z_DEFLATED, -12,
9, Z_DEFAULT_STRATEGY);
if (ret != 0) {
g_free(out_buf);
return -1;
ret = -EINVAL;
goto fail;
}
strm.avail_in = s->cluster_size;
@ -1064,9 +1070,9 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
ret = deflate(&strm, Z_FINISH);
if (ret != Z_STREAM_END && ret != Z_OK) {
g_free(out_buf);
deflateEnd(&strm);
return -1;
ret = -EINVAL;
goto fail;
}
out_len = strm.next_out - out_buf;
@ -1074,29 +1080,37 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
/* could not compress: write normal cluster */
bdrv_write(bs, sector_num, buf, s->cluster_sectors);
ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
if (ret < 0) {
goto fail;
}
} else {
cluster_offset = qcow2_alloc_compressed_cluster_offset(bs,
sector_num << 9, out_len);
if (!cluster_offset)
return -1;
if (!cluster_offset) {
ret = -EIO;
goto fail;
}
cluster_offset &= s->cluster_offset_mask;
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) {
g_free(out_buf);
return -1;
ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
if (ret < 0) {
goto fail;
}
}
ret = 0;
fail:
g_free(out_buf);
return 0;
return ret;
}
static int qcow2_flush(BlockDriverState *bs)
static int qcow2_co_flush(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;
int ret;
qemu_co_mutex_lock(&s->lock);
ret = qcow2_cache_flush(bs, s->l2_table_cache);
if (ret < 0) {
return ret;
@ -1106,28 +1120,9 @@ static int qcow2_flush(BlockDriverState *bs)
if (ret < 0) {
return ret;
}
qemu_co_mutex_unlock(&s->lock);
return bdrv_flush(bs->file);
}
static BlockDriverAIOCB *qcow2_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb,
void *opaque)
{
BDRVQcowState *s = bs->opaque;
int ret;
ret = qcow2_cache_flush(bs, s->l2_table_cache);
if (ret < 0) {
return NULL;
}
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret < 0) {
return NULL;
}
return bdrv_aio_flush(bs->file, cb, opaque);
return bdrv_co_flush(bs->file);
}
static int64_t qcow2_vm_state_offset(BDRVQcowState *s)
@ -1242,16 +1237,15 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_open = qcow2_open,
.bdrv_close = qcow2_close,
.bdrv_create = qcow2_create,
.bdrv_flush = qcow2_flush,
.bdrv_is_allocated = qcow2_is_allocated,
.bdrv_set_key = qcow2_set_key,
.bdrv_make_empty = qcow2_make_empty,
.bdrv_co_readv = qcow2_co_readv,
.bdrv_co_writev = qcow2_co_writev,
.bdrv_aio_flush = qcow2_aio_flush,
.bdrv_co_flush = qcow2_co_flush,
.bdrv_discard = qcow2_discard,
.bdrv_co_discard = qcow2_co_discard,
.bdrv_truncate = qcow2_truncate,
.bdrv_write_compressed = qcow2_write_compressed,

View File

@ -533,11 +533,6 @@ static void bdrv_qed_close(BlockDriverState *bs)
qemu_vfree(s->l1_table);
}
static int bdrv_qed_flush(BlockDriverState *bs)
{
return bdrv_flush(bs->file);
}
static int qed_create(const char *filename, uint32_t cluster_size,
uint64_t image_size, uint32_t table_size,
const char *backing_file, const char *backing_fmt)
@ -1479,7 +1474,6 @@ static BlockDriver bdrv_qed = {
.bdrv_open = bdrv_qed_open,
.bdrv_close = bdrv_qed_close,
.bdrv_create = bdrv_qed_create,
.bdrv_flush = bdrv_qed_flush,
.bdrv_is_allocated = bdrv_qed_is_allocated,
.bdrv_make_empty = bdrv_qed_make_empty,
.bdrv_aio_readv = bdrv_qed_aio_readv,

View File

@ -583,19 +583,6 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
return result;
}
static int raw_flush(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
int ret;
ret = qemu_fdatasync(s->fd);
if (ret < 0) {
return -errno;
}
return 0;
}
#ifdef CONFIG_XFS
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
{
@ -615,7 +602,8 @@ static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
}
#endif
static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
static coroutine_fn int raw_co_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors)
{
#ifdef CONFIG_XFS
BDRVRawState *s = bs->opaque;
@ -645,8 +633,7 @@ static BlockDriver bdrv_file = {
.bdrv_file_open = raw_open,
.bdrv_close = raw_close,
.bdrv_create = raw_create,
.bdrv_flush = raw_flush,
.bdrv_discard = raw_discard,
.bdrv_co_discard = raw_co_discard,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@ -915,7 +902,6 @@ static BlockDriver bdrv_host_device = {
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@ -1035,7 +1021,6 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@ -1135,7 +1120,6 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@ -1255,7 +1239,6 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,

View File

@ -281,7 +281,7 @@ static BlockDriver bdrv_file = {
.bdrv_file_open = raw_open,
.bdrv_close = raw_close,
.bdrv_create = raw_create,
.bdrv_flush = raw_flush,
.bdrv_co_flush = raw_flush,
.bdrv_read = raw_read,
.bdrv_write = raw_write,
.bdrv_truncate = raw_truncate,
@ -409,7 +409,7 @@ static BlockDriver bdrv_host_device = {
.bdrv_probe_device = hdev_probe_device,
.bdrv_file_open = hdev_open,
.bdrv_close = raw_close,
.bdrv_flush = raw_flush,
.bdrv_co_flush = raw_flush,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_read = raw_read,

View File

@ -25,15 +25,9 @@ static void raw_close(BlockDriverState *bs)
{
}
static int raw_flush(BlockDriverState *bs)
static int coroutine_fn raw_co_flush(BlockDriverState *bs)
{
return bdrv_flush(bs->file);
}
static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
return bdrv_aio_flush(bs->file, cb, opaque);
return bdrv_co_flush(bs->file);
}
static int64_t raw_getlength(BlockDriverState *bs)
@ -51,9 +45,10 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
return 1; /* everything can be opened as raw image */
}
static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
static int coroutine_fn raw_co_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors)
{
return bdrv_discard(bs->file, sector_num, nb_sectors);
return bdrv_co_discard(bs->file, sector_num, nb_sectors);
}
static int raw_is_inserted(BlockDriverState *bs)
@ -115,16 +110,16 @@ static BlockDriver bdrv_raw = {
.bdrv_open = raw_open,
.bdrv_close = raw_close,
.bdrv_co_readv = raw_co_readv,
.bdrv_co_writev = raw_co_writev,
.bdrv_flush = raw_flush,
.bdrv_co_flush = raw_co_flush,
.bdrv_co_discard = raw_co_discard,
.bdrv_probe = raw_probe,
.bdrv_getlength = raw_getlength,
.bdrv_truncate = raw_truncate,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_discard = raw_discard,
.bdrv_is_inserted = raw_is_inserted,
.bdrv_media_changed = raw_media_changed,
.bdrv_eject = raw_eject,

View File

@ -705,7 +705,7 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
}
static int qemu_rbd_flush(BlockDriverState *bs)
static int qemu_rbd_co_flush(BlockDriverState *bs)
{
#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
/* rbd_flush added in 0.1.1 */
@ -851,7 +851,7 @@ static BlockDriver bdrv_rbd = {
.bdrv_file_open = qemu_rbd_open,
.bdrv_close = qemu_rbd_close,
.bdrv_create = qemu_rbd_create,
.bdrv_flush = qemu_rbd_flush,
.bdrv_co_flush = qemu_rbd_co_flush,
.bdrv_get_info = qemu_rbd_getinfo,
.create_options = qemu_rbd_create_options,
.bdrv_getlength = qemu_rbd_getlength,

View File

@ -396,7 +396,7 @@ static inline int free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
return !QLIST_EMPTY(&acb->aioreq_head);
}
static void sd_finish_aiocb(SheepdogAIOCB *acb)
static void coroutine_fn sd_finish_aiocb(SheepdogAIOCB *acb)
{
if (!acb->canceled) {
qemu_coroutine_enter(acb->coroutine, NULL);
@ -735,7 +735,7 @@ out:
return ret;
}
static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
struct iovec *iov, int niov, int create,
enum AIOCBState aiocb_type);
@ -743,7 +743,7 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
* This function searchs pending requests to the object `oid', and
* sends them.
*/
static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
{
AIOReq *aio_req, *next;
SheepdogAIOCB *acb;
@ -777,7 +777,7 @@ static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
* This function is registered as a fd handler, and called from the
* main loop when s->fd is ready for reading responses.
*/
static void aio_read_response(void *opaque)
static void coroutine_fn aio_read_response(void *opaque)
{
SheepdogObjRsp rsp;
BDRVSheepdogState *s = opaque;
@ -1064,7 +1064,7 @@ out:
return ret;
}
static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
struct iovec *iov, int niov, int create,
enum AIOCBState aiocb_type)
{
@ -1517,7 +1517,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
* update metadata, this sends a write request to the vdi object.
* Otherwise, this switches back to sd_co_readv/writev.
*/
static void sd_write_done(SheepdogAIOCB *acb)
static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
{
int ret;
BDRVSheepdogState *s = acb->common.bs->opaque;
@ -1615,7 +1615,7 @@ out:
* Returns 1 when we need to wait a response, 0 when there is no sent
* request and -errno in error cases.
*/
static int sd_co_rw_vector(void *p)
static int coroutine_fn sd_co_rw_vector(void *p)
{
SheepdogAIOCB *acb = p;
int ret = 0;

View File

@ -936,10 +936,10 @@ static void vdi_close(BlockDriverState *bs)
{
}
static int vdi_flush(BlockDriverState *bs)
static coroutine_fn int vdi_co_flush(BlockDriverState *bs)
{
logout("\n");
return bdrv_flush(bs->file);
return bdrv_co_flush(bs->file);
}
@ -975,7 +975,7 @@ static BlockDriver bdrv_vdi = {
.bdrv_open = vdi_open,
.bdrv_close = vdi_close,
.bdrv_create = vdi_create,
.bdrv_flush = vdi_flush,
.bdrv_co_flush = vdi_co_flush,
.bdrv_is_allocated = vdi_is_allocated,
.bdrv_make_empty = vdi_make_empty,

View File

@ -90,6 +90,7 @@ typedef struct VmdkExtent {
} VmdkExtent;
typedef struct BDRVVmdkState {
CoMutex lock;
int desc_offset;
bool cid_updated;
uint32_t parent_cid;
@ -283,10 +284,12 @@ static int vmdk_parent_open(BlockDriverState *bs)
char *p_name;
char desc[DESC_SIZE + 1];
BDRVVmdkState *s = bs->opaque;
int ret;
desc[DESC_SIZE] = '\0';
if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
return -1;
ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
if (ret < 0) {
return ret;
}
p_name = strstr(desc, "parentFileNameHint");
@ -296,10 +299,10 @@ static int vmdk_parent_open(BlockDriverState *bs)
p_name += sizeof("parentFileNameHint") + 1;
end_name = strchr(p_name, '\"');
if (end_name == NULL) {
return -1;
return -EINVAL;
}
if ((end_name - p_name) > sizeof(bs->backing_file) - 1) {
return -1;
return -EINVAL;
}
pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
@ -622,19 +625,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
return -ENOTSUP;
}
s->desc_offset = 0;
ret = vmdk_parse_extents(buf, bs, bs->file->filename);
if (ret) {
vmdk_free_extents(bs);
return ret;
}
/* try to open parent images, if exist */
if (vmdk_parent_open(bs)) {
vmdk_free_extents(bs);
return -EINVAL;
}
s->parent_cid = vmdk_read_cid(bs, 1);
return 0;
return vmdk_parse_extents(buf, bs, bs->file->filename);
}
static int vmdk_open(BlockDriverState *bs, int flags)
@ -644,17 +635,24 @@ static int vmdk_open(BlockDriverState *bs, int flags)
if (vmdk_open_sparse(bs, bs->file, flags) == 0) {
s->desc_offset = 0x200;
/* try to open parent images, if exist */
ret = vmdk_parent_open(bs);
if (ret) {
vmdk_free_extents(bs);
return ret;
}
s->parent_cid = vmdk_read_cid(bs, 1);
return 0;
} else {
return vmdk_open_desc_file(bs, flags, 0);
ret = vmdk_open_desc_file(bs, flags, 0);
if (ret) {
goto fail;
}
}
/* try to open parent images, if exist */
ret = vmdk_parent_open(bs);
if (ret) {
goto fail;
}
s->parent_cid = vmdk_read_cid(bs, 1);
qemu_co_mutex_init(&s->lock);
return ret;
fail:
vmdk_free_extents(bs);
return ret;
}
static int get_whole_cluster(BlockDriverState *bs,
@ -1026,6 +1024,17 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVVmdkState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = vmdk_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
@ -1107,6 +1116,17 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
int ret;
BDRVVmdkState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = vmdk_write(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static int vmdk_create_extent(const char *filename, int64_t filesize,
bool flat, bool compress)
@ -1474,14 +1494,14 @@ static void vmdk_close(BlockDriverState *bs)
vmdk_free_extents(bs);
}
static int vmdk_flush(BlockDriverState *bs)
static coroutine_fn int vmdk_co_flush(BlockDriverState *bs)
{
int i, ret, err;
BDRVVmdkState *s = bs->opaque;
ret = bdrv_flush(bs->file);
ret = bdrv_co_flush(bs->file);
for (i = 0; i < s->num_extents; i++) {
err = bdrv_flush(s->extents[i].file);
err = bdrv_co_flush(s->extents[i].file);
if (err < 0) {
ret = err;
}
@ -1544,11 +1564,11 @@ static BlockDriver bdrv_vmdk = {
.instance_size = sizeof(BDRVVmdkState),
.bdrv_probe = vmdk_probe,
.bdrv_open = vmdk_open,
.bdrv_read = vmdk_read,
.bdrv_write = vmdk_write,
.bdrv_read = vmdk_co_read,
.bdrv_write = vmdk_co_write,
.bdrv_close = vmdk_close,
.bdrv_create = vmdk_create,
.bdrv_flush = vmdk_flush,
.bdrv_co_flush = vmdk_co_flush,
.bdrv_is_allocated = vmdk_is_allocated,
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,

View File

@ -110,6 +110,7 @@ struct vhd_dyndisk_header {
};
typedef struct BDRVVPCState {
CoMutex lock;
uint8_t footer_buf[HEADER_SIZE];
uint64_t free_data_block_offset;
int max_table_entries;
@ -226,6 +227,7 @@ static int vpc_open(BlockDriverState *bs, int flags)
s->last_pagetable = -1;
#endif
qemu_co_mutex_init(&s->lock);
return 0;
fail:
return err;
@ -407,6 +409,17 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVVPCState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = vpc_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static int vpc_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
@ -443,9 +456,20 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
return 0;
}
static int vpc_flush(BlockDriverState *bs)
static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
return bdrv_flush(bs->file);
int ret;
BDRVVPCState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = vpc_write(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static coroutine_fn int vpc_co_flush(BlockDriverState *bs)
{
return bdrv_co_flush(bs->file);
}
/*
@ -639,9 +663,9 @@ static BlockDriver bdrv_vpc = {
.instance_size = sizeof(BDRVVPCState),
.bdrv_probe = vpc_probe,
.bdrv_open = vpc_open,
.bdrv_read = vpc_read,
.bdrv_write = vpc_write,
.bdrv_flush = vpc_flush,
.bdrv_read = vpc_co_read,
.bdrv_write = vpc_co_write,
.bdrv_co_flush = vpc_co_flush,
.bdrv_close = vpc_close,
.bdrv_create = vpc_create,

View File

@ -317,6 +317,7 @@ static void print_mapping(const struct mapping_t* mapping);
/* here begins the real VVFAT driver */
typedef struct BDRVVVFATState {
CoMutex lock;
BlockDriverState* bs; /* pointer to parent */
unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
unsigned char first_sectors[0x40*0x200];
@ -1065,6 +1066,7 @@ DLOG(if (stderr == NULL) {
bs->heads = bs->cyls = bs->secs = 0;
// assert(is_consistent(s));
qemu_co_mutex_init(&s->lock);
return 0;
}
@ -1279,6 +1281,17 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
return 0;
}
static coroutine_fn int vvfat_co_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int ret;
BDRVVVFATState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = vvfat_read(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
/* LATER TODO: statify all functions */
/*
@ -2714,6 +2727,17 @@ DLOG(checkpoint());
return 0;
}
static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
int ret;
BDRVVVFATState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock);
ret = vvfat_write(bs, sector_num, buf, nb_sectors);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static int vvfat_is_allocated(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, int* n)
{
@ -2803,8 +2827,8 @@ static BlockDriver bdrv_vvfat = {
.format_name = "vvfat",
.instance_size = sizeof(BDRVVVFATState),
.bdrv_file_open = vvfat_open,
.bdrv_read = vvfat_read,
.bdrv_write = vvfat_write,
.bdrv_read = vvfat_co_read,
.bdrv_write = vvfat_co_write,
.bdrv_close = vvfat_close,
.bdrv_is_allocated = vvfat_is_allocated,
.protocol_name = "fat",

View File

@ -62,7 +62,6 @@ struct BlockDriver {
const uint8_t *buf, int nb_sectors);
void (*bdrv_close)(BlockDriverState *bs);
int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
int (*bdrv_flush)(BlockDriverState *bs);
int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum);
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
@ -76,13 +75,17 @@ struct BlockDriver {
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
int nb_sectors);
BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque);
int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors);
int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs,
int num_reqs);

View File

@ -434,6 +434,7 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg)
FDCtrl *fdctrl = opaque;
uint32_t retval;
reg &= 7;
switch (reg) {
case FD_REG_SRA:
retval = fdctrl_read_statusA(fdctrl);
@ -471,6 +472,7 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
reg &= 7;
switch (reg) {
case FD_REG_DOR:
fdctrl_write_dor(fdctrl, value);
@ -1945,6 +1947,18 @@ static int sun4m_fdc_init1(SysBusDevice *dev)
return fdctrl_init_common(fdctrl);
}
void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev)
{
FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev);
FDCtrl *fdctrl = &isa->state;
int i;
for (i = 0; i < MAX_FD; i++) {
bs[i] = fdctrl->drives[i].bs;
}
}
static const VMStateDescription vmstate_isa_fdc ={
.name = "fdc",
.version_id = 2,

View File

@ -7,14 +7,15 @@
/* fdc.c */
#define MAX_FD 2
static inline void fdctrl_init_isa(DriveInfo **fds)
static inline ISADevice *fdctrl_init_isa(DriveInfo **fds)
{
ISADevice *dev;
dev = isa_try_create("isa-fdc");
if (!dev) {
return;
return NULL;
}
if (fds[0]) {
qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
}
@ -22,10 +23,14 @@ static inline void fdctrl_init_isa(DriveInfo **fds)
qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
}
qdev_init_nofail(&dev->qdev);
return dev;
}
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
target_phys_addr_t mmio_base, DriveInfo **fds);
void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
DriveInfo **fds, qemu_irq *fdc_tc);
void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev);
#endif

25
hw/pc.c
View File

@ -331,12 +331,12 @@ static void pc_cmos_init_late(void *opaque)
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
const char *boot_device,
BusState *idebus0, BusState *idebus1,
ISADevice *floppy, BusState *idebus0, BusState *idebus1,
ISADevice *s)
{
int val, nb, nb_heads, max_track, last_sect, i;
FDriveType fd_type[2];
DriveInfo *fd[2];
BlockDriverState *fd[MAX_FD];
static pc_cmos_init_late_arg arg;
/* various important CMOS locations needed by PC/Bochs bios */
@ -378,14 +378,16 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
}
/* floppy type */
for (i = 0; i < 2; i++) {
fd[i] = drive_get(IF_FLOPPY, 0, i);
if (fd[i] && bdrv_is_inserted(fd[i]->bdrv)) {
bdrv_get_floppy_geometry_hint(fd[i]->bdrv, &nb_heads, &max_track,
&last_sect, FDRIVE_DRV_NONE,
&fd_type[i]);
} else {
fd_type[i] = FDRIVE_DRV_NONE;
if (floppy) {
fdc_get_bs(fd, floppy);
for (i = 0; i < 2; i++) {
if (fd[i] && bdrv_is_inserted(fd[i])) {
bdrv_get_floppy_geometry_hint(fd[i], &nb_heads, &max_track,
&last_sect, FDRIVE_DRV_NONE,
&fd_type[i]);
} else {
fd_type[i] = FDRIVE_DRV_NONE;
}
}
}
val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |
@ -1124,6 +1126,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
void pc_basic_device_init(qemu_irq *gsi,
ISADevice **rtc_state,
ISADevice **floppy,
bool no_vmport)
{
int i;
@ -1188,7 +1191,7 @@ void pc_basic_device_init(qemu_irq *gsi,
for(i = 0; i < MAX_FD; i++) {
fd[i] = drive_get(IF_FLOPPY, 0, i);
}
fdctrl_init_isa(fd);
*floppy = fdctrl_init_isa(fd);
}
void pc_pci_device_init(PCIBus *pci_bus)

View File

@ -142,11 +142,12 @@ qemu_irq *pc_allocate_cpu_irq(void);
void pc_vga_init(PCIBus *pci_bus);
void pc_basic_device_init(qemu_irq *gsi,
ISADevice **rtc_state,
ISADevice **floppy,
bool no_vmport);
void pc_init_ne2k_isa(NICInfo *nd);
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
const char *boot_device,
BusState *ide0, BusState *ide1,
ISADevice *floppy, BusState *ide0, BusState *ide1,
ISADevice *s);
void pc_pci_device_init(PCIBus *pci_bus);

View File

@ -95,6 +95,7 @@ static void pc_init1(MemoryRegion *system_memory,
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
BusState *idebus[MAX_IDE_BUS];
ISADevice *rtc_state;
ISADevice *floppy;
MemoryRegion *ram_memory;
MemoryRegion *pci_memory;
MemoryRegion *rom_memory;
@ -174,7 +175,7 @@ static void pc_init1(MemoryRegion *system_memory,
}
/* init basic PC hardware */
pc_basic_device_init(gsi, &rtc_state, xen_enabled());
pc_basic_device_init(gsi, &rtc_state, &floppy, xen_enabled());
for(i = 0; i < nb_nics; i++) {
NICInfo *nd = &nd_table[i];
@ -207,7 +208,7 @@ static void pc_init1(MemoryRegion *system_memory,
audio_init(gsi, pci_enabled ? pci_bus : NULL);
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
idebus[0], idebus[1], rtc_state);
floppy, idebus[0], idebus[1], rtc_state);
if (pci_enabled && usb_enabled) {
usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);

View File

@ -620,7 +620,7 @@ static void blk_alloc(struct XenDevice *xendev)
static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
int index, qflags, have_barriers, info = 0;
int index, qflags, info = 0;
/* read xenstore entries */
if (blkdev->params == NULL) {
@ -706,7 +706,6 @@ static int blk_init(struct XenDevice *xendev)
blkdev->bs->drv ? blkdev->bs->drv->format_name : "-");
blkdev->file_size = 0;
}
have_barriers = blkdev->bs->drv && blkdev->bs->drv->bdrv_flush ? 1 : 0;
xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
" size %" PRId64 " (%" PRId64 " MB)\n",
@ -714,7 +713,7 @@ static int blk_init(struct XenDevice *xendev)
blkdev->file_size, blkdev->file_size >> 20);
/* fill info */
xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers);
xenstore_write_be_int(&blkdev->xendev, "feature-barrier", 1);
xenstore_write_be_int(&blkdev->xendev, "info", info);
xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk);
xenstore_write_be_int(&blkdev->xendev, "sectors",

View File

@ -103,6 +103,13 @@ void qemu_vfree(void *ptr)
free(ptr);
}
void socket_set_block(int fd)
{
int f;
f = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, f & ~O_NONBLOCK);
}
void socket_set_nonblock(int fd)
{
int f;

View File

@ -73,6 +73,12 @@ void qemu_vfree(void *ptr)
VirtualFree(ptr, 0, MEM_RELEASE);
}
void socket_set_block(int fd)
{
unsigned long opt = 0;
ioctlsocket(fd, FIONBIO, &opt);
}
void socket_set_nonblock(int fd)
{
unsigned long opt = 1;

View File

@ -824,6 +824,8 @@ static int img_convert(int argc, char **argv)
if (compress) {
QEMUOptionParameter *encryption =
get_option_parameter(param, BLOCK_OPT_ENCRYPT);
QEMUOptionParameter *preallocation =
get_option_parameter(param, BLOCK_OPT_PREALLOC);
if (!drv->bdrv_write_compressed) {
error_report("Compression not supported for this file format");
@ -837,6 +839,15 @@ static int img_convert(int argc, char **argv)
ret = -1;
goto out;
}
if (preallocation && preallocation->value.s
&& strcmp(preallocation->value.s, "off"))
{
error_report("Compression and preallocation not supported at "
"the same time");
ret = -1;
goto out;
}
}
/* Create the new image */

View File

@ -1248,6 +1248,7 @@ static int aio_write_f(int argc, char **argv)
case 'P':
pattern = parse_pattern(optarg);
if (pattern < 0) {
free(ctx);
return 0;
}
break;

View File

@ -35,6 +35,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
/* misc helpers */
int qemu_socket(int domain, int type, int protocol);
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
void socket_set_block(int fd);
void socket_set_nonblock(int fd);
int send_all(int fd, const void *buf, int len1);

View File

@ -61,6 +61,7 @@ multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"