Skip to content

Commit 9cf351b

Browse files
litian1992martinkpetersen
authored andcommitted
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>
1 parent 7aa0f56 commit 9cf351b

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

drivers/scsi/storvsc_drv.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,26 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
11311131
kfree(payload);
11321132
}
11331133

1134+
/*
1135+
* The current SCSI handling on the host side does not correctly handle:
1136+
* INQUIRY with page code 0x80, MODE_SENSE / MODE_SENSE_10 with cmd[2] == 0x1c,
1137+
* and (for FC) MAINTENANCE_IN / PERSISTENT_RESERVE_IN passthrough.
1138+
*/
1139+
static bool storvsc_host_mishandles_cmd(u8 opcode, struct hv_device *device)
1140+
{
1141+
switch (opcode) {
1142+
case INQUIRY:
1143+
case MODE_SENSE:
1144+
case MODE_SENSE_10:
1145+
return true;
1146+
case MAINTENANCE_IN:
1147+
case PERSISTENT_RESERVE_IN:
1148+
return hv_dev_is_fc(device);
1149+
default:
1150+
return false;
1151+
}
1152+
}
1153+
11341154
static void storvsc_on_io_completion(struct storvsc_device *stor_device,
11351155
struct vstor_packet *vstor_packet,
11361156
struct storvsc_cmd_request *request)
@@ -1141,22 +1161,12 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
11411161
stor_pkt = &request->vstor_packet;
11421162

11431163
/*
1144-
* The current SCSI handling on the host side does
1145-
* not correctly handle:
1146-
* INQUIRY command with page code parameter set to 0x80
1147-
* MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c
1148-
* MAINTENANCE_IN is not supported by HyperV FC passthrough
1149-
*
11501164
* Setup srb and scsi status so this won't be fatal.
11511165
* We do this so we can distinguish truly fatal failues
11521166
* (srb status == 0x4) and off-line the device in that case.
11531167
*/
11541168

1155-
if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
1156-
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE) ||
1157-
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) ||
1158-
(stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN &&
1159-
hv_dev_is_fc(device))) {
1169+
if (storvsc_host_mishandles_cmd(stor_pkt->vm_srb.cdb[0], device)) {
11601170
vstor_packet->vm_srb.scsi_status = 0;
11611171
vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS;
11621172
}

0 commit comments

Comments
 (0)