SCSI: Add disk reset handler
PATCH 1/1 SCSI: Add disk reset handler
Ensure that pending requests of an SCSI disk are purged on system reset and also restore max_lba. The latter is now only present in the reset handler as that one is already automatically called during init.
Signed-off-by Jan Kiszka <[email protected]>
--- hw/scsi-disk.c | 32 ++++++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 8 deletions(-)
This should be applied to stable as well. I can provide a corresponding patch once this one is acceptable.
hw/scsi-disk.c +24 -8
@@ -1010,22 +1010,42 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, } } -static void scsi_destroy (SCSIDevice *dev) +static void scsi_disk_purge_requests (SCSIDiskState *s) { -SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev, dev);SCSIDiskReq *r;while (!QTAILQ_EMPTY (&s->qdev.requests)) { r =DO_UPCAST (SCSIDiskReq, req,QTAILQ_FIRST (&s->qdev.requests));scsi_remove_request (r); } +} + +static void scsi_disk_reset (DeviceState *dev) +{ +SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev.qdev, dev); +uint64_t nb_sectors; + +scsi_disk_purge_requests (s); + +bdrv_get_geometry (s->bs, &nb_sectors); + nb_sectors /= s->cluster_size; +if (nb_sectors) { + nb_sectors--; + } + s->max_lba = nb_sectors; +} + +static void scsi_destroy (SCSIDevice *dev) +{ +SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev, dev); + +scsi_disk_purge_requests (s);drive_uninit (s->qdev.conf.dinfo); }static int scsi_disk_initfn (SCSIDevice *dev) {SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev, dev); -uint64_t nb_sectors;if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {error_report ("scsi-disk: drive property not set" );
@@ -1046,11 +1066,6 @@ static int scsi_disk_initfn(SCSIDevice *dev) s->cluster_size = s->qdev.blocksize /512 ; s->qdev.type =TYPE_DISK ; -bdrv_get_geometry (s->bs, &nb_sectors); - nb_sectors /= s->cluster_size; -if (nb_sectors) - nb_sectors--; - s->max_lba = nb_sectors;qemu_add_vm_change_state_handler (scsi_dma_restart_cb, s);return 0 ; }
@@ -1059,6 +1074,7 @@ static SCSIDeviceInfo scsi_disk_info = { .qdev.name = "scsi-disk", .qdev.desc = "virtual scsi disk or cdrom", .qdev.size = sizeof(SCSIDiskState), + .qdev.reset = scsi_disk_reset, .init = scsi_disk_initfn, .destroy = scsi_destroy, .send_command = scsi_send_command,
PATCH v2 1/1 SCSI: Add disk reset handler
Ensure that pending requests of an SCSI disk are purged on system reset and also restore max_lba. The latter is no only present in the reset handler as that one is called after init as well.
Signed-off-by Jan Kiszka <[email protected]>
---
Changes in v2:
- cancel associated aio requests as well
hw/scsi-disk.c | 35 +++++++++++++++++++++++++++-------- 1 files changed, 27 insertions(+), 8 deletions(-)
hw/scsi-disk.c +27 -8
@@ -1010,22 +1010,45 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, } } -static void scsi_destroy (SCSIDevice *dev) +static void scsi_disk_purge_requests (SCSIDiskState *s) { -SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev, dev);SCSIDiskReq *r;while (!QTAILQ_EMPTY (&s->qdev.requests)) { r =DO_UPCAST (SCSIDiskReq, req,QTAILQ_FIRST (&s->qdev.requests)); +if (r->req.aiocb) { +bdrv_aio_cancel (r->req.aiocb); + }scsi_remove_request (r); } +} + +static void scsi_disk_reset (DeviceState *dev) +{ +SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev.qdev, dev); +uint64_t nb_sectors; + +scsi_disk_purge_requests (s); + +bdrv_get_geometry (s->bs, &nb_sectors); + nb_sectors /= s->cluster_size; +if (nb_sectors) { + nb_sectors--; + } + s->max_lba = nb_sectors; +} + +static void scsi_destroy (SCSIDevice *dev) +{ +SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev, dev); + +scsi_disk_purge_requests (s);drive_uninit (s->qdev.conf.dinfo); }static int scsi_disk_initfn (SCSIDevice *dev) {SCSIDiskState *s =DO_UPCAST (SCSIDiskState, qdev, dev); -uint64_t nb_sectors;if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {error_report ("scsi-disk: drive property not set" );
@@ -1046,11 +1069,6 @@ static int scsi_disk_initfn(SCSIDevice *dev) s->cluster_size = s->qdev.blocksize /512 ; s->qdev.type =TYPE_DISK ; -bdrv_get_geometry (s->bs, &nb_sectors); - nb_sectors /= s->cluster_size; -if (nb_sectors) - nb_sectors--; - s->max_lba = nb_sectors;qemu_add_vm_change_state_handler (scsi_dma_restart_cb, s);return 0 ; }
@@ -1059,6 +1077,7 @@ static SCSIDeviceInfo scsi_disk_info = { .qdev.name = "scsi-disk", .qdev.desc = "virtual scsi disk or cdrom", .qdev.size = sizeof(SCSIDiskState), + .qdev.reset = scsi_disk_reset, .init = scsi_disk_initfn, .destroy = scsi_destroy, .send_command = scsi_send_command,