scsi: core: Remove the cmd field from struct scsi_request

Now that each scsi_request is backed by a scsi_cmnd, there is no need to
indirect the CDB storage.  Change all submitters of SCSI passthrough
requests to store the CDB information directly in the scsi_cmnd, and while
doing so allocate the full 32 bytes that cover all Linux supported SCSI
hosts instead of requiring dynamic allocation for > 16 byte CDBs.  On
64-bit systems this does not change the size of the scsi_cmnd at all, while
on 32-bit systems it slightly increases it for now, but that increase will
be made up by the removal of the remaining scsi_request fields.

Link: https://lore.kernel.org/r/20220224175552.988286-4-hch@lst.de
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: John Garry <john.garry@huawei.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Christoph Hellwig 2022-02-24 18:55:47 +01:00 committed by Martin K. Petersen
parent 71bada345b
commit ce70fd9a55
19 changed files with 113 additions and 168 deletions

View File

@ -1022,7 +1022,9 @@ void ata_scsi_sdev_config(struct scsi_device *sdev)
*/ */
bool ata_scsi_dma_need_drain(struct request *rq) bool ata_scsi_dma_need_drain(struct request *rq)
{ {
return atapi_cmd_type(scsi_req(rq)->cmd[0]) == ATAPI_MISC; struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);
return atapi_cmd_type(scmd->cmnd[0]) == ATAPI_MISC;
} }
EXPORT_SYMBOL_GPL(ata_scsi_dma_need_drain); EXPORT_SYMBOL_GPL(ata_scsi_dma_need_drain);

View File

@ -693,6 +693,7 @@ static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *nod
static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc) static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc)
{ {
struct request_queue *q = bdev_get_queue(pd->bdev); struct request_queue *q = bdev_get_queue(pd->bdev);
struct scsi_cmnd *scmd;
struct request *rq; struct request *rq;
int ret = 0; int ret = 0;
@ -700,6 +701,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
scmd = blk_mq_rq_to_pdu(rq);
if (cgc->buflen) { if (cgc->buflen) {
ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen,
@ -708,8 +710,8 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
goto out; goto out;
} }
scsi_req(rq)->cmd_len = COMMAND_SIZE(cgc->cmd[0]); scmd->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
memcpy(scsi_req(rq)->cmd, cgc->cmd, CDROM_PACKET_SIZE); memcpy(scmd->cmnd, cgc->cmd, CDROM_PACKET_SIZE);
rq->timeout = 60*HZ; rq->timeout = 60*HZ;
if (cgc->quiet) if (cgc->quiet)

View File

@ -13,6 +13,7 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
fmode_t mode, unsigned int timeout) fmode_t mode, unsigned int timeout)
{ {
struct scsi_request *sreq; struct scsi_request *sreq;
struct scsi_cmnd *scmd;
struct request *rq; struct request *rq;
struct bio *bio; struct bio *bio;
int ret; int ret;
@ -33,19 +34,19 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
ret = -ENOMEM; ret = -ENOMEM;
sreq = scsi_req(rq); sreq = scsi_req(rq);
sreq->cmd_len = hdr->request_len; scmd = blk_mq_rq_to_pdu(rq);
if (sreq->cmd_len > BLK_MAX_CDB) { scmd->cmd_len = hdr->request_len;
sreq->cmd = kzalloc(sreq->cmd_len, GFP_KERNEL); if (scmd->cmd_len > sizeof(scmd->cmnd)) {
if (!sreq->cmd) ret = -EINVAL;
goto out_put_request; goto out_put_request;
} }
ret = -EFAULT; ret = -EFAULT;
if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len)) if (copy_from_user(scmd->cmnd, uptr64(hdr->request), scmd->cmd_len))
goto out_free_cmd; goto out_put_request;
ret = -EPERM; ret = -EPERM;
if (!scsi_cmd_allowed(sreq->cmd, mode)) if (!scsi_cmd_allowed(scmd->cmnd, mode))
goto out_free_cmd; goto out_put_request;
ret = 0; ret = 0;
if (hdr->dout_xfer_len) { if (hdr->dout_xfer_len) {
@ -57,7 +58,7 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
} }
if (ret) if (ret)
goto out_free_cmd; goto out_put_request;
bio = rq->bio; bio = rq->bio;
blk_execute_rq(rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL)); blk_execute_rq(rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL));
@ -92,8 +93,6 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
blk_rq_unmap_user(bio); blk_rq_unmap_user(bio);
out_free_cmd:
scsi_req_free_cmd(scsi_req(rq));
out_put_request: out_put_request:
blk_mq_free_request(rq); blk_mq_free_request(rq);
return ret; return ret;

View File

@ -36,11 +36,9 @@ void scsi_show_rq(struct seq_file *m, struct request *rq)
struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req); struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req);
int alloc_ms = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc); int alloc_ms = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc);
int timeout_ms = jiffies_to_msecs(rq->timeout); int timeout_ms = jiffies_to_msecs(rq->timeout);
const u8 *const cdb = READ_ONCE(cmd->cmnd);
char buf[80] = "(?)"; char buf[80] = "(?)";
if (cdb) __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len);
__scsi_format_command(buf, sizeof(buf), cdb, cmd->cmd_len);
seq_printf(m, ", .cmd=%s, .retries=%d, .result = %#x, .flags=", buf, seq_printf(m, ", .cmd=%s, .retries=%d, .result = %#x, .flags=", buf,
cmd->retries, cmd->result); cmd->retries, cmd->result);
scsi_flags_show(m, cmd->flags, scsi_cmd_flags, scsi_flags_show(m, cmd->flags, scsi_cmd_flags,

View File

@ -980,7 +980,7 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
* @scmd: SCSI command structure to hijack * @scmd: SCSI command structure to hijack
* @ses: structure to save restore information * @ses: structure to save restore information
* @cmnd: CDB to send. Can be NULL if no new cmnd is needed * @cmnd: CDB to send. Can be NULL if no new cmnd is needed
* @cmnd_size: size in bytes of @cmnd (must be <= BLK_MAX_CDB) * @cmnd_size: size in bytes of @cmnd (must be <= MAX_COMMAND_SIZE)
* @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored)
* *
* This function is used to save a scsi command information before re-execution * This function is used to save a scsi command information before re-execution
@ -1002,7 +1002,6 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
* command. * command.
*/ */
ses->cmd_len = scmd->cmd_len; ses->cmd_len = scmd->cmd_len;
ses->cmnd = scmd->cmnd;
ses->data_direction = scmd->sc_data_direction; ses->data_direction = scmd->sc_data_direction;
ses->sdb = scmd->sdb; ses->sdb = scmd->sdb;
ses->result = scmd->result; ses->result = scmd->result;
@ -1013,8 +1012,8 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
scmd->prot_op = SCSI_PROT_NORMAL; scmd->prot_op = SCSI_PROT_NORMAL;
scmd->eh_eflags = 0; scmd->eh_eflags = 0;
scmd->cmnd = ses->eh_cmnd; memcpy(ses->cmnd, scmd->cmnd, sizeof(ses->cmnd));
memset(scmd->cmnd, 0, BLK_MAX_CDB); memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
memset(&scmd->sdb, 0, sizeof(scmd->sdb)); memset(&scmd->sdb, 0, sizeof(scmd->sdb));
scmd->result = 0; scmd->result = 0;
scmd->req.resid_len = 0; scmd->req.resid_len = 0;
@ -1033,7 +1032,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
} else { } else {
scmd->sc_data_direction = DMA_NONE; scmd->sc_data_direction = DMA_NONE;
if (cmnd) { if (cmnd) {
BUG_ON(cmnd_size > BLK_MAX_CDB); BUG_ON(cmnd_size > sizeof(scmd->cmnd));
memcpy(scmd->cmnd, cmnd, cmnd_size); memcpy(scmd->cmnd, cmnd, cmnd_size);
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
} }
@ -1066,7 +1065,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
* Restore original data * Restore original data
*/ */
scmd->cmd_len = ses->cmd_len; scmd->cmd_len = ses->cmd_len;
scmd->cmnd = ses->cmnd; memcpy(scmd->cmnd, ses->cmnd, sizeof(ses->cmnd));
scmd->sc_data_direction = ses->data_direction; scmd->sc_data_direction = ses->data_direction;
scmd->sdb = ses->sdb; scmd->sdb = ses->sdb;
scmd->result = ses->result; scmd->result = ses->result;
@ -2022,6 +2021,7 @@ static void eh_lock_door_done(struct request *req, blk_status_t status)
*/ */
static void scsi_eh_lock_door(struct scsi_device *sdev) static void scsi_eh_lock_door(struct scsi_device *sdev)
{ {
struct scsi_cmnd *scmd;
struct request *req; struct request *req;
struct scsi_request *rq; struct scsi_request *rq;
@ -2029,14 +2029,15 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
if (IS_ERR(req)) if (IS_ERR(req))
return; return;
rq = scsi_req(req); rq = scsi_req(req);
scmd = blk_mq_rq_to_pdu(req);
rq->cmd[0] = ALLOW_MEDIUM_REMOVAL; scmd->cmnd[0] = ALLOW_MEDIUM_REMOVAL;
rq->cmd[1] = 0; scmd->cmnd[1] = 0;
rq->cmd[2] = 0; scmd->cmnd[2] = 0;
rq->cmd[3] = 0; scmd->cmnd[3] = 0;
rq->cmd[4] = SCSI_REMOVAL_PREVENT; scmd->cmnd[4] = SCSI_REMOVAL_PREVENT;
rq->cmd[5] = 0; scmd->cmnd[5] = 0;
rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
req->rq_flags |= RQF_QUIET; req->rq_flags |= RQF_QUIET;
req->timeout = 10 * HZ; req->timeout = 10 * HZ;
@ -2399,7 +2400,6 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
scmd = (struct scsi_cmnd *)(rq + 1); scmd = (struct scsi_cmnd *)(rq + 1);
scsi_init_command(dev, scmd); scsi_init_command(dev, scmd);
scmd->cmnd = scsi_req(rq)->cmd;
scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL; scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL;
memset(&scmd->sdb, 0, sizeof(scmd->sdb)); memset(&scmd->sdb, 0, sizeof(scmd->sdb));

View File

@ -345,19 +345,15 @@ EXPORT_SYMBOL(scsi_cmd_allowed);
static int scsi_fill_sghdr_rq(struct scsi_device *sdev, struct request *rq, static int scsi_fill_sghdr_rq(struct scsi_device *sdev, struct request *rq,
struct sg_io_hdr *hdr, fmode_t mode) struct sg_io_hdr *hdr, fmode_t mode)
{ {
struct scsi_request *req = scsi_req(rq); struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);
if (hdr->cmd_len < 6) if (hdr->cmd_len < 6)
return -EMSGSIZE; return -EMSGSIZE;
if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len)) if (copy_from_user(scmd->cmnd, hdr->cmdp, hdr->cmd_len))
return -EFAULT; return -EFAULT;
if (!scsi_cmd_allowed(req->cmd, mode)) if (!scsi_cmd_allowed(scmd->cmnd, mode))
return -EPERM; return -EPERM;
scmd->cmd_len = hdr->cmd_len;
/*
* fill in request structure
*/
req->cmd_len = hdr->cmd_len;
rq->timeout = msecs_to_jiffies(hdr->timeout); rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout) if (!rq->timeout)
@ -416,6 +412,7 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
int at_head = 0; int at_head = 0;
struct request *rq; struct request *rq;
struct scsi_request *req; struct scsi_request *req;
struct scsi_cmnd *scmd;
struct bio *bio; struct bio *bio;
if (hdr->interface_id != 'S') if (hdr->interface_id != 'S')
@ -444,16 +441,16 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
req = scsi_req(rq); req = scsi_req(rq);
scmd = blk_mq_rq_to_pdu(rq);
if (hdr->cmd_len > BLK_MAX_CDB) { if (hdr->cmd_len > sizeof(scmd->cmnd)) {
req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); ret = -EINVAL;
if (!req->cmd) goto out_put_request;
goto out_put_request;
} }
ret = scsi_fill_sghdr_rq(sdev, rq, hdr, mode); ret = scsi_fill_sghdr_rq(sdev, rq, hdr, mode);
if (ret < 0) if (ret < 0)
goto out_free_cdb; goto out_put_request;
ret = 0; ret = 0;
if (hdr->iovec_count) { if (hdr->iovec_count) {
@ -463,7 +460,7 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
ret = import_iovec(rq_data_dir(rq), hdr->dxferp, ret = import_iovec(rq_data_dir(rq), hdr->dxferp,
hdr->iovec_count, 0, &iov, &i); hdr->iovec_count, 0, &iov, &i);
if (ret < 0) if (ret < 0)
goto out_free_cdb; goto out_put_request;
/* SG_IO howto says that the shorter of the two wins */ /* SG_IO howto says that the shorter of the two wins */
iov_iter_truncate(&i, hdr->dxfer_len); iov_iter_truncate(&i, hdr->dxfer_len);
@ -475,7 +472,7 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
hdr->dxfer_len, GFP_KERNEL); hdr->dxfer_len, GFP_KERNEL);
if (ret) if (ret)
goto out_free_cdb; goto out_put_request;
bio = rq->bio; bio = rq->bio;
req->retries = 0; req->retries = 0;
@ -488,8 +485,6 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
ret = scsi_complete_sghdr_rq(rq, hdr, bio); ret = scsi_complete_sghdr_rq(rq, hdr, bio);
out_free_cdb:
scsi_req_free_cmd(req);
out_put_request: out_put_request:
blk_mq_free_request(rq); blk_mq_free_request(rq);
return ret; return ret;
@ -530,6 +525,7 @@ static int sg_scsi_ioctl(struct request_queue *q, fmode_t mode,
struct scsi_request *req; struct scsi_request *req;
int err; int err;
unsigned int in_len, out_len, bytes, opcode, cmdlen; unsigned int in_len, out_len, bytes, opcode, cmdlen;
struct scsi_cmnd *scmd;
char *buffer = NULL; char *buffer = NULL;
if (!sic) if (!sic)
@ -561,6 +557,7 @@ static int sg_scsi_ioctl(struct request_queue *q, fmode_t mode,
goto error_free_buffer; goto error_free_buffer;
} }
req = scsi_req(rq); req = scsi_req(rq);
scmd = blk_mq_rq_to_pdu(rq);
cmdlen = COMMAND_SIZE(opcode); cmdlen = COMMAND_SIZE(opcode);
@ -568,15 +565,15 @@ static int sg_scsi_ioctl(struct request_queue *q, fmode_t mode,
* get command and data to send to device, if any * get command and data to send to device, if any
*/ */
err = -EFAULT; err = -EFAULT;
req->cmd_len = cmdlen; scmd->cmd_len = cmdlen;
if (copy_from_user(req->cmd, sic->data, cmdlen)) if (copy_from_user(scmd->cmnd, sic->data, cmdlen))
goto error; goto error;
if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
goto error; goto error;
err = -EPERM; err = -EPERM;
if (!scsi_cmd_allowed(req->cmd, mode)) if (!scsi_cmd_allowed(scmd->cmnd, mode))
goto error; goto error;
/* default. possible overridden later */ /* default. possible overridden later */

View File

@ -214,6 +214,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
{ {
struct request *req; struct request *req;
struct scsi_request *rq; struct scsi_request *rq;
struct scsi_cmnd *scmd;
int ret; int ret;
req = scsi_alloc_request(sdev->request_queue, req = scsi_alloc_request(sdev->request_queue,
@ -231,8 +232,9 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
if (ret) if (ret)
goto out; goto out;
} }
rq->cmd_len = COMMAND_SIZE(cmd[0]); scmd = blk_mq_rq_to_pdu(req);
memcpy(rq->cmd, cmd, rq->cmd_len); scmd->cmd_len = COMMAND_SIZE(cmd[0]);
memcpy(scmd->cmnd, cmd, scmd->cmd_len);
rq->retries = retries; rq->retries = retries;
req->timeout = timeout; req->timeout = timeout;
req->cmd_flags |= flags; req->cmd_flags |= flags;
@ -1126,9 +1128,9 @@ static void scsi_initialize_rq(struct request *rq)
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
struct scsi_request *req = &cmd->req; struct scsi_request *req = &cmd->req;
memset(req->__cmd, 0, sizeof(req->__cmd)); memset(cmd->cmnd, 0, sizeof(cmd->cmnd));
req->cmd = req->__cmd; cmd->cmd_len = MAX_COMMAND_SIZE;
req->cmd_len = BLK_MAX_CDB;
req->sense_len = 0; req->sense_len = 0;
init_rcu_head(&cmd->rcu); init_rcu_head(&cmd->rcu);
@ -1196,8 +1198,6 @@ static blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev,
memset(&cmd->sdb, 0, sizeof(cmd->sdb)); memset(&cmd->sdb, 0, sizeof(cmd->sdb));
} }
cmd->cmd_len = scsi_req(req)->cmd_len;
cmd->cmnd = scsi_req(req)->cmd;
cmd->transfersize = blk_rq_bytes(req); cmd->transfersize = blk_rq_bytes(req);
cmd->allowed = scsi_req(req)->retries; cmd->allowed = scsi_req(req)->retries;
return BLK_STS_OK; return BLK_STS_OK;
@ -1567,8 +1567,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
cmd->prot_type = 0; cmd->prot_type = 0;
cmd->prot_flags = 0; cmd->prot_flags = 0;
cmd->submitter = 0; cmd->submitter = 0;
cmd->cmd_len = 0;
cmd->cmnd = NULL;
memset(&cmd->sdb, 0, sizeof(cmd->sdb)); memset(&cmd->sdb, 0, sizeof(cmd->sdb));
cmd->underflow = 0; cmd->underflow = 0;
cmd->transfersize = 0; cmd->transfersize = 0;
@ -1616,8 +1614,7 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
return ret; return ret;
} }
cmd->cmnd = scsi_req(req)->cmd = scsi_req(req)->__cmd; memset(cmd->cmnd, 0, sizeof(cmd->cmnd));
memset(cmd->cmnd, 0, BLK_MAX_CDB);
return scsi_cmd_to_driver(cmd)->init_command(cmd); return scsi_cmd_to_driver(cmd)->init_command(cmd);
} }

View File

@ -87,7 +87,7 @@ void scmd_printk(const char *level, const struct scsi_cmnd *scmd,
char *logbuf; char *logbuf;
size_t off = 0, logbuf_len; size_t off = 0, logbuf_len;
if (!scmd || !scmd->cmnd) if (!scmd)
return; return;
logbuf = scsi_log_reserve_buffer(&logbuf_len); logbuf = scsi_log_reserve_buffer(&logbuf_len);
@ -183,9 +183,6 @@ void scsi_print_command(struct scsi_cmnd *cmd)
char *logbuf; char *logbuf;
size_t off, logbuf_len; size_t off, logbuf_len;
if (!cmd->cmnd)
return;
logbuf = scsi_log_reserve_buffer(&logbuf_len); logbuf = scsi_log_reserve_buffer(&logbuf_len);
if (!logbuf) if (!logbuf)
return; return;

View File

@ -128,7 +128,6 @@ static DEFINE_IDA(sd_index_ida);
static DEFINE_MUTEX(sd_ref_mutex); static DEFINE_MUTEX(sd_ref_mutex);
static struct kmem_cache *sd_cdb_cache; static struct kmem_cache *sd_cdb_cache;
static mempool_t *sd_cdb_pool;
static mempool_t *sd_page_pool; static mempool_t *sd_page_pool;
static struct lock_class_key sd_bio_compl_lkclass; static struct lock_class_key sd_bio_compl_lkclass;
@ -1075,13 +1074,7 @@ static blk_status_t sd_setup_rw32_cmnd(struct scsi_cmnd *cmd, bool write,
sector_t lba, unsigned int nr_blocks, sector_t lba, unsigned int nr_blocks,
unsigned char flags) unsigned char flags)
{ {
cmd->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC);
if (unlikely(cmd->cmnd == NULL))
return BLK_STS_RESOURCE;
cmd->cmd_len = SD_EXT_CDB_SIZE; cmd->cmd_len = SD_EXT_CDB_SIZE;
memset(cmd->cmnd, 0, cmd->cmd_len);
cmd->cmnd[0] = VARIABLE_LENGTH_CMD; cmd->cmnd[0] = VARIABLE_LENGTH_CMD;
cmd->cmnd[7] = 0x18; /* Additional CDB len */ cmd->cmnd[7] = 0x18; /* Additional CDB len */
cmd->cmnd[9] = write ? WRITE_32 : READ_32; cmd->cmnd[9] = write ? WRITE_32 : READ_32;
@ -1313,17 +1306,9 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
static void sd_uninit_command(struct scsi_cmnd *SCpnt) static void sd_uninit_command(struct scsi_cmnd *SCpnt)
{ {
struct request *rq = scsi_cmd_to_rq(SCpnt); struct request *rq = scsi_cmd_to_rq(SCpnt);
u8 *cmnd;
if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
mempool_free(rq->special_vec.bv_page, sd_page_pool); mempool_free(rq->special_vec.bv_page, sd_page_pool);
if (SCpnt->cmnd != scsi_req(rq)->cmd) {
cmnd = SCpnt->cmnd;
SCpnt->cmnd = NULL;
SCpnt->cmd_len = 0;
mempool_free(cmnd, sd_cdb_pool);
}
} }
static bool sd_need_revalidate(struct block_device *bdev, static bool sd_need_revalidate(struct block_device *bdev,
@ -3819,18 +3804,11 @@ static int __init init_sd(void)
goto err_out_class; goto err_out_class;
} }
sd_cdb_pool = mempool_create_slab_pool(SD_MEMPOOL_SIZE, sd_cdb_cache);
if (!sd_cdb_pool) {
printk(KERN_ERR "sd: can't init extended cdb pool\n");
err = -ENOMEM;
goto err_out_cache;
}
sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0); sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0);
if (!sd_page_pool) { if (!sd_page_pool) {
printk(KERN_ERR "sd: can't init discard page pool\n"); printk(KERN_ERR "sd: can't init discard page pool\n");
err = -ENOMEM; err = -ENOMEM;
goto err_out_ppool; goto err_out_cache;
} }
err = scsi_register_driver(&sd_template.gendrv); err = scsi_register_driver(&sd_template.gendrv);
@ -3842,9 +3820,6 @@ static int __init init_sd(void)
err_out_driver: err_out_driver:
mempool_destroy(sd_page_pool); mempool_destroy(sd_page_pool);
err_out_ppool:
mempool_destroy(sd_cdb_pool);
err_out_cache: err_out_cache:
kmem_cache_destroy(sd_cdb_cache); kmem_cache_destroy(sd_cdb_cache);
@ -3868,7 +3843,6 @@ static void __exit exit_sd(void)
SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
scsi_unregister_driver(&sd_template.gendrv); scsi_unregister_driver(&sd_template.gendrv);
mempool_destroy(sd_cdb_pool);
mempool_destroy(sd_page_pool); mempool_destroy(sd_page_pool);
kmem_cache_destroy(sd_cdb_cache); kmem_cache_destroy(sd_cdb_cache);

View File

@ -818,7 +818,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
} }
if (atomic_read(&sdp->detaching)) { if (atomic_read(&sdp->detaching)) {
if (srp->bio) { if (srp->bio) {
scsi_req_free_cmd(scsi_req(srp->rq));
blk_mq_free_request(srp->rq); blk_mq_free_request(srp->rq);
srp->rq = NULL; srp->rq = NULL;
} }
@ -1393,7 +1392,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status)
* blk_rq_unmap_user() can be called from user context. * blk_rq_unmap_user() can be called from user context.
*/ */
srp->rq = NULL; srp->rq = NULL;
scsi_req_free_cmd(scsi_req(rq));
blk_mq_free_request(rq); blk_mq_free_request(rq);
write_lock_irqsave(&sfp->rq_list_lock, iflags); write_lock_irqsave(&sfp->rq_list_lock, iflags);
@ -1738,18 +1736,12 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
struct request_queue *q = sfp->parentdp->device->request_queue; struct request_queue *q = sfp->parentdp->device->request_queue;
struct rq_map_data *md, map_data; struct rq_map_data *md, map_data;
int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ; int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ;
unsigned char *long_cmdp = NULL; struct scsi_cmnd *scmd;
SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
"sg_start_req: dxfer_len=%d\n", "sg_start_req: dxfer_len=%d\n",
dxfer_len)); dxfer_len));
if (hp->cmd_len > BLK_MAX_CDB) {
long_cmdp = kzalloc(hp->cmd_len, GFP_KERNEL);
if (!long_cmdp)
return -ENOMEM;
}
/* /*
* NOTE * NOTE
* *
@ -1763,16 +1755,18 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
*/ */
rq = scsi_alloc_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ? rq = scsi_alloc_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(rq)) { if (IS_ERR(rq))
kfree(long_cmdp);
return PTR_ERR(rq); return PTR_ERR(rq);
} scmd = blk_mq_rq_to_pdu(rq);
req = scsi_req(rq); req = scsi_req(rq);
if (hp->cmd_len > BLK_MAX_CDB) if (hp->cmd_len > sizeof(scmd->cmnd)) {
req->cmd = long_cmdp; blk_mq_free_request(rq);
memcpy(req->cmd, cmd, hp->cmd_len); return -EINVAL;
req->cmd_len = hp->cmd_len; }
memcpy(scmd->cmnd, cmd, hp->cmd_len);
scmd->cmd_len = hp->cmd_len;
srp->rq = rq; srp->rq = rq;
rq->end_io_data = srp; rq->end_io_data = srp;
@ -1865,10 +1859,8 @@ sg_finish_rem_req(Sg_request *srp)
if (srp->bio) if (srp->bio)
ret = blk_rq_unmap_user(srp->bio); ret = blk_rq_unmap_user(srp->bio);
if (srp->rq) { if (srp->rq)
scsi_req_free_cmd(scsi_req(srp->rq));
blk_mq_free_request(srp->rq); blk_mq_free_request(srp->rq);
}
if (srp->res_used) if (srp->res_used)
sg_unlink_reserve(sfp, srp); sg_unlink_reserve(sfp, srp);

View File

@ -966,6 +966,7 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
struct gendisk *disk = cdi->disk; struct gendisk *disk = cdi->disk;
u32 len = nr * CD_FRAMESIZE_RAW; u32 len = nr * CD_FRAMESIZE_RAW;
struct scsi_request *req; struct scsi_request *req;
struct scsi_cmnd *scmd;
struct request *rq; struct request *rq;
struct bio *bio; struct bio *bio;
int ret; int ret;
@ -974,22 +975,23 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
req = scsi_req(rq); req = scsi_req(rq);
scmd = blk_mq_rq_to_pdu(rq);
ret = blk_rq_map_user(disk->queue, rq, NULL, ubuf, len, GFP_KERNEL); ret = blk_rq_map_user(disk->queue, rq, NULL, ubuf, len, GFP_KERNEL);
if (ret) if (ret)
goto out_put_request; goto out_put_request;
req->cmd[0] = GPCMD_READ_CD; scmd->cmnd[0] = GPCMD_READ_CD;
req->cmd[1] = 1 << 2; scmd->cmnd[1] = 1 << 2;
req->cmd[2] = (lba >> 24) & 0xff; scmd->cmnd[2] = (lba >> 24) & 0xff;
req->cmd[3] = (lba >> 16) & 0xff; scmd->cmnd[3] = (lba >> 16) & 0xff;
req->cmd[4] = (lba >> 8) & 0xff; scmd->cmnd[4] = (lba >> 8) & 0xff;
req->cmd[5] = lba & 0xff; scmd->cmnd[5] = lba & 0xff;
req->cmd[6] = (nr >> 16) & 0xff; scmd->cmnd[6] = (nr >> 16) & 0xff;
req->cmd[7] = (nr >> 8) & 0xff; scmd->cmnd[7] = (nr >> 8) & 0xff;
req->cmd[8] = nr & 0xff; scmd->cmnd[8] = nr & 0xff;
req->cmd[9] = 0xf8; scmd->cmnd[9] = 0xf8;
req->cmd_len = 12; scmd->cmd_len = 12;
rq->timeout = 60 * HZ; rq->timeout = 60 * HZ;
bio = rq->bio; bio = rq->bio;

View File

@ -472,10 +472,11 @@ static void st_release_request(struct st_request *streq)
static void st_do_stats(struct scsi_tape *STp, struct request *req) static void st_do_stats(struct scsi_tape *STp, struct request *req)
{ {
struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
ktime_t now; ktime_t now;
now = ktime_get(); now = ktime_get();
if (scsi_req(req)->cmd[0] == WRITE_6) { if (scmd->cmnd[0] == WRITE_6) {
now = ktime_sub(now, STp->stats->write_time); now = ktime_sub(now, STp->stats->write_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_write_time); atomic64_add(ktime_to_ns(now), &STp->stats->tot_write_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time); atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
@ -489,7 +490,7 @@ static void st_do_stats(struct scsi_tape *STp, struct request *req)
} else } else
atomic64_add(atomic_read(&STp->stats->last_write_size), atomic64_add(atomic_read(&STp->stats->last_write_size),
&STp->stats->write_byte_cnt); &STp->stats->write_byte_cnt);
} else if (scsi_req(req)->cmd[0] == READ_6) { } else if (scmd->cmnd[0] == READ_6) {
now = ktime_sub(now, STp->stats->read_time); now = ktime_sub(now, STp->stats->read_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_read_time); atomic64_add(ktime_to_ns(now), &STp->stats->tot_read_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time); atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
@ -542,12 +543,14 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
int err = 0; int err = 0;
struct scsi_tape *STp = SRpnt->stp; struct scsi_tape *STp = SRpnt->stp;
struct scsi_cmnd *scmd;
req = scsi_alloc_request(SRpnt->stp->device->request_queue, req = scsi_alloc_request(SRpnt->stp->device->request_queue,
data_direction == DMA_TO_DEVICE ? data_direction == DMA_TO_DEVICE ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(req)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
scmd = blk_mq_rq_to_pdu(req);
rq = scsi_req(req); rq = scsi_req(req);
req->rq_flags |= RQF_QUIET; req->rq_flags |= RQF_QUIET;
@ -574,9 +577,8 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
} }
SRpnt->bio = req->bio; SRpnt->bio = req->bio;
rq->cmd_len = COMMAND_SIZE(cmd[0]); scmd->cmd_len = COMMAND_SIZE(cmd[0]);
memset(rq->cmd, 0, BLK_MAX_CDB); memcpy(scmd->cmnd, cmd, scmd->cmd_len);
memcpy(rq->cmd, cmd, rq->cmd_len);
req->timeout = timeout; req->timeout = timeout;
rq->retries = retries; rq->retries = retries;
req->end_io_data = SRpnt; req->end_io_data = SRpnt;

View File

@ -666,15 +666,14 @@ static void ufshpb_execute_umap_req(struct ufshpb_lu *hpb,
struct ufshpb_req *umap_req, struct ufshpb_req *umap_req,
struct ufshpb_region *rgn) struct ufshpb_region *rgn)
{ {
struct request *req; struct request *req = umap_req->req;
struct scsi_request *rq; struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
req = umap_req->req;
req->timeout = 0; req->timeout = 0;
req->end_io_data = (void *)umap_req; req->end_io_data = umap_req;
rq = scsi_req(req);
ufshpb_set_unmap_cmd(rq->cmd, rgn); ufshpb_set_unmap_cmd(scmd->cmnd, rgn);
rq->cmd_len = HPB_WRITE_BUFFER_CMD_LENGTH; scmd->cmd_len = HPB_WRITE_BUFFER_CMD_LENGTH;
blk_execute_rq_nowait(req, true, ufshpb_umap_req_compl_fn); blk_execute_rq_nowait(req, true, ufshpb_umap_req_compl_fn);
@ -686,7 +685,7 @@ static int ufshpb_execute_map_req(struct ufshpb_lu *hpb,
{ {
struct request_queue *q; struct request_queue *q;
struct request *req; struct request *req;
struct scsi_request *rq; struct scsi_cmnd *scmd;
int mem_size = hpb->srgn_mem_size; int mem_size = hpb->srgn_mem_size;
int ret = 0; int ret = 0;
int i; int i;
@ -709,14 +708,13 @@ static int ufshpb_execute_map_req(struct ufshpb_lu *hpb,
req->end_io_data = map_req; req->end_io_data = map_req;
rq = scsi_req(req);
if (unlikely(last)) if (unlikely(last))
mem_size = hpb->last_srgn_entries * HPB_ENTRY_SIZE; mem_size = hpb->last_srgn_entries * HPB_ENTRY_SIZE;
ufshpb_set_read_buf_cmd(rq->cmd, map_req->rb.rgn_idx, scmd = blk_mq_rq_to_pdu(req);
ufshpb_set_read_buf_cmd(scmd->cmnd, map_req->rb.rgn_idx,
map_req->rb.srgn_idx, mem_size); map_req->rb.srgn_idx, mem_size);
rq->cmd_len = HPB_READ_BUFFER_CMD_LENGTH; scmd->cmd_len = HPB_READ_BUFFER_CMD_LENGTH;
blk_execute_rq_nowait(req, true, ufshpb_map_req_compl_fn); blk_execute_rq_nowait(req, true, ufshpb_map_req_compl_fn);

View File

@ -961,6 +961,7 @@ pscsi_execute_cmd(struct se_cmd *cmd)
struct scatterlist *sgl = cmd->t_data_sg; struct scatterlist *sgl = cmd->t_data_sg;
u32 sgl_nents = cmd->t_data_nents; u32 sgl_nents = cmd->t_data_nents;
struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
struct scsi_cmnd *scmd;
struct request *req; struct request *req;
sense_reason_t ret; sense_reason_t ret;
@ -978,12 +979,15 @@ pscsi_execute_cmd(struct se_cmd *cmd)
req->end_io = pscsi_req_done; req->end_io = pscsi_req_done;
req->end_io_data = cmd; req->end_io_data = cmd;
scsi_req(req)->cmd_len = scsi_command_size(cmd->t_task_cdb);
if (scsi_req(req)->cmd_len > BLK_MAX_CDB) { scmd = blk_mq_rq_to_pdu(req);
scmd->cmd_len = scsi_command_size(cmd->t_task_cdb);
if (scmd->cmd_len > sizeof(scmd->cmnd)) {
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
goto fail_put_request; goto fail_put_request;
} }
memcpy(scsi_req(req)->cmd, cmd->t_task_cdb, scsi_req(req)->cmd_len); memcpy(scmd->cmnd, cmd->t_task_cdb, scmd->cmd_len);
if (pdv->pdv_sd->type == TYPE_DISK || if (pdv->pdv_sd->type == TYPE_DISK ||
pdv->pdv_sd->type == TYPE_ZBC) pdv->pdv_sd->type == TYPE_ZBC)
req->timeout = PS_TIMEOUT_DISK; req->timeout = PS_TIMEOUT_DISK;
@ -991,7 +995,7 @@ pscsi_execute_cmd(struct se_cmd *cmd)
req->timeout = PS_TIMEOUT_OTHER; req->timeout = PS_TIMEOUT_OTHER;
scsi_req(req)->retries = PS_RETRY; scsi_req(req)->retries = PS_RETRY;
cmd->priv = scsi_req(req)->cmd; cmd->priv = scmd->cmnd;
blk_execute_rq_nowait(req, cmd->sam_task_attr == TCM_HEAD_TAG, blk_execute_rq_nowait(req, cmd->sam_task_attr == TCM_HEAD_TAG,
pscsi_req_done); pscsi_req_done);

View File

@ -177,7 +177,6 @@ static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
* but reading register selected in srb->cmnd[4] * but reading register selected in srb->cmnd[4]
*/ */
srb->cmd_len = 16; srb->cmd_len = 16;
srb->cmnd = ses.cmnd;
srb->cmnd[2] = 1; srb->cmnd[2] = 1;
usb_stor_transparent_scsi_command(srb, us); usb_stor_transparent_scsi_command(srb, us);

View File

@ -326,7 +326,7 @@ struct isd200_info {
/* maximum number of LUNs supported */ /* maximum number of LUNs supported */
unsigned char MaxLUNs; unsigned char MaxLUNs;
unsigned char cmnd[BLK_MAX_CDB]; unsigned char cmnd[MAX_COMMAND_SIZE];
struct scsi_cmnd srb; struct scsi_cmnd srb;
struct scatterlist sg; struct scatterlist sg;
}; };
@ -485,7 +485,7 @@ static int isd200_action( struct us_data *us, int action,
int status; int status;
memset(&ata, 0, sizeof(ata)); memset(&ata, 0, sizeof(ata));
srb->cmnd = info->cmnd; memcpy(srb->cmnd, info->cmnd, MAX_COMMAND_SIZE);
srb->device = &srb_dev; srb->device = &srb_dev;
ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;

View File

@ -28,9 +28,6 @@ struct scsi_driver;
* supports without specifying a cmd_len by ULD's * supports without specifying a cmd_len by ULD's
*/ */
#define MAX_COMMAND_SIZE 16 #define MAX_COMMAND_SIZE 16
#if (MAX_COMMAND_SIZE > BLK_MAX_CDB)
# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB
#endif
struct scsi_data_buffer { struct scsi_data_buffer {
struct sg_table table; struct sg_table table;
@ -100,9 +97,7 @@ struct scsi_cmnd {
unsigned short cmd_len; unsigned short cmd_len;
enum dma_data_direction sc_data_direction; enum dma_data_direction sc_data_direction;
/* These elements define the operation we are about to perform */ unsigned char cmnd[32]; /* SCSI CDB */
unsigned char *cmnd;
/* These elements define the operation we ultimately want to perform */ /* These elements define the operation we ultimately want to perform */
struct scsi_data_buffer sdb; struct scsi_data_buffer sdb;

View File

@ -38,10 +38,8 @@ struct scsi_eh_save {
unsigned underflow; unsigned underflow;
unsigned char cmd_len; unsigned char cmd_len;
unsigned char prot_op; unsigned char prot_op;
unsigned char *cmnd; unsigned char cmnd[32];
struct scsi_data_buffer sdb; struct scsi_data_buffer sdb;
/* new command support */
unsigned char eh_cmnd[BLK_MAX_CDB];
struct scatterlist sense_sgl; struct scatterlist sense_sgl;
}; };

View File

@ -4,12 +4,7 @@
#include <linux/blk-mq.h> #include <linux/blk-mq.h>
#define BLK_MAX_CDB 16
struct scsi_request { struct scsi_request {
unsigned char __cmd[BLK_MAX_CDB];
unsigned char *cmd;
unsigned short cmd_len;
int result; int result;
unsigned int sense_len; unsigned int sense_len;
unsigned int resid_len; /* residual count */ unsigned int resid_len; /* residual count */
@ -22,10 +17,4 @@ static inline struct scsi_request *scsi_req(struct request *rq)
return blk_mq_rq_to_pdu(rq); return blk_mq_rq_to_pdu(rq);
} }
static inline void scsi_req_free_cmd(struct scsi_request *req)
{
if (req->cmd != req->__cmd)
kfree(req->cmd);
}
#endif /* _SCSI_SCSI_REQUEST_H */ #endif /* _SCSI_SCSI_REQUEST_H */