diff options
author | Bart Van Assche <bart.vanassche@wdc.com> | 2017-08-30 19:58:39 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-08-31 23:06:12 -0400 |
commit | 64104f703212ff50e855bb2e2fa80d71db62c521 (patch) | |
tree | 13179e6dcb14cdde2fb7b2763bfcf6537dfac8c3 | |
parent | 3515832cc61467bfb87191a30401de1700e9956a (diff) |
scsi: Call scsi_initialize_rq() for filesystem requests
If a pass-through request is submitted then blk_get_request()
initializes that request by calling scsi_initialize_rq(). Also call this
function for filesystem requests. Introduce CMD_INITIALIZED to keep
track of whether or not a request has already been initialized.
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Brian King <brking@linux.vnet.ibm.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 26 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 3 |
2 files changed, 25 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 938a7e398cd4..4bfe0df35823 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -642,6 +642,11 @@ static bool scsi_end_request(struct request *req, blk_status_t error, | |||
642 | if (blk_queue_add_random(q)) | 642 | if (blk_queue_add_random(q)) |
643 | add_disk_randomness(req->rq_disk); | 643 | add_disk_randomness(req->rq_disk); |
644 | 644 | ||
645 | if (!blk_rq_is_scsi(req)) { | ||
646 | WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED)); | ||
647 | cmd->flags &= ~SCMD_INITIALIZED; | ||
648 | } | ||
649 | |||
645 | if (req->mq_ctx) { | 650 | if (req->mq_ctx) { |
646 | /* | 651 | /* |
647 | * In the MQ case the command gets freed by __blk_mq_end_request, | 652 | * In the MQ case the command gets freed by __blk_mq_end_request, |
@@ -1110,7 +1115,8 @@ EXPORT_SYMBOL(scsi_init_io); | |||
1110 | * scsi_initialize_rq - initialize struct scsi_cmnd.req | 1115 | * scsi_initialize_rq - initialize struct scsi_cmnd.req |
1111 | * @rq: Request associated with the SCSI command to be initialized. | 1116 | * @rq: Request associated with the SCSI command to be initialized. |
1112 | * | 1117 | * |
1113 | * Called from inside blk_get_request(). | 1118 | * Called from inside blk_get_request() for pass-through requests and from |
1119 | * inside scsi_init_command() for filesystem requests. | ||
1114 | */ | 1120 | */ |
1115 | void scsi_initialize_rq(struct request *rq) | 1121 | void scsi_initialize_rq(struct request *rq) |
1116 | { | 1122 | { |
@@ -1154,7 +1160,13 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) | |||
1154 | { | 1160 | { |
1155 | void *buf = cmd->sense_buffer; | 1161 | void *buf = cmd->sense_buffer; |
1156 | void *prot = cmd->prot_sdb; | 1162 | void *prot = cmd->prot_sdb; |
1157 | unsigned int unchecked_isa_dma = cmd->flags & SCMD_UNCHECKED_ISA_DMA; | 1163 | struct request *rq = blk_mq_rq_from_pdu(cmd); |
1164 | unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS; | ||
1165 | |||
1166 | if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) { | ||
1167 | flags |= SCMD_INITIALIZED; | ||
1168 | scsi_initialize_rq(rq); | ||
1169 | } | ||
1158 | 1170 | ||
1159 | /* zero out the cmd, except for the embedded scsi_request */ | 1171 | /* zero out the cmd, except for the embedded scsi_request */ |
1160 | memset((char *)cmd + sizeof(cmd->req), 0, | 1172 | memset((char *)cmd + sizeof(cmd->req), 0, |
@@ -1163,7 +1175,7 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) | |||
1163 | cmd->device = dev; | 1175 | cmd->device = dev; |
1164 | cmd->sense_buffer = buf; | 1176 | cmd->sense_buffer = buf; |
1165 | cmd->prot_sdb = prot; | 1177 | cmd->prot_sdb = prot; |
1166 | cmd->flags = unchecked_isa_dma; | 1178 | cmd->flags = flags; |
1167 | INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); | 1179 | INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); |
1168 | cmd->jiffies_at_alloc = jiffies; | 1180 | cmd->jiffies_at_alloc = jiffies; |
1169 | 1181 | ||
@@ -1350,6 +1362,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1350 | 1362 | ||
1351 | ret = scsi_setup_cmnd(sdev, req); | 1363 | ret = scsi_setup_cmnd(sdev, req); |
1352 | out: | 1364 | out: |
1365 | if (ret != BLKPREP_OK) | ||
1366 | cmd->flags &= ~SCMD_INITIALIZED; | ||
1353 | return scsi_prep_return(q, req, ret); | 1367 | return scsi_prep_return(q, req, ret); |
1354 | } | 1368 | } |
1355 | 1369 | ||
@@ -1869,6 +1883,7 @@ static int scsi_mq_prep_fn(struct request *req) | |||
1869 | struct scsi_device *sdev = req->q->queuedata; | 1883 | struct scsi_device *sdev = req->q->queuedata; |
1870 | struct Scsi_Host *shost = sdev->host; | 1884 | struct Scsi_Host *shost = sdev->host; |
1871 | struct scatterlist *sg; | 1885 | struct scatterlist *sg; |
1886 | int ret; | ||
1872 | 1887 | ||
1873 | scsi_init_command(sdev, cmd); | 1888 | scsi_init_command(sdev, cmd); |
1874 | 1889 | ||
@@ -1902,7 +1917,10 @@ static int scsi_mq_prep_fn(struct request *req) | |||
1902 | 1917 | ||
1903 | blk_mq_start_request(req); | 1918 | blk_mq_start_request(req); |
1904 | 1919 | ||
1905 | return scsi_setup_cmnd(sdev, req); | 1920 | ret = scsi_setup_cmnd(sdev, req); |
1921 | if (ret != BLK_STS_OK) | ||
1922 | cmd->flags &= ~SCMD_INITIALIZED; | ||
1923 | return ret; | ||
1906 | } | 1924 | } |
1907 | 1925 | ||
1908 | static void scsi_mq_done(struct scsi_cmnd *cmd) | 1926 | static void scsi_mq_done(struct scsi_cmnd *cmd) |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index f5afcff8d76f..a9f8f7e79d83 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -57,6 +57,9 @@ struct scsi_pointer { | |||
57 | /* for scmd->flags */ | 57 | /* for scmd->flags */ |
58 | #define SCMD_TAGGED (1 << 0) | 58 | #define SCMD_TAGGED (1 << 0) |
59 | #define SCMD_UNCHECKED_ISA_DMA (1 << 1) | 59 | #define SCMD_UNCHECKED_ISA_DMA (1 << 1) |
60 | #define SCMD_INITIALIZED (1 << 3) | ||
61 | /* flags preserved across unprep / reprep */ | ||
62 | #define SCMD_PRESERVED_FLAGS (SCMD_UNCHECKED_ISA_DMA | SCMD_INITIALIZED) | ||
60 | 63 | ||
61 | struct scsi_cmnd { | 64 | struct scsi_cmnd { |
62 | struct scsi_request req; | 65 | struct scsi_request req; |