mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
ANDROID: scsi: core: Delay unaligned write error retries
Host-managed zoned block devices report the sense code 21h/04h
(UNALIGNED WRITE COMMAND) when attempting to write data at another LBA
than the write pointer. Retry unaligned writes after all other pending
commands have completed instead of retrying these immediately. The
change in this patch makes the following function decide to queue the
failed command to the error handler instead of retrying it immediately:
static void scsi_complete(struct request *rq)
{
[ ... ]
switch (disposition) {
case SUCCESS:
scsi_finish_command(cmd);
break;
case NEEDS_RETRY:
scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY);
break;
case ADD_TO_MLQUEUE:
scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
break;
default:
scsi_eh_scmd_add(cmd);
break;
}
}
This patch has not been posted on any Linux kernel mailing list since
there is agreement that another approach will be taken to preserve the
order of WRITE commands for zoned devices. However, the implementation
of that new approach is not yet available.
Bug: 197782466
Change-Id: I3529ce4f01ff166a0c8ac321eb31b0e7771906ac
Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
@@ -672,11 +672,11 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
|
||||
|
||||
case ILLEGAL_REQUEST:
|
||||
/*
|
||||
* Unaligned write command. Retry immediately to handle
|
||||
* out-of-order zoned writes.
|
||||
* Unaligned write command. This indicates that zoned writes got
|
||||
* reordered. Retry after all pending commands have completed.
|
||||
*/
|
||||
if (sshdr.asc == 0x21 && sshdr.ascq == 0x04)
|
||||
return NEEDS_RETRY;
|
||||
return NEEDS_DELAYED_RETRY;
|
||||
if (sshdr.asc == 0x20 || /* Invalid command operation code */
|
||||
sshdr.asc == 0x21 || /* Logical block address out of range */
|
||||
sshdr.asc == 0x22 || /* Invalid function */
|
||||
|
||||
@@ -93,6 +93,7 @@ static inline int scsi_status_is_check_condition(int status)
|
||||
* Internal return values.
|
||||
*/
|
||||
enum scsi_disposition {
|
||||
NEEDS_DELAYED_RETRY = 0x2000,
|
||||
NEEDS_RETRY = 0x2001,
|
||||
SUCCESS = 0x2002,
|
||||
FAILED = 0x2003,
|
||||
|
||||
Reference in New Issue
Block a user