diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-10-12 22:48:45 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-10-12 22:48:45 +0100 |
| commit | 724c1c8bb350d84c097ab2005aad15e125d06b6c (patch) | |
| tree | b55ff4dc3e8012e2624d2aa2d1211684bd425656 /hw/scsi/virtio-scsi.c | |
| parent | a0bdf866873467271eff9a92f179ab0f77d735cb (diff) | |
| parent | a0c9162c8250e121af438aee5ef93e64ec62dae1 (diff) | |
| download | focaccia-qemu-724c1c8bb350d84c097ab2005aad15e125d06b6c.tar.gz focaccia-qemu-724c1c8bb350d84c097ab2005aad15e125d06b6c.zip | |
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* qtest documentation improvements (Eduardo, myself) * libqtest event buffering (Maxim) * use RCU for list of children of a bus (Maxim) * move more files to softmmu/ (myself) * meson.build cleanups, qemu-storage-daemon fix (Philippe) # gpg: Signature made Mon 12 Oct 2020 16:55:19 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini-gitlab/tags/for-upstream: (38 commits) meson: identify more sections of meson.build scsi/scsi_bus: fix races in REPORT LUNS virtio-scsi: use scsi_device_get scsi/scsi_bus: Add scsi_device_get scsi/scsi-bus: scsi_device_find: don't return unrealized devices device-core: use atomic_set on .realized property scsi: switch to bus->check_address device-core: use RCU for list of children of a bus device_core: use drain_call_rcu in in qmp_device_add scsi/scsi_bus: switch search direction in scsi_device_find qdev: add "check if address free" callback for buses qemu-iotests, qtest: rewrite test 067 as a qtest qtest: check that drives are really appearing and disappearing qtest: switch users back to qtest_qmp_receive device-plug-test: use qtest_qmp to send the device_del command qtest: remove qtest_qmp_receive_success qtest: Reintroduce qtest_qmp_receive with QMP event buffering qtest: rename qtest_qmp_receive to qtest_qmp_receive_dict meson.build: Re-enable KVM support for MIPS build-sys: fix git version from -version ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/scsi/virtio-scsi.c')
| -rw-r--r-- | hw/scsi/virtio-scsi.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 3a71ea7097..3db9a8aae9 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -33,7 +33,7 @@ static inline int virtio_scsi_get_lun(uint8_t *lun) return ((lun[2] << 8) | lun[3]) & 0x3FFF; } -static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) +static inline SCSIDevice *virtio_scsi_device_get(VirtIOSCSI *s, uint8_t *lun) { if (lun[0] != 1) { return NULL; @@ -41,7 +41,7 @@ static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) { return NULL; } - return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); + return scsi_device_get(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); } void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req) @@ -256,7 +256,7 @@ static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d) * case of async cancellation. */ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) { - SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf.lun); + SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun); SCSIRequest *r, *next; BusChild *kid; int target; @@ -367,12 +367,16 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: target = req->req.tmf.lun[1]; s->resetting++; - QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { - d = SCSI_DEVICE(kid->child); - if (d->channel == 0 && d->id == target) { - qdev_reset_all(&d->qdev); - } + + rcu_read_lock(); + QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) { + SCSIDevice *d1 = SCSI_DEVICE(kid->child); + if (d1->channel == 0 && d1->id == target) { + qdev_reset_all(&d1->qdev); + } } + rcu_read_unlock(); + s->resetting--; break; @@ -382,14 +386,17 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) break; } + object_unref(OBJECT(d)); return ret; incorrect_lun: req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN; + object_unref(OBJECT(d)); return ret; fail: req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET; + object_unref(OBJECT(d)); return ret; } @@ -560,7 +567,7 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) } } - d = virtio_scsi_device_find(s, req->req.cmd.lun); + d = virtio_scsi_device_get(s, req->req.cmd.lun); if (!d) { req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; virtio_scsi_complete_cmd_req(req); @@ -576,10 +583,12 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) req->sreq->cmd.xfer > req->qsgl.size)) { req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN; virtio_scsi_complete_cmd_req(req); + object_unref(OBJECT(d)); return -ENOBUFS; } scsi_req_ref(req->sreq); blk_io_plug(d->conf.blk); + object_unref(OBJECT(d)); return 0; } |