Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Li Tian and committed by
Martin K. Petersen
9cf351b2 7aa0f56d

+21 -11
+21 -11
drivers/scsi/storvsc_drv.c
··· 1131 1131 kfree(payload); 1132 1132 } 1133 1133 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 + 1134 1154 static void storvsc_on_io_completion(struct storvsc_device *stor_device, 1135 1155 struct vstor_packet *vstor_packet, 1136 1156 struct storvsc_cmd_request *request) ··· 1161 1141 stor_pkt = &request->vstor_packet; 1162 1142 1163 1143 /* 1164 - * The current SCSI handling on the host side does 1165 - * not correctly handle: 1166 - * INQUIRY command with page code parameter set to 0x80 1167 - * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c 1168 - * MAINTENANCE_IN is not supported by HyperV FC passthrough 1169 - * 1170 1144 * Setup srb and scsi status so this won't be fatal. 1171 1145 * We do this so we can distinguish truly fatal failues 1172 1146 * (srb status == 0x4) and off-line the device in that case. 1173 1147 */ 1174 1148 1175 - if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || 1176 - (stor_pkt->vm_srb.cdb[0] == MODE_SENSE) || 1177 - (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) || 1178 - (stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN && 1179 - hv_dev_is_fc(device))) { 1149 + if (storvsc_host_mishandles_cmd(stor_pkt->vm_srb.cdb[0], device)) { 1180 1150 vstor_packet->vm_srb.scsi_status = 0; 1181 1151 vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS; 1182 1152 }