mirror of https://gitee.com/openkylin/qemu.git
Merge remote-tracking branch 'kwolf/for-anthony' into staging
* kwolf/for-anthony: fdc: simplify media change handling qcow2: lock on prealloc block: make bdrv_create adopt coroutine qcow2: Limit COW to where it's needed sheepdog: switch to writethrough mode if cluster doesn't support flush
This commit is contained in:
commit
7c652c1eaf
46
block.c
46
block.c
|
@ -341,13 +341,53 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
|
||||||
return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
|
return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct CreateCo {
|
||||||
|
BlockDriver *drv;
|
||||||
|
char *filename;
|
||||||
|
QEMUOptionParameter *options;
|
||||||
|
int ret;
|
||||||
|
} CreateCo;
|
||||||
|
|
||||||
|
static void coroutine_fn bdrv_create_co_entry(void *opaque)
|
||||||
|
{
|
||||||
|
CreateCo *cco = opaque;
|
||||||
|
assert(cco->drv);
|
||||||
|
|
||||||
|
cco->ret = cco->drv->bdrv_create(cco->filename, cco->options);
|
||||||
|
}
|
||||||
|
|
||||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
int bdrv_create(BlockDriver *drv, const char* filename,
|
||||||
QEMUOptionParameter *options)
|
QEMUOptionParameter *options)
|
||||||
{
|
{
|
||||||
if (!drv->bdrv_create)
|
int ret;
|
||||||
return -ENOTSUP;
|
|
||||||
|
|
||||||
return drv->bdrv_create(filename, options);
|
Coroutine *co;
|
||||||
|
CreateCo cco = {
|
||||||
|
.drv = drv,
|
||||||
|
.filename = g_strdup(filename),
|
||||||
|
.options = options,
|
||||||
|
.ret = NOT_DONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!drv->bdrv_create) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemu_in_coroutine()) {
|
||||||
|
/* Fast-path if already in coroutine context */
|
||||||
|
bdrv_create_co_entry(&cco);
|
||||||
|
} else {
|
||||||
|
co = qemu_coroutine_create(bdrv_create_co_entry);
|
||||||
|
qemu_coroutine_enter(co, &cco);
|
||||||
|
while (cco.ret == NOT_DONE) {
|
||||||
|
qemu_aio_wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cco.ret;
|
||||||
|
g_free(cco.filename);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
|
int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
|
||||||
|
|
|
@ -883,17 +883,21 @@ again:
|
||||||
assert(keep_clusters <= nb_clusters);
|
assert(keep_clusters <= nb_clusters);
|
||||||
nb_clusters -= keep_clusters;
|
nb_clusters -= keep_clusters;
|
||||||
} else {
|
} else {
|
||||||
/* For the moment, overwrite compressed clusters one by one */
|
|
||||||
if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
|
|
||||||
nb_clusters = 1;
|
|
||||||
} else {
|
|
||||||
nb_clusters = count_cow_clusters(s, nb_clusters, l2_table, l2_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
keep_clusters = 0;
|
keep_clusters = 0;
|
||||||
cluster_offset = 0;
|
cluster_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nb_clusters > 0) {
|
||||||
|
/* For the moment, overwrite compressed clusters one by one */
|
||||||
|
uint64_t entry = be64_to_cpu(l2_table[l2_index + keep_clusters]);
|
||||||
|
if (entry & QCOW_OFLAG_COMPRESSED) {
|
||||||
|
nb_clusters = 1;
|
||||||
|
} else {
|
||||||
|
nb_clusters = count_cow_clusters(s, nb_clusters, l2_table,
|
||||||
|
l2_index + keep_clusters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cluster_offset &= L2E_OFFSET_MASK;
|
cluster_offset &= L2E_OFFSET_MASK;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1192,7 +1192,10 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
||||||
|
|
||||||
/* And if we're supposed to preallocate metadata, do that now */
|
/* And if we're supposed to preallocate metadata, do that now */
|
||||||
if (prealloc) {
|
if (prealloc) {
|
||||||
|
BDRVQcowState *s = bs->opaque;
|
||||||
|
qemu_co_mutex_lock(&s->lock);
|
||||||
ret = preallocate(bs);
|
ret = preallocate(bs);
|
||||||
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1678,6 +1678,14 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rsp->result == SD_RES_INVALID_PARMS) {
|
||||||
|
dprintf("disable write cache since the server doesn't support it\n");
|
||||||
|
|
||||||
|
s->cache_enabled = 0;
|
||||||
|
closesocket(s->flush_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (rsp->result != SD_RES_SUCCESS) {
|
if (rsp->result != SD_RES_SUCCESS) {
|
||||||
error_report("%s", sd_strerror(rsp->result));
|
error_report("%s", sd_strerror(rsp->result));
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
29
hw/fdc.c
29
hw/fdc.c
|
@ -705,6 +705,15 @@ static void fdctrl_raise_irq(FDCtrl *fdctrl, uint8_t status0)
|
||||||
qemu_set_irq(fdctrl->irq, 1);
|
qemu_set_irq(fdctrl->irq, 1);
|
||||||
fdctrl->sra |= FD_SRA_INTPEND;
|
fdctrl->sra |= FD_SRA_INTPEND;
|
||||||
}
|
}
|
||||||
|
if (status0 & FD_SR0_SEEK) {
|
||||||
|
FDrive *cur_drv;
|
||||||
|
/* A seek clears the disk change line (if a disk is inserted) */
|
||||||
|
cur_drv = get_cur_drv(fdctrl);
|
||||||
|
if (cur_drv->max_track) {
|
||||||
|
cur_drv->media_changed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fdctrl->reset_sensei = 0;
|
fdctrl->reset_sensei = 0;
|
||||||
fdctrl->status0 = status0;
|
fdctrl->status0 = status0;
|
||||||
FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
|
FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
|
||||||
|
@ -936,23 +945,7 @@ static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
|
||||||
|
|
||||||
static int fdctrl_media_changed(FDrive *drv)
|
static int fdctrl_media_changed(FDrive *drv)
|
||||||
{
|
{
|
||||||
int ret;
|
return drv->media_changed;
|
||||||
|
|
||||||
if (!drv->bs)
|
|
||||||
return 0;
|
|
||||||
if (drv->media_changed) {
|
|
||||||
drv->media_changed = 0;
|
|
||||||
ret = 1;
|
|
||||||
} else {
|
|
||||||
ret = bdrv_media_changed(drv->bs);
|
|
||||||
if (ret < 0) {
|
|
||||||
ret = 0; /* we don't know, assume no */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret) {
|
|
||||||
fd_revalidate(drv);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Digital input register : 0x07 (read-only) */
|
/* Digital input register : 0x07 (read-only) */
|
||||||
|
@ -1856,6 +1849,7 @@ static void fdctrl_change_cb(void *opaque, bool load)
|
||||||
FDrive *drive = opaque;
|
FDrive *drive = opaque;
|
||||||
|
|
||||||
drive->media_changed = 1;
|
drive->media_changed = 1;
|
||||||
|
fd_revalidate(drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const BlockDevOps fdctrl_block_ops = {
|
static const BlockDevOps fdctrl_block_ops = {
|
||||||
|
@ -1886,7 +1880,6 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl)
|
||||||
fd_init(drive);
|
fd_init(drive);
|
||||||
fd_revalidate(drive);
|
fd_revalidate(drive);
|
||||||
if (drive->bs) {
|
if (drive->bs) {
|
||||||
drive->media_changed = 1;
|
|
||||||
bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive);
|
bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue