Patchwork [v3,13/27] block: Drop medium lock tracking, ask device models instead

login
register
mail settings
Submitter Markus Armbruster
Date Sept. 6, 2011, 4:58 p.m.
Message ID <1315328340-6192-14-git-send-email-armbru@redhat.com>
Download mbox | patch
Permalink /patch/113617/
State New
Headers show

Comments

Markus Armbruster - Sept. 6, 2011, 4:58 p.m.
Requires new BlockDevOps member is_medium_locked().  Implement for IDE
and SCSI CD-ROMs.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c        |   16 +++++++++-------
 block.h        |    7 ++++++-
 block_int.h    |    1 -
 blockdev.c     |    2 +-
 hw/ide/core.c  |    6 ++++++
 hw/scsi-disk.c |   10 ++++++++++
 6 files changed, 32 insertions(+), 10 deletions(-)
Paolo Bonzini - Sept. 7, 2011, 7:06 a.m.
On 09/06/2011 06:58 PM, Markus Armbruster wrote:
> Requires new BlockDevOps member is_medium_locked().  Implement for IDE
> and SCSI CD-ROMs.
>
> Signed-off-by: Markus Armbruster<armbru@redhat.com>
> ---
>   block.c        |   16 +++++++++-------
>   block.h        |    7 ++++++-
>   block_int.h    |    1 -
>   blockdev.c     |    2 +-
>   hw/ide/core.c  |    6 ++++++
>   hw/scsi-disk.c |   10 ++++++++++
>   6 files changed, 32 insertions(+), 10 deletions(-)
>
> diff --git a/block.c b/block.c
> index 7408fa9..1e4be73 100644
> --- a/block.c
> +++ b/block.c
> @@ -818,6 +818,14 @@ static void bdrv_dev_resize_cb(BlockDriverState *bs)
>       }
>   }
>
> +bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
> +{
> +    if (bs->dev_ops&&  bs->dev_ops->is_medium_locked) {
> +        return bs->dev_ops->is_medium_locked(bs->dev_opaque);
> +    }
> +    return false;
> +}
> +
>   /*
>    * Run consistency checks on an image
>    *
> @@ -1890,7 +1898,7 @@ 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->locked);
> +                                    bdrv_dev_is_medium_locked(bs));
>
>           if (bs->drv) {
>               QObject *obj;
> @@ -3060,11 +3068,6 @@ void bdrv_eject(BlockDriverState *bs, int eject_flag)
>       }
>   }
>
> -int bdrv_is_locked(BlockDriverState *bs)
> -{
> -    return bs->locked;
> -}
> -
>   /**
>    * Lock or unlock the media (if it is locked, the user won't be able
>    * to eject it manually).
> @@ -3075,7 +3078,6 @@ void bdrv_set_locked(BlockDriverState *bs, int locked)
>
>       trace_bdrv_set_locked(bs, locked);
>
> -    bs->locked = locked;
>       if (drv&&  drv->bdrv_set_locked) {
>           drv->bdrv_set_locked(bs, locked);
>       }
> diff --git a/block.h b/block.h
> index 5d941e9..396ca0e 100644
> --- a/block.h
> +++ b/block.h
> @@ -37,6 +37,11 @@ typedef struct BlockDevOps {
>        */
>       void (*change_media_cb)(void *opaque);
>       /*
> +     * Is the virtual medium locked into the device?
> +     * Device models implement this only when device has such a lock.
> +     */
> +    bool (*is_medium_locked)(void *opaque);
> +    /*
>        * Runs when the size changed (e.g. monitor command block_resize)
>        */
>       void (*resize_cb)(void *opaque);
> @@ -94,6 +99,7 @@ void bdrv_detach_dev(BlockDriverState *bs, void *dev);
>   void *bdrv_get_attached_dev(BlockDriverState *bs);
>   void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
>                         void *opaque);
> +bool bdrv_dev_is_medium_locked(BlockDriverState *bs);
>   int bdrv_read(BlockDriverState *bs, int64_t sector_num,
>                 uint8_t *buf, int nb_sectors);
>   int bdrv_write(BlockDriverState *bs, int64_t sector_num,
> @@ -206,7 +212,6 @@ int bdrv_is_sg(BlockDriverState *bs);
>   int bdrv_enable_write_cache(BlockDriverState *bs);
>   int bdrv_is_inserted(BlockDriverState *bs);
>   int bdrv_media_changed(BlockDriverState *bs);
> -int bdrv_is_locked(BlockDriverState *bs);
>   void bdrv_set_locked(BlockDriverState *bs, int locked);
>   void bdrv_eject(BlockDriverState *bs, int eject_flag);
>   void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
> diff --git a/block_int.h b/block_int.h
> index b63c57b..4f7ff3b 100644
> --- a/block_int.h
> +++ b/block_int.h
> @@ -156,7 +156,6 @@ struct BlockDriverState {
>       int keep_read_only; /* if true, the media was requested to stay read only */
>       int open_flags; /* flags used to open the file, re-used for re-open */
>       int removable; /* if true, the media can be removed */
> -    int locked;    /* if true, the media cannot temporarily be ejected */
>       int encrypted; /* if true, the media is encrypted */
>       int valid_key; /* if true, a valid encryption key has been set */
>       int sg;        /* if true, the device is a /dev/sg* */
> diff --git a/blockdev.c b/blockdev.c
> index 049dda5..3f00b2e 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -640,7 +640,7 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
>           qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
>           return -1;
>       }
> -    if (!force&&  bdrv_is_locked(bs)) {
> +    if (!force&&  bdrv_dev_is_medium_locked(bs)) {
>           qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
>           return -1;
>       }
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index 34b7b83..b1a73ee 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -1795,8 +1795,14 @@ void ide_bus_reset(IDEBus *bus)
>       bus->dma->ops->reset(bus->dma);
>   }
>
> +static bool ide_cd_is_medium_locked(void *opaque)
> +{
> +    return ((IDEState *)opaque)->tray_locked;
> +}
> +
>   static const BlockDevOps ide_cd_block_ops = {
>       .change_media_cb = ide_cd_change_cb,
> +    .is_medium_locked = ide_cd_is_medium_locked,
>   };
>
>   int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
> diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
> index 65783a7..42682d0 100644
> --- a/hw/scsi-disk.c
> +++ b/hw/scsi-disk.c
> @@ -1165,6 +1165,15 @@ static void scsi_destroy(SCSIDevice *dev)
>       blockdev_mark_auto_del(s->qdev.conf.bs);
>   }
>
> +static bool scsi_cd_is_medium_locked(void *opaque)
> +{
> +    return ((SCSIDiskState *)opaque)->tray_locked;
> +}
> +
> +static const BlockDevOps scsi_cd_block_ops = {
> +    .is_medium_locked = scsi_cd_is_medium_locked,
> +};
> +
>   static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
>   {
>       SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
> @@ -1199,6 +1208,7 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
>       }
>
>       if (scsi_type == TYPE_ROM) {
> +        bdrv_set_dev_ops(s->bs,&scsi_cd_block_ops, s);
>           s->qdev.blocksize = 2048;
>       } else if (scsi_type == TYPE_DISK) {
>           s->qdev.blocksize = s->qdev.conf.logical_block_size;

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Patch

diff --git a/block.c b/block.c
index 7408fa9..1e4be73 100644
--- a/block.c
+++ b/block.c
@@ -818,6 +818,14 @@  static void bdrv_dev_resize_cb(BlockDriverState *bs)
     }
 }
 
+bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
+{
+    if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
+        return bs->dev_ops->is_medium_locked(bs->dev_opaque);
+    }
+    return false;
+}
+
 /*
  * Run consistency checks on an image
  *
@@ -1890,7 +1898,7 @@  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->locked);
+                                    bdrv_dev_is_medium_locked(bs));
 
         if (bs->drv) {
             QObject *obj;
@@ -3060,11 +3068,6 @@  void bdrv_eject(BlockDriverState *bs, int eject_flag)
     }
 }
 
-int bdrv_is_locked(BlockDriverState *bs)
-{
-    return bs->locked;
-}
-
 /**
  * Lock or unlock the media (if it is locked, the user won't be able
  * to eject it manually).
@@ -3075,7 +3078,6 @@  void bdrv_set_locked(BlockDriverState *bs, int locked)
 
     trace_bdrv_set_locked(bs, locked);
 
-    bs->locked = locked;
     if (drv && drv->bdrv_set_locked) {
         drv->bdrv_set_locked(bs, locked);
     }
diff --git a/block.h b/block.h
index 5d941e9..396ca0e 100644
--- a/block.h
+++ b/block.h
@@ -37,6 +37,11 @@  typedef struct BlockDevOps {
      */
     void (*change_media_cb)(void *opaque);
     /*
+     * Is the virtual medium locked into the device?
+     * Device models implement this only when device has such a lock.
+     */
+    bool (*is_medium_locked)(void *opaque);
+    /*
      * Runs when the size changed (e.g. monitor command block_resize)
      */
     void (*resize_cb)(void *opaque);
@@ -94,6 +99,7 @@  void bdrv_detach_dev(BlockDriverState *bs, void *dev);
 void *bdrv_get_attached_dev(BlockDriverState *bs);
 void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
                       void *opaque);
+bool bdrv_dev_is_medium_locked(BlockDriverState *bs);
 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors);
 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
@@ -206,7 +212,6 @@  int bdrv_is_sg(BlockDriverState *bs);
 int bdrv_enable_write_cache(BlockDriverState *bs);
 int bdrv_is_inserted(BlockDriverState *bs);
 int bdrv_media_changed(BlockDriverState *bs);
-int bdrv_is_locked(BlockDriverState *bs);
 void bdrv_set_locked(BlockDriverState *bs, int locked);
 void bdrv_eject(BlockDriverState *bs, int eject_flag);
 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
diff --git a/block_int.h b/block_int.h
index b63c57b..4f7ff3b 100644
--- a/block_int.h
+++ b/block_int.h
@@ -156,7 +156,6 @@  struct BlockDriverState {
     int keep_read_only; /* if true, the media was requested to stay read only */
     int open_flags; /* flags used to open the file, re-used for re-open */
     int removable; /* if true, the media can be removed */
-    int locked;    /* if true, the media cannot temporarily be ejected */
     int encrypted; /* if true, the media is encrypted */
     int valid_key; /* if true, a valid encryption key has been set */
     int sg;        /* if true, the device is a /dev/sg* */
diff --git a/blockdev.c b/blockdev.c
index 049dda5..3f00b2e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -640,7 +640,7 @@  static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
         qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
         return -1;
     }
-    if (!force && bdrv_is_locked(bs)) {
+    if (!force && bdrv_dev_is_medium_locked(bs)) {
         qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
         return -1;
     }
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 34b7b83..b1a73ee 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1795,8 +1795,14 @@  void ide_bus_reset(IDEBus *bus)
     bus->dma->ops->reset(bus->dma);
 }
 
+static bool ide_cd_is_medium_locked(void *opaque)
+{
+    return ((IDEState *)opaque)->tray_locked;
+}
+
 static const BlockDevOps ide_cd_block_ops = {
     .change_media_cb = ide_cd_change_cb,
+    .is_medium_locked = ide_cd_is_medium_locked,
 };
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 65783a7..42682d0 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1165,6 +1165,15 @@  static void scsi_destroy(SCSIDevice *dev)
     blockdev_mark_auto_del(s->qdev.conf.bs);
 }
 
+static bool scsi_cd_is_medium_locked(void *opaque)
+{
+    return ((SCSIDiskState *)opaque)->tray_locked;
+}
+
+static const BlockDevOps scsi_cd_block_ops = {
+    .is_medium_locked = scsi_cd_is_medium_locked,
+};
+
 static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
@@ -1199,6 +1208,7 @@  static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
     }
 
     if (scsi_type == TYPE_ROM) {
+        bdrv_set_dev_ops(s->bs, &scsi_cd_block_ops, s);
         s->qdev.blocksize = 2048;
     } else if (scsi_type == TYPE_DISK) {
         s->qdev.blocksize = s->qdev.conf.logical_block_size;