Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.5:Update
qemu-linux-user
0167-scsi-disk-fold-SG_IO-errors-back-in.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0167-scsi-disk-fold-SG_IO-errors-back-in.patch of Package qemu-linux-user
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 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: Bruce Rogers <brogers@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 b0cdbc1b9f01c7b4280bfa8d0b98..5bb37b59617dbeae7578d21c3c2f 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -76,7 +76,7 @@ typedef struct SCSIDiskReq { struct iovec iov; QEMUIOVector qiov; BlockAcctCookie acct; - unsigned char *status; + uint32_t status; } SCSIDiskReq; #define SCSI_DISK_F_REMOVABLE 0 @@ -188,7 +188,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); } @@ -441,11 +441,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)); @@ -2616,8 +2617,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, @@ -2698,9 +2717,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; } @@ -2814,7 +2838,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 0e177db8070721921c5698e173e7..d163b9e6c0bb77ca65a8ee655814 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -327,6 +327,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" # hw/scsi/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