#define FTYPE_CD 1
#define FTYPE_HARDDISK 2
-static QEMUWin32AIOState *aio;
-
typedef struct RawWin32AIOData {
BlockDriverState *bs;
HANDLE hfile;
return ret;
}
-static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
+static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque, int type)
+ BlockCompletionFunc *cb, void *opaque, int type)
{
RawWin32AIOData *acb = g_slice_new(RawWin32AIOData);
ThreadPool *pool;
NULL, 0, NULL, 0, &returned, NULL);
}
+static void raw_detach_aio_context(BlockDriverState *bs)
+{
+ BDRVRawState *s = bs->opaque;
+
+ if (s->aio) {
+ win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
+ }
+}
+
+static void raw_attach_aio_context(BlockDriverState *bs,
+ AioContext *new_context)
+{
+ BDRVRawState *s = bs->opaque;
+
+ if (s->aio) {
+ win32_aio_attach_aio_context(s->aio, new_context);
+ }
+}
+
static void raw_probe_alignment(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
}
}
+static void raw_parse_filename(const char *filename, QDict *options,
+ Error **errp)
+{
+ /* The filename does not have to be prefixed by the protocol name, since
+ * "file" is the default protocol; therefore, the return value of this
+ * function call can be ignored. */
+ strstart(filename, "file:", &filename);
+
+ qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
+}
+
static QemuOptsList raw_runtime_opts = {
.name = "raw",
.head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head),
opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
raw_parse_flags(flags, &access_flags, &overlapped);
- if ((flags & BDRV_O_NATIVE_AIO) && aio == NULL) {
- aio = win32_aio_init();
- if (aio == NULL) {
- error_setg(errp, "Could not initialize AIO");
- ret = -EINVAL;
- goto fail;
- }
- }
-
if (filename[0] && filename[1] == ':') {
snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", filename[0]);
} else if (filename[0] == '\\' && filename[1] == '\\') {
}
if (flags & BDRV_O_NATIVE_AIO) {
- ret = win32_aio_attach(aio, s->hfile);
+ s->aio = win32_aio_init();
+ if (s->aio == NULL) {
+ CloseHandle(s->hfile);
+ error_setg(errp, "Could not initialize AIO");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = win32_aio_attach(s->aio, s->hfile);
if (ret < 0) {
+ win32_aio_cleanup(s->aio);
CloseHandle(s->hfile);
error_setg_errno(errp, -ret, "Could not enable AIO");
goto fail;
}
- s->aio = aio;
+
+ win32_aio_attach_aio_context(s->aio, bdrv_get_aio_context(bs));
}
raw_probe_alignment(bs);
return ret;
}
-static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
+static BlockAIOCB *raw_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
+ BlockCompletionFunc *cb, void *opaque)
{
BDRVRawState *s = bs->opaque;
if (s->aio) {
}
}
-static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
+static BlockAIOCB *raw_aio_writev(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
+ BlockCompletionFunc *cb, void *opaque)
{
BDRVRawState *s = bs->opaque;
if (s->aio) {
}
}
-static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
+static BlockAIOCB *raw_aio_flush(BlockDriverState *bs,
+ BlockCompletionFunc *cb, void *opaque)
{
BDRVRawState *s = bs->opaque;
return paio_submit(bs, s->hfile, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
static void raw_close(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
+
+ if (s->aio) {
+ win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
+ win32_aio_cleanup(s->aio);
+ s->aio = NULL;
+ }
+
CloseHandle(s->hfile);
+ if (bs->open_flags & BDRV_O_TEMPORARY) {
+ unlink(bs->filename);
+ }
}
static int raw_truncate(BlockDriverState *bs, int64_t offset)
return st.st_size;
}
-static int raw_create(const char *filename, QEMUOptionParameter *options,
- Error **errp)
+static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
{
int fd;
int64_t total_size = 0;
+ strstart(filename, "file:", &filename);
+
/* Read out options */
- while (options && options->name) {
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
- total_size = options->value.n / 512;
- }
- options++;
- }
+ total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+ BDRV_SECTOR_SIZE);
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
return -EIO;
}
set_sparse(fd);
- ftruncate(fd, total_size * 512);
+ ftruncate(fd, total_size);
qemu_close(fd);
return 0;
}
-static QEMUOptionParameter raw_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
- },
- { NULL }
+
+static QemuOptsList raw_create_opts = {
+ .name = "raw-create-opts",
+ .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
+ .desc = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Virtual disk size"
+ },
+ { /* end of list */ }
+ }
};
-static BlockDriver bdrv_file = {
+BlockDriver bdrv_file = {
.format_name = "file",
.protocol_name = "file",
.instance_size = sizeof(BDRVRawState),
.bdrv_needs_filename = true,
- .bdrv_file_open = raw_open,
- .bdrv_close = raw_close,
- .bdrv_create = raw_create,
+ .bdrv_parse_filename = raw_parse_filename,
+ .bdrv_file_open = raw_open,
+ .bdrv_close = raw_close,
+ .bdrv_create = raw_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
- .create_options = raw_create_options,
+ .create_opts = &raw_create_opts,
};
/***********************************************/
return 0;
}
+static void hdev_parse_filename(const char *filename, QDict *options,
+ Error **errp)
+{
+ /* The prefix is optional, just as for "file". */
+ strstart(filename, "host_device:", &filename);
+
+ qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
+}
+
static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
QemuOpts *opts = qemu_opts_create(&raw_runtime_opts, NULL, 0,
&error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto done;
.protocol_name = "host_device",
.instance_size = sizeof(BDRVRawState),
.bdrv_needs_filename = true,
+ .bdrv_parse_filename = hdev_parse_filename,
.bdrv_probe_device = hdev_probe_device,
.bdrv_file_open = hdev_open,
.bdrv_close = raw_close,
.bdrv_aio_writev = raw_aio_writev,
.bdrv_aio_flush = raw_aio_flush,
+ .bdrv_detach_aio_context = raw_detach_aio_context,
+ .bdrv_attach_aio_context = raw_attach_aio_context,
+
.bdrv_getlength = raw_getlength,
.has_variable_length = true,