scsi: scsi_debug: Split resp_read_dt0()

Split this function to remove conditional locking. This patch prepares
for enabling context analysis.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.garry@linux.dev>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/eea4ce8d6ddc86a401570f09a559a3b3c50e78ff.1791924924.git.bvanassche@acm.org
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
Bart Van Assche 2026-10-13 15:10:05 -07:00 committed by Martin K. Petersen (Oracle)
parent 06bce26589
commit 06c3166f25

View File

@ -4608,6 +4608,70 @@ static int resp_read_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
return 0;
}
/*
* Returns 0 upon success or -1 with *scsi_status set to a SCSI status code upon
* failure.
*/
static int __resp_read_dt0_dix(struct scsi_cmnd *scp, u64 lba, u32 num,
u32 ei_lba, int *scsi_status)
{
const u8 *const cmd = scp->cmnd;
switch (prot_verify_read(scp, lba, num, ei_lba)) {
case 1: /* Guard tag error */
if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
mk_sense_buffer(scp, ABORTED_COMMAND,
LOGICAL_BLOCK_GUARD_CHECK_FAILED);
*scsi_status = check_condition_result;
return -1;
}
if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) {
mk_sense_buffer(scp, ILLEGAL_REQUEST,
LOGICAL_BLOCK_GUARD_CHECK_FAILED);
*scsi_status = illegal_condition_result;
return -1;
}
break;
case 3: /* Reference tag error */
if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
mk_sense_buffer(scp, ABORTED_COMMAND,
LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
*scsi_status = check_condition_result;
return -1;
}
if (scp->prot_flags & SCSI_PROT_REF_CHECK) {
mk_sense_buffer(scp, ILLEGAL_REQUEST,
LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
*scsi_status = illegal_condition_result;
return -1;
}
break;
}
return 0;
}
/*
* Returns the number of bytes transferred, or -1 with *scsi_status set to a
* SCSI status code on failure.
*/
static int __resp_read_dt0(struct scsi_cmnd *scp, struct sdeb_store_info *sip,
u64 lba, u32 num, u32 ei_lba, int *scsi_status)
{
int ret;
/* DIX + T10 DIF */
if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
ret = __resp_read_dt0_dix(scp, lba, num, ei_lba, scsi_status);
if (ret < 0)
return ret;
}
ret = do_device_access(sip, scp, 0, lba, num, 0, false, false);
if (ret < 0)
*scsi_status = DID_ERROR << 16;
return ret;
}
static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
{
bool check_prot;
@ -4617,7 +4681,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
u64 lba;
struct sdeb_store_info *sip = devip2sip(devip, true);
u8 *cmd = scp->cmnd;
bool meta_data_locked = false;
int scsi_status;
switch (cmd[0]) {
case READ_16:
@ -4699,48 +4763,16 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
}
if (sdebug_dev_is_zoned(devip) ||
(sdebug_dix && scsi_prot_sg_count(scp))) {
(sdebug_dix && scsi_prot_sg_count(scp))) {
sdeb_meta_read_lock(sip);
meta_data_locked = true;
}
/* DIX + T10 DIF */
if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
switch (prot_verify_read(scp, lba, num, ei_lba)) {
case 1: /* Guard tag error */
if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
sdeb_meta_read_unlock(sip);
mk_sense_buffer(scp, ABORTED_COMMAND,
LOGICAL_BLOCK_GUARD_CHECK_FAILED);
return check_condition_result;
} else if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) {
sdeb_meta_read_unlock(sip);
mk_sense_buffer(scp, ILLEGAL_REQUEST,
LOGICAL_BLOCK_GUARD_CHECK_FAILED);
return illegal_condition_result;
}
break;
case 3: /* Reference tag error */
if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
sdeb_meta_read_unlock(sip);
mk_sense_buffer(scp, ABORTED_COMMAND,
LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
return check_condition_result;
} else if (scp->prot_flags & SCSI_PROT_REF_CHECK) {
sdeb_meta_read_unlock(sip);
mk_sense_buffer(scp, ILLEGAL_REQUEST,
LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
return illegal_condition_result;
}
break;
}
}
ret = do_device_access(sip, scp, 0, lba, num, 0, false, false);
if (meta_data_locked)
ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status);
sdeb_meta_read_unlock(sip);
if (unlikely(ret == -1))
return DID_ERROR << 16;
} else {
ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status);
}
if (unlikely(ret < 0))
return scsi_status;
scsi_set_resid(scp, scsi_bufflen(scp) - ret);