Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:Update
qemu.29315
scsi-disk-fold-SG_IO-errors-back-into-re.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File scsi-disk-fold-SG_IO-errors-back-into-re.patch of Package qemu.29315
From: Hannes Reinecke <hare@suse.de> Date: Wed, 11 Nov 2020 17:34:45 +0100 Subject: scsi-disk: fold SG_IO errors back into request status References: bsc#1178049,bsc#1194938 When SG_IO returns with a non-zero 'host_status' or 'status' we should be folding these values into the request status to allow any drivers to signal them back to the guest. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Lin Ma <lma@suse.com> --- hw/scsi/scsi-disk.c | 37 ++++++++++++++++++++++++++++++------- hw/scsi/trace-events | 1 + 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index e0996c2f5b5a9859697cf8803738..2602941196033e263afe3dacd6bf 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -77,7 +77,7 @@ typedef struct SCSIDiskReq { struct iovec iov; QEMUIOVector qiov; BlockAcctCookie acct; - unsigned char *status; + uint32_t status; } SCSIDiskReq; #define SCSI_DISK_F_REMOVABLE 0 @@ -189,7 +189,7 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) return true; } - if (ret < 0 || (r->status && *r->status)) { + if (ret < 0 || r->status) { return scsi_handle_rw_error(r, -ret, acct_failed); } @@ -453,11 +453,12 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed) * whether the error has to be handled by the guest or should rather * pause the host. */ - assert(r->status && *r->status); - if (scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) { + assert(r->status); + if ((r->status >> 8) || + scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) { /* These errors are handled by guest. */ sdc->update_sense(&r->req); - scsi_req_complete(&r->req, *r->status); + scsi_req_complete(&r->req, r->status); return true; } error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense)); @@ -2714,8 +2715,26 @@ typedef struct SCSIBlockReq { /* CDB passed to SG_IO. */ uint8_t cdb[16]; + BlockCompletionFunc *cb; + void *cb_opaque; } SCSIBlockReq; +static void sgio_aio_complete(void *opaque, int ret) +{ + SCSIBlockReq *req = (SCSIBlockReq *)opaque; + SCSIDiskReq *r = &req->req; + SCSISense sense; + + trace_scsi_disk_aio_sgio_done(r->req.tag, ret, req->io_header.status, + req->io_header.host_status); + r->status = sg_io_sense_from_errno(-ret, &req->io_header, &sense); + if ((r->status & 0xff) == CHECK_CONDITION && + req->io_header.status != CHECK_CONDITION) + scsi_req_build_sense(&r->req, sense); + + req->cb(req->cb_opaque, ret); +} + static BlockAIOCB *scsi_block_do_sgio(SCSIBlockReq *req, int64_t offset, QEMUIOVector *iov, int direction, @@ -2796,9 +2815,14 @@ static BlockAIOCB *scsi_block_do_sgio(SCSIBlockReq *req, io_header->timeout = 5000; io_header->usr_ptr = r; io_header->flags |= SG_FLAG_DIRECT_IO; + + req->cb = cb; + req->cb_opaque = opaque; + trace_scsi_disk_aio_sgio_command(r->req.tag, req->cdb[0], lba, nb_logical_blocks, io_header->timeout); - aiocb = blk_aio_ioctl(s->qdev.conf.blk, SG_IO, io_header, cb, opaque); + aiocb = blk_aio_ioctl(s->qdev.conf.blk, SG_IO, io_header, + sgio_aio_complete, req); assert(aiocb != NULL); return aiocb; } @@ -2912,7 +2936,6 @@ static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf) return 0; } - r->req.status = &r->io_header.status; return scsi_disk_dma_command(req, buf); } diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events index 92e3819b5c3ee30df7a9400d6abd..0a08147c27d70637ffd9170ae903 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -329,6 +329,7 @@ scsi_disk_dma_command_READ(uint64_t lba, uint32_t len) "Read (sector %" PRId64 " scsi_disk_dma_command_WRITE(const char *cmd, uint64_t lba, int len) "Write %s(sector %" PRId64 ", count %u)" scsi_disk_new_request(uint32_t lun, uint32_t tag, const char *line) "Command: lun=%d tag=0x%x data=%s" scsi_disk_aio_sgio_command(uint32_t tag, uint8_t cmd, uint64_t lba, int len, uint32_t timeout) "disk aio sgio: tag=0x%x cmd 0x%x (sector %" PRId64 ", count %d) timeout %u" +scsi_disk_aio_sgio_done(uint32_t tag, int ret, uint8_t status, uint8_t host_status) "disk aio sgio: cmd 0x%x ret %d status 0x%x host_status 0x%x" # scsi-generic.c scsi_generic_command_complete_noio(void *req, uint32_t tag, uint8_t status, uint8_t host_status) "Command complete %p tag=0x%x status=0x%x host_status=0x%x"
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor