Commit 9cf351b2 authored by Li Tian's avatar Li Tian Committed by Martin K. Petersen
Browse files

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: default avatarLi Tian <litian@redhat.com>
Reviewed-by: default avatarLong Li <longli@microsoft.com>
Reviewed-by: default avatarLaurence Oberman <loberman@redhat.com>
Link: https://patch.msgid.link/20260406015344.12566-1-litian@redhat.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 7aa0f56d
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -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;
	}