diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2017-05-26 11:49:59 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-05-26 13:39:15 -0400 |
commit | 2819bfa1ca27db2517b8d968fb0b179e70f3d3e9 (patch) | |
tree | cfc419ad473f89fe8b19380567aeb7f30d50cad2 | |
parent | d2f2b0d2dc2f7c931ac91a84faafe3ec2c2ef8d5 (diff) | |
download | linux-scsi-work.tar.gz |
scsi: sd: Clean up sd_setup_read_write_cmnd()scsi-work
Rework sd_setup_read_write_cmnd() so it becomes more readable. Put all
the sanity checking at the head of the function and sanitize the logged
error messages. Move the legacy SCSI logging calls to the end of the
functions and reduce conditional nesting.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/sd.c | 126 |
1 files changed, 47 insertions, 79 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 33cd30f9f47b56..ecc5c8b05ba039 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1021,58 +1021,46 @@ static int sd_setup_read_write_6_cmnd(struct scsi_cmnd *cmd, bool write, return BLKPREP_OK; } -static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt) +static int sd_setup_read_write_cmnd(struct scsi_cmnd *cmd) { - struct request *rq = SCpnt->request; - struct scsi_device *sdp = SCpnt->device; - struct gendisk *disk = rq->rq_disk; - struct scsi_disk *sdkp = scsi_disk(disk); + struct request *rq = cmd->request; + struct scsi_device *sdp = cmd->device; + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq)); sector_t threshold; unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); - unsigned int dif, dix; unsigned int mask = logical_to_sectors(sdp, 1) - 1; + unsigned char protect, fua; bool zoned_write = sd_is_zoned(sdkp) && rq_data_dir(rq) == WRITE; bool write = rq_data_dir(rq) == WRITE; + bool dif, dix; int ret; - unsigned char protect, fua; if (zoned_write) { - ret = sd_zbc_write_lock_zone(SCpnt); + ret = sd_zbc_write_lock_zone(cmd); if (ret != BLKPREP_OK) return ret; } - ret = scsi_init_io(SCpnt); + ret = scsi_init_io(cmd); if (ret != BLKPREP_OK) goto out; - SCpnt = rq->special; - /* from here on until we're complete, any goto out - * is used for a killable error condition */ - ret = BLKPREP_KILL; + if (!sdp || !scsi_device_online(sdp) || sdp->changed) { + scmd_printk(KERN_ERR, cmd, "device offline or changed\n"); + ret = BLKPREP_KILL; + goto out; + } - SCSI_LOG_HLQUEUE(1, - scmd_printk(KERN_INFO, SCpnt, - "%s: block=%llu, count=%d\n", - __func__, (unsigned long long)lba, nr_blocks)); - - if (!sdp || !scsi_device_online(sdp) || - lba + blk_rq_sectors(rq) > get_capacity(disk)) { - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "Finishing %u sectors\n", - blk_rq_sectors(rq))); - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "Retry with 0x%p\n", SCpnt)); + if (blk_rq_pos(rq) + blk_rq_sectors(rq) > get_capacity(rq->rq_disk)) { + scmd_printk(KERN_ERR, cmd, "access beyond end of device\n"); + ret = BLKPREP_KILL; goto out; } - if (sdp->changed) { - /* - * quietly refuse to do anything to a changed disc until - * the changed bit has been reset - */ - /* printk("SCSI disk has been changed or is not present. Prohibiting further I/O.\n"); */ + if ((blk_rq_pos(rq) & mask) || (blk_rq_sectors(rq) & mask)) { + scmd_printk(KERN_ERR, cmd, "request not aligned to the logical block size\n"); + ret = BLKPREP_KILL; goto out; } @@ -1092,80 +1080,60 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt) } } - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", - (unsigned long long)lba)); - - if ((blk_rq_pos(rq) & mask) || (blk_rq_sectors(rq) & mask)) { - scmd_printk(KERN_ERR, SCpnt, "request not aligned to the logical block size\n"); - goto out; - } - - if (rq_data_dir(rq) == WRITE) { - SCpnt->cmnd[0] = WRITE_6; - - if (blk_integrity_rq(rq)) - sd_dif_prepare(SCpnt); - - } else if (rq_data_dir(rq) == READ) { - SCpnt->cmnd[0] = READ_6; - } else { - scmd_printk(KERN_ERR, SCpnt, "Unknown command %d\n", req_op(rq)); - goto out; - } - - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "%s %d/%u 512 byte blocks.\n", - (rq_data_dir(rq) == WRITE) ? - "writing" : "reading", nr_blocks, - blk_rq_sectors(rq))); - fua = (rq->cmd_flags & REQ_FUA) ? 0x8 : 0; - dix = scsi_prot_sg_count(SCpnt); - dif = scsi_host_dif_capable(SCpnt->device->host, sdkp->protection_type); + dix = scsi_prot_sg_count(cmd); + dif = scsi_host_dif_capable(cmd->device->host, sdkp->protection_type); + + if (write && dix) + sd_dif_prepare(cmd); if (dif || dix) - protect = sd_setup_protect_cmnd(SCpnt, dix, dif); + protect = sd_setup_protect_cmnd(cmd, dix, dif); else protect = 0; if (protect && sdkp->protection_type == T10_PI_TYPE2_PROTECTION) { - ret = sd_setup_read_write_32_cmnd(SCpnt, write, lba, nr_blocks, + ret = sd_setup_read_write_32_cmnd(cmd, write, lba, nr_blocks, protect | fua); } else if (sdp->use_16_for_rw || (nr_blocks > 0xffff)) { - ret = sd_setup_read_write_16_cmnd(SCpnt, write, lba, nr_blocks, + ret = sd_setup_read_write_16_cmnd(cmd, write, lba, nr_blocks, protect | fua); - } else if ((nr_blocks > 0xff) || (lba > 0x1fffff) || - scsi_device_protection(SCpnt->device) || - SCpnt->device->use_10_for_rw) { - ret = sd_setup_read_write_10_cmnd(SCpnt, write, lba, nr_blocks, + } else if ((nr_blocks > 0xff) || (lba > 0x1fffff) || sdp->use_10_for_rw + || protect) { + ret = sd_setup_read_write_10_cmnd(cmd, write, lba, nr_blocks, protect | fua); } else { - ret = sd_setup_read_write_6_cmnd(SCpnt, write, lba, nr_blocks, + ret = sd_setup_read_write_6_cmnd(cmd, write, lba, nr_blocks, protect | fua); } if (ret != BLKPREP_OK) goto out; - SCpnt->sdb.length = nr_blocks * sdp->sector_size; - /* * We shouldn't disconnect in the middle of a sector, so with a dumb * host adapter, it's safe to assume that we can at least transfer * this many bytes between each connect / disconnect. */ - SCpnt->transfersize = sdp->sector_size; - SCpnt->underflow = nr_blocks << 9; - SCpnt->allowed = SD_MAX_RETRIES; + cmd->transfersize = sdp->sector_size; + cmd->underflow = nr_blocks << 9; + cmd->allowed = SD_MAX_RETRIES; + cmd->sdb.length = nr_blocks * sdp->sector_size; + + SCSI_LOG_HLQUEUE(1, + scmd_printk(KERN_INFO, cmd, + "%s: block=%llu, count=%d\n", __func__, + (unsigned long long)blk_rq_pos(rq), + blk_rq_sectors(rq))); + SCSI_LOG_HLQUEUE(2, + scmd_printk(KERN_INFO, cmd, + "%s %d/%u 512 byte blocks.\n", + write ? "writing" : "reading", nr_blocks, + blk_rq_sectors(rq))); - /* - * This indicates that the command is ready from our end to be - * queued. - */ - ret = BLKPREP_OK; out: if (zoned_write && ret != BLKPREP_OK) - sd_zbc_write_unlock_zone(SCpnt); + sd_zbc_write_unlock_zone(cmd); return ret; } |