aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@wdc.com>2017-08-30 19:58:39 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2017-08-31 23:06:12 -0400
commit64104f703212ff50e855bb2e2fa80d71db62c521 (patch)
tree13179e6dcb14cdde2fb7b2763bfcf6537dfac8c3
parent3515832cc61467bfb87191a30401de1700e9956a (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.c26
-rw-r--r--include/scsi/scsi_cmnd.h3
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 */
1115void scsi_initialize_rq(struct request *rq) 1121void 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);
1352out: 1364out:
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
1908static void scsi_mq_done(struct scsi_cmnd *cmd) 1926static 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
61struct scsi_cmnd { 64struct scsi_cmnd {
62 struct scsi_request req; 65 struct scsi_request req;