mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for Hyper-V vFC
The storvsc driver has become stricter in handling SRB status codes returned by the Hyper-V host. When using Virtual Fibre Channel (vFC) passthrough, the host may return SRB_STATUS_DATA_OVERRUN for PERSISTENT_RESERVE_IN commands if the allocation length in the CDB does not match the host's expected response size. Currently, this status is treated as a fatal error, propagating Host_status=0x07 [DID_ERROR] to the SCSI mid-layer. This causes userspace storage utilities (such as sg_persist) to fail with transport errors, even when the host has actually returned the requested reservation data in the buffer. Refactor the existing command-specific workarounds into a new helper function, storvsc_host_mishandles_cmd(), and add PERSISTENT_RESERVE_IN to the list of commands where SRB status errors should be suppressed for vFC devices. This ensures that the SCSI mid-layer processes the returned data buffer instead of terminating the command. Signed-off-by: Li Tian <litian@redhat.com> Reviewed-by: Long Li <longli@microsoft.com> Reviewed-by: Laurence Oberman <loberman@redhat.com> Link: https://patch.msgid.link/20260406015344.12566-1-litian@redhat.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
7aa0f56d4b
commit
9cf351b289
|
|
@ -1131,6 +1131,26 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
|
|||
kfree(payload);
|
||||
}
|
||||
|
||||
/*
|
||||
* The current SCSI handling on the host side does not correctly handle:
|
||||
* INQUIRY with page code 0x80, MODE_SENSE / MODE_SENSE_10 with cmd[2] == 0x1c,
|
||||
* and (for FC) MAINTENANCE_IN / PERSISTENT_RESERVE_IN passthrough.
|
||||
*/
|
||||
static bool storvsc_host_mishandles_cmd(u8 opcode, struct hv_device *device)
|
||||
{
|
||||
switch (opcode) {
|
||||
case INQUIRY:
|
||||
case MODE_SENSE:
|
||||
case MODE_SENSE_10:
|
||||
return true;
|
||||
case MAINTENANCE_IN:
|
||||
case PERSISTENT_RESERVE_IN:
|
||||
return hv_dev_is_fc(device);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void storvsc_on_io_completion(struct storvsc_device *stor_device,
|
||||
struct vstor_packet *vstor_packet,
|
||||
struct storvsc_cmd_request *request)
|
||||
|
|
@ -1141,22 +1161,12 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
|
|||
stor_pkt = &request->vstor_packet;
|
||||
|
||||
/*
|
||||
* The current SCSI handling on the host side does
|
||||
* not correctly handle:
|
||||
* INQUIRY command with page code parameter set to 0x80
|
||||
* MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c
|
||||
* MAINTENANCE_IN is not supported by HyperV FC passthrough
|
||||
*
|
||||
* Setup srb and scsi status so this won't be fatal.
|
||||
* We do this so we can distinguish truly fatal failues
|
||||
* (srb status == 0x4) and off-line the device in that case.
|
||||
*/
|
||||
|
||||
if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
|
||||
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE) ||
|
||||
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) ||
|
||||
(stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN &&
|
||||
hv_dev_is_fc(device))) {
|
||||
if (storvsc_host_mishandles_cmd(stor_pkt->vm_srb.cdb[0], device)) {
|
||||
vstor_packet->vm_srb.scsi_status = 0;
|
||||
vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user