From: Stefan Hajnoczi <[email protected]> The SPC-6 specification says that the PREEMPT service action ignores the TYPE field when there is no reservation. However, the LIO Linux iSCSI target rejects commands with a zero TYPE field. The field never ends up being used in this case, so replace it with a "valid" value to work around the issue.
Reported-by: Qing Wang <[email protected]> Buglink: https://redhat.atlassian.net/browse/RHEL-155807 Signed-off-by: Stefan Hajnoczi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Bonzini <[email protected]> --- include/scsi/constants.h | 10 ++++++++++ hw/scsi/scsi-generic.c | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/scsi/constants.h b/include/scsi/constants.h index cb97bdb6362..717e470a5d4 100644 --- a/include/scsi/constants.h +++ b/include/scsi/constants.h @@ -340,4 +340,14 @@ #define PRO_REGISTER_AND_MOVE 0x07 #define PRO_REPLACE_LOST_RESERVATION 0x08 +/* + * Persistent reservation types + */ +#define PR_TYPE_WRITE_EXCLUSIVE 0x1 +#define PR_TYPE_EXCLUSIVE_ACCESS 0x3 +#define PR_TYPE_WRITE_EXCLUSIVE_REG_ONLY 0x5 +#define PR_TYPE_EXCLUSIVE_ACCESS_REG_ONLY 0x6 +#define PR_TYPE_WRITE_EXCLUSIVE_ALL_REGS 0x7 +#define PR_TYPE_EXCLUSIVE_ACCESS_ALL_REGS 0x8 + #endif diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index d0086d86d94..f1c328e6da6 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -453,6 +453,16 @@ static bool scsi_generic_pr_preempt(SCSIDevice *s, uint64_t key, uint64_t key_be = cpu_to_be64(key); int ret; + /* + * The LIO iSCSI target in Linux up to at least version 7.0 rejects PREEMPT + * commands with a zero TYPE field although the SPC-6 specification says + * the field should be ignored when there is no persistent reservation. + * Work around this by choosing an arbitrary valid PR type value. + */ + if (resv_type == 0) { + resv_type = PR_TYPE_WRITE_EXCLUSIVE; + } + cmd[0] = PERSISTENT_RESERVE_OUT; cmd[1] = PRO_PREEMPT; cmd[2] = resv_type & 0xf; -- 2.54.0
