aboutsummaryrefslogtreecommitdiff
path: root/block.c
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2011-09-06 18:58:51 +0200
committerKevin Wolf <kwolf@redhat.com>2011-09-12 15:17:21 +0200
commit2c6942fa7b332a95286071b92d233853e1000948 (patch)
tree0f113bddd757393477efd4e2c9c05f252c229f2d /block.c
parentdb118fe725b92a8271ff7d17f1d932104965bdb0 (diff)
block: Clean up remaining users of "removable"
BlockDriverState member removable is a confused mess. It is true when an ide-cd, scsi-cd or floppy qdev is attached, or when the BlockDriverState was created with -drive if={floppy,sd} or -drive if={ide,scsi,xen,none},media=cdrom ("created removable"), except when an ide-hd, scsi-hd, scsi-generic or virtio-blk qdev is attached. Three users remain: 1. eject_device(), via bdrv_is_removable() uses it to determine whether a block device can eject media. 2. bdrv_info() is monitor command "info block". QMP documentation says "true if the device is removable, false otherwise". From the monitor user's point of view, the only sensible interpretation of "is removable" is "can eject media with monitor commands eject and change". A block device can eject media unless a device is attached that doesn't support it. Switch the two users over to new bdrv_dev_has_removable_media() that returns exactly that. 3. bdrv_getlength() uses to suppress its length cache when media can change (see commit 46a4e4e6). Media change is either monitor command change (updates the length cache), monitor command eject (doesn't update the length cache, easily fixable), or physical media change (invalidates length cache, not so easily fixable). I'm refraining from improving anything here, because this series is long enough already. Instead, I simply switch it over to bdrv_dev_has_removable_media() as well. This changes the behavior of the length cache and of monitor commands eject and change in two cases: a. drive not created removable, no device attached The commit makes the drive removable, and defeats the length cache. Example: -drive if=none b. drive created removable, but the attached drive is non-removable, and doesn't call bdrv_set_removable(..., 0) (most devices don't) The commit makes the drive non-removable, and enables the length cache. Example: -drive if=xen,media=cdrom -M xenpv The other non-removable devices that don't call bdrv_set_removable() can't currently use a drive created removable, either because they aren't qdevified, or because they lack a drive property. Won't stay that way. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/block.c b/block.c
index 7225b15bdf..fee45bfbf4 100644
--- a/block.c
+++ b/block.c
@@ -802,6 +802,9 @@ void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
{
bs->dev_ops = ops;
bs->dev_opaque = opaque;
+ if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
+ bs_snapshots = NULL;
+ }
}
static void bdrv_dev_change_media_cb(BlockDriverState *bs)
@@ -811,6 +814,11 @@ static void bdrv_dev_change_media_cb(BlockDriverState *bs)
}
}
+bool bdrv_dev_has_removable_media(BlockDriverState *bs)
+{
+ return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
+}
+
static void bdrv_dev_resize_cb(BlockDriverState *bs)
{
if (bs->dev_ops && bs->dev_ops->resize_cb) {
@@ -1329,7 +1337,7 @@ int64_t bdrv_getlength(BlockDriverState *bs)
if (!drv)
return -ENOMEDIUM;
- if (bs->growable || bs->removable) {
+ if (bs->growable || bdrv_dev_has_removable_media(bs)) {
if (drv->bdrv_getlength) {
return drv->bdrv_getlength(bs);
}
@@ -1614,11 +1622,6 @@ void bdrv_set_removable(BlockDriverState *bs, int removable)
}
}
-int bdrv_is_removable(BlockDriverState *bs)
-{
- return bs->removable;
-}
-
int bdrv_is_read_only(BlockDriverState *bs)
{
return bs->read_only;
@@ -1897,7 +1900,8 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
"'removable': %i, 'locked': %i }",
- bs->device_name, bs->removable,
+ bs->device_name,
+ bdrv_dev_has_removable_media(bs),
bdrv_dev_is_medium_locked(bs));
if (bs->drv) {