[PATCH] scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for Hyper-V vFC
From: Li Tian
Date: Sun Apr 05 2026 - 21:54:22 EST
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@xxxxxxxxxx>
---
drivers/scsi/storvsc_drv.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index ae1abab97835..6977ca8a0658 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -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;
}
--
2.53.0