From: Stefan Hajnoczi <[email protected]> The SCSI specification says PREEMPT without a reservation removes all registrations with the given key. Try to register again after PREEMPT since our key will have been removed.
In practice some SCSI targets keep the calling I_T nexus' registration instead of removing it. Therefore we need to handle both the spec-compliant and the non-compliant behavior. Signed-off-by: Stefan Hajnoczi <[email protected]> Reviewed-by: Paolo Bonzini <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Bonzini <[email protected]> (cherry picked from commit b9a3b329d09dea5a4692de483419693ef0e23052) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 349dea6bddf..5182f9236da 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -513,6 +513,16 @@ bool scsi_generic_pr_state_preempt(SCSIDevice *s, Error **errp) if (!scsi_generic_pr_preempt(s, key, resv_type, errp)) { return false; } + + /* + * Some SCSI targets, like the Linux LIO target, remove our + * registration when preempting without a reservation (resv_type is 0). + * Try to register again but ignore the error since a RESERVATION + * CONFLICT is expected if our registration remained in place. + */ + if (resv_type == 0) { + scsi_generic_pr_register(s, key, NULL); + } } return true; } -- 2.47.3
