Merge remote-tracking branch 'kwolf/for-anthony' into staging
This commit is contained in:
commit
e86d9b12b5
254
block.c
254
block.c
@ -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,
|
||||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
|
||||
{
|
||||
BlockDriverAIOCBSync *acb;
|
||||
BlockDriverAIOCBCoroutine *acb = opaque;
|
||||
BlockDriverState *bs = acb->common.bs;
|
||||
|
||||
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;
|
||||
|
||||
if (!acb->bh) {
|
||||
acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
|
||||
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);
|
||||
}
|
||||
|
||||
qemu_bh_schedule(acb->bh);
|
||||
BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
|
||||
int64_t sector_num, int nb_sectors,
|
||||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
Coroutine *co;
|
||||
BlockDriverAIOCBCoroutine *acb;
|
||||
|
||||
trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
|
||||
|
||||
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);
|
||||
|
||||
return &acb->common;
|
||||
}
|
||||
|
||||
@ -2916,20 +2864,132 @@ 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)
|
||||
{
|
||||
RwCo *rwco = opaque;
|
||||
|
||||
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(),
|
||||
};
|
||||
BlockDriverAIOCB *acb;
|
||||
|
||||
acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
|
||||
if (!acb) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/* removable device support */
|
||||
|
5
block.h
5
block.h
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
34
block/cow.c
34
block/cow.c
@ -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,
|
||||
|
15
block/dmg.c
15
block/dmg.c
@ -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,
|
||||
};
|
||||
|
||||
|
28
block/nbd.c
28
block/nbd.c
@ -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",
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
13
block/qcow.c
13
block/qcow.c
@ -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_flush = qcow_co_flush,
|
||||
.bdrv_write_compressed = qcow_write_compressed,
|
||||
.bdrv_get_info = qcow_get_info,
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
23
block/raw.c
23
block/raw.c
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
||||
|
78
block/vmdk.c
78
block/vmdk.c
@ -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;
|
||||
} else {
|
||||
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) {
|
||||
vmdk_free_extents(bs);
|
||||
return ret;
|
||||
goto fail;
|
||||
}
|
||||
s->parent_cid = vmdk_read_cid(bs, 1);
|
||||
return 0;
|
||||
} else {
|
||||
return vmdk_open_desc_file(bs, flags, 0);
|
||||
}
|
||||
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,
|
||||
|
||||
|
34
block/vpc.c
34
block/vpc.c
@ -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,
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
14
hw/fdc.c
14
hw/fdc.c
@ -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,
|
||||
|
9
hw/fdc.h
9
hw/fdc.h
@ -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
|
||||
|
15
hw/pc.c
15
hw/pc.c
@ -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,16 +378,18 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
|
||||
}
|
||||
|
||||
/* floppy type */
|
||||
if (floppy) {
|
||||
fdc_get_bs(fd, floppy);
|
||||
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,
|
||||
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) |
|
||||
cmos_get_fd_drive_type(fd_type[1]);
|
||||
rtc_set_memory(s, 0x10, val);
|
||||
@ -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)
|
||||
|
3
hw/pc.h
3
hw/pc.h
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
11
qemu-img.c
11
qemu-img.c
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user