/* call the change callback */
bs->media_changed = 1;
if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
+ bs->change_cb(bs->change_opaque, CHANGE_MEDIA);
}
return 0;
/* call the change callback */
bs->media_changed = 1;
if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
+ bs->change_cb(bs->change_opaque, CHANGE_MEDIA);
}
}
}
}
+/* make a BlockDriverState anonymous by removing from bdrv_state list.
+ Also, NULL terminate the device_name to prevent double remove */
+void bdrv_make_anon(BlockDriverState *bs)
+{
+ if (bs->device_name[0] != '\0') {
+ QTAILQ_REMOVE(&bdrv_states, bs, list);
+ }
+ bs->device_name[0] = '\0';
+}
+
void bdrv_delete(BlockDriverState *bs)
{
assert(!bs->peer);
/* remove from list, if necessary */
- if (bs->device_name[0] != '\0') {
- QTAILQ_REMOVE(&bdrv_states, bs, list);
- }
+ bdrv_make_anon(bs);
bdrv_close(bs);
if (bs->file != NULL) {
return -ENOTSUP;
if (bs->read_only)
return -EACCES;
+ if (bdrv_in_use(bs))
+ return -EBUSY;
ret = drv->bdrv_truncate(bs, offset);
if (ret == 0) {
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
+ if (bs->change_cb) {
+ bs->change_cb(bs->change_opaque, CHANGE_SIZE);
+ }
}
return ret;
}
/* XXX: no longer used */
void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque)
+ void (*change_cb)(void *opaque, int reason),
+ void *opaque)
{
bs->change_cb = change_cb;
bs->change_opaque = opaque;
/* call the change callback now, we skipped it on open */
bs->media_changed = 1;
if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
+ bs->change_cb(bs->change_opaque, CHANGE_MEDIA);
}
return ret;
}
MultiwriteCB *mcb;
int i;
+ /* don't submit writes if we don't have a medium */
+ if (bs->drv == NULL) {
+ for (i = 0; i < num_reqs; i++) {
+ reqs[i].error = -ENOMEDIUM;
+ }
+ return -1;
+ }
+
if (num_reqs == 0) {
return 0;
}
return bs->dirty_count;
}
+void bdrv_set_in_use(BlockDriverState *bs, int in_use)
+{
+ assert(bs->in_use != in_use);
+ bs->in_use = in_use;
+}
+
+int bdrv_in_use(BlockDriverState *bs)
+{
+ return bs->in_use;
+}
+
int bdrv_img_create(const char *filename, const char *fmt,
const char *base_filename, const char *base_fmt,
char *options, uint64_t img_size, int flags)
QEMUOptionParameter *backing_fmt, *backing_file;
BlockDriverState *bs = NULL;
BlockDriver *drv, *proto_drv;
+ BlockDriver *backing_drv = NULL;
int ret = 0;
/* Find driver and parse its options */
backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
if (backing_fmt && backing_fmt->value.s) {
- if (!bdrv_find_format(backing_fmt->value.s)) {
+ backing_drv = bdrv_find_format(backing_fmt->value.s);
+ if (!backing_drv) {
error_report("Unknown backing file format '%s'",
backing_fmt->value.s);
ret = -EINVAL;
if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {
if (backing_file && backing_file->value.s) {
uint64_t size;
- const char *fmt = NULL;
char buf[32];
- if (backing_fmt && backing_fmt->value.s) {
- fmt = backing_fmt->value.s;
- }
-
bs = bdrv_new("");
- ret = bdrv_open(bs, backing_file->value.s, flags, drv);
+ ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
if (ret < 0) {
- error_report("Could not open '%s'", filename);
+ error_report("Could not open '%s'", backing_file->value.s);
goto out;
}
bdrv_get_geometry(bs, &size);