Don't bloat struct request with BLOCK_PC specific fields.

WIP, breaks dm BLOCK_PC passthrough and the old IDE driver for now.
---
 block/blk-core.c                            | 23 ++++++---
 block/blk-exec.c                            | 17 -------
 block/blk-mq.c                              |  4 --
 block/bsg-lib.c                             | 10 ++--
 block/bsg.c                                 | 31 ++++--------
 block/scsi_ioctl.c                          | 68 +++++++++++--------------
 drivers/ata/libata-scsi.c                   |  2 +-
 drivers/block/pktcdvd.c                     |  9 ++--
 drivers/block/virtio_blk.c                  |  9 ++--
 drivers/cdrom/cdrom.c                       | 36 +++++++------
 drivers/md/dm.c                             |  4 ++
 drivers/message/fusion/mptsas.c             |  4 +-
 drivers/scsi/device_handler/scsi_dh_alua.c  | 78 ++++++++++++++---------------
 drivers/scsi/device_handler/scsi_dh_emc.c   | 52 +++++++++----------
 drivers/scsi/device_handler/scsi_dh_hp_sw.c | 38 ++++++++------
 drivers/scsi/device_handler/scsi_dh_rdac.c  | 43 ++++++++--------
 drivers/scsi/mpt2sas/mpt2sas_transport.c    |  4 +-
 drivers/scsi/mpt3sas/mpt3sas_transport.c    |  4 +-
 drivers/scsi/osd/osd_initiator.c            | 32 ++++++------
 drivers/scsi/osst.c                         | 10 ++--
 drivers/scsi/qla2xxx/qla_bsg.c              |  2 +-
 drivers/scsi/qla2xxx/qla_isr.c              |  6 ++-
 drivers/scsi/qla2xxx/qla_mr.c               |  2 +-
 drivers/scsi/scsi_error.c                   | 22 ++++----
 drivers/scsi/scsi_lib.c                     | 22 ++++----
 drivers/scsi/scsi_transport_fc.c            | 10 ++--
 drivers/scsi/sd.c                           | 47 ++---------------
 drivers/scsi/sg.c                           | 21 +++-----
 drivers/scsi/st.c                           | 21 ++++----
 drivers/target/target_core_pscsi.c          | 14 +++---
 include/linux/blkdev.h                      | 27 ++++++----
 include/linux/blktrace_api.h                |  4 +-
 include/scsi/scsi_cmnd.h                    |  2 +-
 kernel/trace/blktrace.c                     | 11 ++--
 34 files changed, 319 insertions(+), 370 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 2e5020f..5d78a85 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -105,8 +105,6 @@ void blk_rq_init(struct request_queue *q, struct request 
*rq)
        rq->__sector = (sector_t) -1;
        INIT_HLIST_NODE(&rq->hash);
        RB_CLEAR_NODE(&rq->rb_node);
-       rq->cmd = rq->__cmd;
-       rq->cmd_len = BLK_MAX_CDB;
        rq->tag = -1;
        rq->start_time = jiffies;
        set_start_time_ns(rq);
@@ -149,7 +147,7 @@ void blk_dump_rq_flags(struct request *rq, char *msg)
        if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
                printk(KERN_INFO "  cdb: ");
                for (bit = 0; bit < BLK_MAX_CDB; bit++)
-                       printk("%02x ", rq->cmd[bit]);
+                       printk("%02x ", rq->block_pc->cmd[bit]);
                printk("\n");
        }
 }
@@ -1253,8 +1251,6 @@ struct request *blk_make_request(struct request_queue *q, 
struct bio *bio,
        if (IS_ERR(rq))
                return rq;
 
-       blk_rq_set_block_pc(rq);
-
        for_each_bio(bio) {
                struct bio *bounce_bio = bio;
                int ret;
@@ -1274,15 +1270,24 @@ EXPORT_SYMBOL(blk_make_request);
 /**
  * blk_rq_set_block_pc - initialize a request to type BLOCK_PC
  * @rq:                request to be initialized
+ * @cmd_len:   length of the CDB
+ * @gfp:       kmalloc flags
  *
  */
-void blk_rq_set_block_pc(struct request *rq)
+int blk_rq_set_block_pc(struct request *rq, unsigned short cmd_len,
+               u8 *sense, gfp_t gfp)
 {
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->__data_len = 0;
        rq->__sector = (sector_t) -1;
        rq->bio = rq->biotail = NULL;
-       memset(rq->__cmd, 0, sizeof(rq->__cmd));
+
+       rq->block_pc = kzalloc(sizeof(*rq->block_pc) + cmd_len, gfp);
+       if (!rq->block_pc)
+               return -ENOMEM;
+       rq->block_pc->cmd_len = cmd_len;
+       rq->block_pc->sense = sense;
+       return 0;
 }
 EXPORT_SYMBOL(blk_rq_set_block_pc);
 
@@ -1379,6 +1384,10 @@ void __blk_put_request(struct request_queue *q, struct 
request *req)
        if (unlikely(!q))
                return;
 
+       /* could also be other type-specific data */
+       if (req->block_pc)
+               kfree(req->block_pc);
+
        if (q->mq_ops) {
                blk_mq_free_request(req);
                return;
diff --git a/block/blk-exec.c b/block/blk-exec.c
index 3fec8a2..94e909e 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -10,11 +10,6 @@
 
 #include "blk.h"
 
-/*
- * for max sense size
- */
-#include <scsi/scsi_cmnd.h>
-
 /**
  * blk_end_sync_rq - executes a completion event on a request
  * @rq: request to complete
@@ -100,16 +95,9 @@ int blk_execute_rq(struct request_queue *q, struct gendisk 
*bd_disk,
                   struct request *rq, int at_head)
 {
        DECLARE_COMPLETION_ONSTACK(wait);
-       char sense[SCSI_SENSE_BUFFERSIZE];
        int err = 0;
        unsigned long hang_check;
 
-       if (!rq->sense) {
-               memset(sense, 0, sizeof(sense));
-               rq->sense = sense;
-               rq->sense_len = 0;
-       }
-
        rq->end_io_data = &wait;
        blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
 
@@ -123,11 +111,6 @@ int blk_execute_rq(struct request_queue *q, struct gendisk 
*bd_disk,
        if (rq->errors)
                err = -EIO;
 
-       if (rq->sense == sense) {
-               rq->sense = NULL;
-               rq->sense_len = 0;
-       }
-
        return err;
 }
 EXPORT_SYMBOL(blk_execute_rq);
diff --git a/block/blk-mq.c b/block/blk-mq.c
index ade8a2d..715e3c0 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -210,12 +210,8 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, 
struct blk_mq_ctx *ctx,
        /* tag was already set */
        rq->errors = 0;
 
-       rq->cmd = rq->__cmd;
-
        rq->extra_len = 0;
-       rq->sense_len = 0;
        rq->resid_len = 0;
-       rq->sense = NULL;
 
        INIT_LIST_HEAD(&rq->timeout_list);
        rq->timeout = 0;
diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 650f427..6b73dca 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -59,9 +59,9 @@ void bsg_job_done(struct bsg_job *job, int result,
        err = job->req->errors = result;
        if (err < 0)
                /* we're only returning the result field in the reply */
-               job->req->sense_len = sizeof(u32);
+               job->req->block_pc->sense_len = sizeof(u32);
        else
-               job->req->sense_len = job->reply_len;
+               job->req->block_pc->sense_len = job->reply_len;
        /* we assume all request payload was transferred, residual == 0 */
        req->resid_len = 0;
 
@@ -124,9 +124,9 @@ static int bsg_create_job(struct device *dev, struct 
request *req)
        job->req = req;
        if (q->bsg_job_size)
                job->dd_data = (void *)&job[1];
-       job->request = req->cmd;
-       job->request_len = req->cmd_len;
-       job->reply = req->sense;
+       job->request = req->block_pc->cmd;
+       job->request_len = req->block_pc->cmd_len;
+       job->reply = req->block_pc->sense;
        job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
                                                 * allocated */
        if (req->bio) {
diff --git a/block/bsg.c b/block/bsg.c
index d214e92..ebf0dc1 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -140,18 +140,13 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, 
struct request *rq,
                                struct sg_io_v4 *hdr, struct bsg_device *bd,
                                fmode_t has_write_perm)
 {
-       if (hdr->request_len > BLK_MAX_CDB) {
-               rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
-               if (!rq->cmd)
-                       return -ENOMEM;
-       }
-
-       if (copy_from_user(rq->cmd, (void __user *)(unsigned long)hdr->request,
+       if (copy_from_user(rq->block_pc->cmd,
+                          (void __user *)(unsigned long)hdr->request,
                           hdr->request_len))
                return -EFAULT;
 
        if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
-               if (blk_verify_command(rq->cmd, has_write_perm))
+               if (blk_verify_command(rq->block_pc->cmd, has_write_perm))
                        return -EPERM;
        } else if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
@@ -159,8 +154,6 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, 
struct request *rq,
        /*
         * fill in request structure
         */
-       rq->cmd_len = hdr->request_len;
-
        rq->timeout = msecs_to_jiffies(hdr->timeout);
        if (!rq->timeout)
                rq->timeout = q->sg_timeout;
@@ -236,7 +229,10 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, 
fmode_t has_write_perm,
        rq = blk_get_request(q, rw, GFP_KERNEL);
        if (IS_ERR(rq))
                return rq;
-       blk_rq_set_block_pc(rq);
+
+       ret = blk_rq_set_block_pc(rq, hdr->request_len, sense, GFP_KERNEL);
+       if (ret)
+               goto out;
 
        ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
        if (ret)
@@ -280,13 +276,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, 
fmode_t has_write_perm,
                        goto out;
        }
 
-       rq->sense = sense;
-       rq->sense_len = 0;
-
        return rq;
 out:
-       if (rq->cmd != rq->__cmd)
-               kfree(rq->cmd);
        blk_put_request(rq);
        if (next_rq) {
                blk_rq_unmap_user(next_rq->bio);
@@ -407,12 +398,12 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, 
struct sg_io_v4 *hdr,
                hdr->info |= SG_INFO_CHECK;
        hdr->response_len = 0;
 
-       if (rq->sense_len && hdr->response) {
+       if (rq->block_pc->sense_len && hdr->response) {
                int len = min_t(unsigned int, hdr->max_response_len,
-                                       rq->sense_len);
+                                       rq->block_pc->sense_len);
 
                ret = copy_to_user((void __user *)(unsigned long)hdr->response,
-                                  rq->sense, len);
+                                  rq->block_pc->sense, len);
                if (!ret)
                        hdr->response_len = len;
                else
@@ -439,8 +430,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, 
struct sg_io_v4 *hdr,
                ret = rq->errors;
 
        blk_rq_unmap_user(bio);
-       if (rq->cmd != rq->__cmd)
-               kfree(rq->cmd);
        blk_put_request(rq);
 
        return ret;
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 55b6f15..62f4e16 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -227,16 +227,14 @@ EXPORT_SYMBOL(blk_verify_command);
 static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
                             struct sg_io_hdr *hdr, fmode_t mode)
 {
-       if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
+       if (copy_from_user(rq->block_pc->cmd, hdr->cmdp, hdr->cmd_len))
                return -EFAULT;
-       if (blk_verify_command(rq->cmd, mode & FMODE_WRITE))
+       if (blk_verify_command(rq->block_pc->cmd, mode & FMODE_WRITE))
                return -EPERM;
 
        /*
         * fill in request structure
         */
-       rq->cmd_len = hdr->cmd_len;
-
        rq->timeout = msecs_to_jiffies(hdr->timeout);
        if (!rq->timeout)
                rq->timeout = q->sg_timeout;
@@ -267,10 +265,11 @@ static int blk_complete_sghdr_rq(struct request *rq, 
struct sg_io_hdr *hdr,
        hdr->resid = rq->resid_len;
        hdr->sb_len_wr = 0;
 
-       if (rq->sense_len && hdr->sbp) {
-               int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);
+       if (rq->block_pc->sense_len && hdr->sbp) {
+               int len = min((unsigned int) hdr->mx_sb_len,
+                               rq->block_pc->sense_len);
 
-               if (!copy_to_user(hdr->sbp, rq->sense, len))
+               if (!copy_to_user(hdr->sbp, rq->block_pc->sense, len))
                        hdr->sb_len_wr = len;
                else
                        ret = -EFAULT;
@@ -291,7 +290,6 @@ static int sg_io(struct request_queue *q, struct gendisk 
*bd_disk,
        int writing = 0;
        int at_head = 0;
        struct request *rq;
-       char sense[SCSI_SENSE_BUFFERSIZE];
        struct bio *bio;
 
        if (hdr->interface_id != 'S')
@@ -318,17 +316,14 @@ static int sg_io(struct request_queue *q, struct gendisk 
*bd_disk,
        rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
-       blk_rq_set_block_pc(rq);
 
-       if (hdr->cmd_len > BLK_MAX_CDB) {
-               rq->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
-               if (!rq->cmd)
-                       goto out_put_request;
-       }
+       ret = blk_rq_set_block_pc(rq, hdr->cmd_len, NULL, GFP_KERNEL);
+       if (ret)
+               goto out_put_request;
 
        ret = -EFAULT;
        if (blk_fill_sghdr_rq(q, rq, hdr, mode))
-               goto out_free_cdb;
+               goto out_put_request;
 
        ret = 0;
        if (hdr->iovec_count) {
@@ -339,7 +334,7 @@ static int sg_io(struct request_queue *q, struct gendisk 
*bd_disk,
                                   hdr->dxferp, hdr->iovec_count,
                                   0, &iov, &i);
                if (ret < 0)
-                       goto out_free_cdb;
+                       goto out_put_request;
 
                /* SG_IO howto says that the shorter of the two wins */
                iov_iter_truncate(&i, hdr->dxfer_len);
@@ -351,12 +346,9 @@ static int sg_io(struct request_queue *q, struct gendisk 
*bd_disk,
                                      GFP_KERNEL);
 
        if (ret)
-               goto out_free_cdb;
+               goto out_put_request;
 
        bio = rq->bio;
-       memset(sense, 0, sizeof(sense));
-       rq->sense = sense;
-       rq->sense_len = 0;
        rq->retries = 0;
 
        start_time = jiffies;
@@ -371,9 +363,6 @@ static int sg_io(struct request_queue *q, struct gendisk 
*bd_disk,
 
        ret = blk_complete_sghdr_rq(rq, hdr, bio);
 
-out_free_cdb:
-       if (rq->cmd != rq->__cmd)
-               kfree(rq->cmd);
 out_put_request:
        blk_put_request(rq);
        return ret;
@@ -449,22 +438,23 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk 
*disk, fmode_t mode,
                err = PTR_ERR(rq);
                goto error_free_buffer;
        }
-       blk_rq_set_block_pc(rq);
 
        cmdlen = COMMAND_SIZE(opcode);
+       err = blk_rq_set_block_pc(rq, cmdlen, sense, GFP_KERNEL);
+       if (err)
+               goto error;
 
        /*
         * get command and data to send to device, if any
         */
        err = -EFAULT;
-       rq->cmd_len = cmdlen;
-       if (copy_from_user(rq->cmd, sic->data, cmdlen))
+       if (copy_from_user(rq->block_pc->cmd, sic->data, cmdlen))
                goto error;
 
        if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
                goto error;
 
-       err = blk_verify_command(rq->cmd, mode & FMODE_WRITE);
+       err = blk_verify_command(rq->block_pc->cmd, mode & FMODE_WRITE);
        if (err)
                goto error;
 
@@ -500,18 +490,14 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk 
*disk, fmode_t mode,
                goto error;
        }
 
-       memset(sense, 0, sizeof(sense));
-       rq->sense = sense;
-       rq->sense_len = 0;
-
        blk_execute_rq(q, disk, rq, 0);
 
        err = rq->errors & 0xff;        /* only 8 bit SCSI status */
        if (err) {
-               if (rq->sense_len && rq->sense) {
-                       bytes = (OMAX_SB_LEN > rq->sense_len) ?
-                               rq->sense_len : OMAX_SB_LEN;
-                       if (copy_to_user(sic->data, rq->sense, bytes))
+               if (rq->block_pc->sense_len) {
+                       bytes = (OMAX_SB_LEN > rq->block_pc->sense_len) ?
+                               rq->block_pc->sense_len : OMAX_SB_LEN;
+                       if (copy_to_user(sic->data, rq->block_pc->sense, bytes))
                                err = -EFAULT;
                }
        } else {
@@ -539,14 +525,16 @@ static int __blk_send_generic(struct request_queue *q, 
struct gendisk *bd_disk,
        rq = blk_get_request(q, WRITE, __GFP_WAIT);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
-       blk_rq_set_block_pc(rq);
+       err = blk_rq_set_block_pc(rq, 6, NULL, GFP_KERNEL);
+       if (err)
+               goto out_put_request;
+
        rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
-       rq->cmd[0] = cmd;
-       rq->cmd[4] = data;
-       rq->cmd_len = 6;
+       rq->block_pc->cmd[0] = cmd;
+       rq->block_pc->cmd[4] = data;
        err = blk_execute_rq(q, bd_disk, rq, 0);
+out_put_request:
        blk_put_request(rq);
-
        return err;
 }
 
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 3131adc..d8cb4ec 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1143,7 +1143,7 @@ static int atapi_drain_needed(struct request *rq)
        if (!blk_rq_bytes(rq) || (rq->cmd_flags & REQ_WRITE))
                return 0;
 
-       return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
+       return atapi_cmd_type(rq->block_pc->cmd[0]) == ATAPI_MISC;
 }
 
 static int ata_scsi_dev_config(struct scsi_device *sdev,
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 09e628da..51f919d 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -706,7 +706,11 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, 
struct packet_command *
                             WRITE : READ, __GFP_WAIT);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
-       blk_rq_set_block_pc(rq);
+
+       ret = blk_rq_set_block_pc(rq, COMMAND_SIZE(cgc->cmd[0]), NULL,
+                       GFP_KERNEL);
+       if (ret)
+               goto out;
 
        if (cgc->buflen) {
                ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen,
@@ -715,8 +719,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, 
struct packet_command *
                        goto out;
        }
 
-       rq->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
-       memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
+       memcpy(rq->block_pc->cmd, cgc->cmd, CDROM_PACKET_SIZE);
 
        rq->timeout = 60*HZ;
        if (cgc->quiet)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index d4d05f0..cd3bcc0 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -90,7 +90,8 @@ static int __virtblk_add_req(struct virtqueue *vq,
         * inhdr with additional status information.
         */
        if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
-               sg_init_one(&cmd, vbr->req->cmd, vbr->req->cmd_len);
+               sg_init_one(&cmd, vbr->req->block_pc->cmd,
+                               vbr->req->block_pc->cmd_len);
                sgs[num_out++] = &cmd;
        }
 
@@ -102,7 +103,8 @@ static int __virtblk_add_req(struct virtqueue *vq,
        }
 
        if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
-               sg_init_one(&sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
+               sg_init_one(&sense, vbr->req->block_pc->sense,
+                               SCSI_SENSE_BUFFERSIZE);
                sgs[num_out + num_in++] = &sense;
                sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr));
                sgs[num_out + num_in++] = &inhdr;
@@ -122,7 +124,8 @@ static inline void virtblk_request_done(struct request *req)
 
        if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
                req->resid_len = virtio32_to_cpu(vblk->vdev, 
vbr->in_hdr.residual);
-               req->sense_len = virtio32_to_cpu(vblk->vdev, 
vbr->in_hdr.sense_len);
+               req->block_pc->sense_len =
+                       virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
                req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
        } else if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
                req->errors = (error != 0);
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 5d28a45..7a5672a 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2160,6 +2160,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info 
*cdi, __u8 __user *ubuf,
                               int lba, int nframes)
 {
        struct request_queue *q = cdi->disk->queue;
+       struct request_sense sense;
        struct request *rq;
        struct bio *bio;
        unsigned int len;
@@ -2184,7 +2185,14 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info 
*cdi, __u8 __user *ubuf,
                        ret = PTR_ERR(rq);
                        break;
                }
-               blk_rq_set_block_pc(rq);
+
+               memset(&sense, 0, sizeof(sense));
+
+               ret = blk_rq_set_block_pc(rq, 10, (u8 *)&sense, GFP_KERNEL);
+               if (ret) {
+                       blk_put_request(rq);
+                       break;
+               }
 
                ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
                if (ret) {
@@ -2192,25 +2200,23 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info 
*cdi, __u8 __user *ubuf,
                        break;
                }
 
-               rq->cmd[0] = GPCMD_READ_CD;
-               rq->cmd[1] = 1 << 2;
-               rq->cmd[2] = (lba >> 24) & 0xff;
-               rq->cmd[3] = (lba >> 16) & 0xff;
-               rq->cmd[4] = (lba >>  8) & 0xff;
-               rq->cmd[5] = lba & 0xff;
-               rq->cmd[6] = (nr >> 16) & 0xff;
-               rq->cmd[7] = (nr >>  8) & 0xff;
-               rq->cmd[8] = nr & 0xff;
-               rq->cmd[9] = 0xf8;
-
-               rq->cmd_len = 12;
+               rq->block_pc->cmd[0] = GPCMD_READ_CD;
+               rq->block_pc->cmd[1] = 1 << 2;
+               rq->block_pc->cmd[2] = (lba >> 24) & 0xff;
+               rq->block_pc->cmd[3] = (lba >> 16) & 0xff;
+               rq->block_pc->cmd[4] = (lba >>  8) & 0xff;
+               rq->block_pc->cmd[5] = lba & 0xff;
+               rq->block_pc->cmd[6] = (nr >> 16) & 0xff;
+               rq->block_pc->cmd[7] = (nr >>  8) & 0xff;
+               rq->block_pc->cmd[8] = nr & 0xff;
+               rq->block_pc->cmd[9] = 0xf8;
+
                rq->timeout = 60 * HZ;
                bio = rq->bio;
 
                if (blk_execute_rq(q, cdi->disk, rq, 0)) {
-                       struct request_sense *s = rq->sense;
                        ret = -EIO;
-                       cdi->last_sense = s->sense_key;
+                       cdi->last_sense = sense.sense_key;
                }
 
                if (blk_rq_unmap_user(bio))
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8001fe9..17df896 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1069,6 +1069,7 @@ static void dm_end_request(struct request *clone, int 
error)
        struct mapped_device *md = tio->md;
        struct request *rq = tio->orig;
 
+#if 0
        if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
                rq->errors = clone->errors;
                rq->resid_len = clone->resid_len;
@@ -1081,6 +1082,7 @@ static void dm_end_request(struct request *clone, int 
error)
                         */
                        rq->sense_len = clone->sense_len;
        }
+#endif
 
        free_rq_clone(clone);
        blk_end_request_all(rq, error);
@@ -1773,9 +1775,11 @@ static int setup_clone(struct request *clone, struct 
request *rq,
        if (r)
                return r;
 
+#if 0
        clone->cmd = rq->cmd;
        clone->cmd_len = rq->cmd_len;
        clone->sense = rq->sense;
+#endif
        clone->end_io = end_clone_request;
        clone->end_io_data = tio;
 
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 5bdaae1..34127ac 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -2321,8 +2321,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, 
struct sas_rphy *rphy,
                SmpPassthroughReply_t *smprep;
 
                smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
-               memcpy(req->sense, smprep, sizeof(*smprep));
-               req->sense_len = sizeof(*smprep);
+               memcpy(req->block_pc->sense, smprep, sizeof(*smprep));
+               req->block_pc->sense_len = sizeof(*smprep);
                req->resid_len = 0;
                rsp->resid_len -= smprep->ResponseDataLength;
        } else {
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 854b568..9d2d781 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -107,7 +107,7 @@ static int realloc_buffer(struct alua_dh_data *h, unsigned 
len)
 }
 
 static struct request *get_alua_req(struct scsi_device *sdev,
-                                   void *buffer, unsigned buflen, int rw)
+               struct alua_dh_data *h, unsigned buflen, int rw)
 {
        struct request *rq;
        struct request_queue *q = sdev->request_queue;
@@ -119,9 +119,16 @@ static struct request *get_alua_req(struct scsi_device 
*sdev,
                            "%s: blk_get_request failed\n", __func__);
                return NULL;
        }
-       blk_rq_set_block_pc(rq);
 
-       if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
+       memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+       h->senselen = 0;
+
+       if (blk_rq_set_block_pc(rq, 16, h->sense, GFP_NOIO)) {
+               blk_put_request(rq);
+               return NULL;
+       }
+
+       if (buflen && blk_rq_map_kern(q, rq, h->buff, buflen, GFP_NOIO)) {
                blk_put_request(rq);
                sdev_printk(KERN_INFO, sdev,
                            "%s: blk_rq_map_kern failed\n", __func__);
@@ -145,27 +152,23 @@ static int submit_vpd_inquiry(struct scsi_device *sdev, 
struct alua_dh_data *h)
        struct request *rq;
        int err = SCSI_DH_RES_TEMP_UNAVAIL;
 
-       rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
+       rq = get_alua_req(sdev, h, h->bufflen, READ);
        if (!rq)
                goto done;
 
        /* Prepare the command. */
-       rq->cmd[0] = INQUIRY;
-       rq->cmd[1] = 1;
-       rq->cmd[2] = 0x83;
-       rq->cmd[4] = h->bufflen;
-       rq->cmd_len = COMMAND_SIZE(INQUIRY);
-
-       rq->sense = h->sense;
-       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       rq->sense_len = h->senselen = 0;
+       rq->block_pc->cmd[0] = INQUIRY;
+       rq->block_pc->cmd[1] = 1;
+       rq->block_pc->cmd[2] = 0x83;
+       rq->block_pc->cmd[4] = h->bufflen;
+       rq->block_pc->cmd_len = COMMAND_SIZE(INQUIRY);
 
        err = blk_execute_rq(rq->q, NULL, rq, 1);
        if (err == -EIO) {
                sdev_printk(KERN_INFO, sdev,
                            "%s: evpd inquiry failed with %x\n",
                            ALUA_DH_NAME, rq->errors);
-               h->senselen = rq->sense_len;
+               h->senselen = rq->block_pc->sense_len;
                err = SCSI_DH_IO;
        }
        blk_put_request(rq);
@@ -183,32 +186,28 @@ static unsigned submit_rtpg(struct scsi_device *sdev, 
struct alua_dh_data *h,
        struct request *rq;
        int err = SCSI_DH_RES_TEMP_UNAVAIL;
 
-       rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
+       rq = get_alua_req(sdev, h, h->bufflen, READ);
        if (!rq)
                goto done;
 
        /* Prepare the command. */
-       rq->cmd[0] = MAINTENANCE_IN;
+       rq->block_pc->cmd[0] = MAINTENANCE_IN;
        if (rtpg_ext_hdr_req)
-               rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
+               rq->block_pc->cmd[1] = MI_REPORT_TARGET_PGS | 
MI_EXT_HDR_PARAM_FMT;
        else
-               rq->cmd[1] = MI_REPORT_TARGET_PGS;
-       rq->cmd[6] = (h->bufflen >> 24) & 0xff;
-       rq->cmd[7] = (h->bufflen >> 16) & 0xff;
-       rq->cmd[8] = (h->bufflen >>  8) & 0xff;
-       rq->cmd[9] = h->bufflen & 0xff;
-       rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
-
-       rq->sense = h->sense;
-       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       rq->sense_len = h->senselen = 0;
+               rq->block_pc->cmd[1] = MI_REPORT_TARGET_PGS;
+       rq->block_pc->cmd[6] = (h->bufflen >> 24) & 0xff;
+       rq->block_pc->cmd[7] = (h->bufflen >> 16) & 0xff;
+       rq->block_pc->cmd[8] = (h->bufflen >>  8) & 0xff;
+       rq->block_pc->cmd[9] = h->bufflen & 0xff;
+       rq->block_pc->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
 
        err = blk_execute_rq(rq->q, NULL, rq, 1);
        if (err == -EIO) {
                sdev_printk(KERN_INFO, sdev,
                            "%s: rtpg failed with %x\n",
                            ALUA_DH_NAME, rq->errors);
-               h->senselen = rq->sense_len;
+               h->senselen = rq->block_pc->sense_len;
                err = SCSI_DH_IO;
        }
        blk_put_request(rq);
@@ -237,7 +236,7 @@ static void stpg_endio(struct request *req, int error)
                goto done;
        }
 
-       if (req->sense_len > 0) {
+       if (req->block_pc->sense_len > 0) {
                err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
                                           &sense_hdr);
                if (!err) {
@@ -293,22 +292,19 @@ static unsigned submit_stpg(struct alua_dh_data *h)
        h->buff[6] = (h->group_id >> 8) & 0xff;
        h->buff[7] = h->group_id & 0xff;
 
-       rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
+       rq = get_alua_req(sdev, h, stpg_len, WRITE);
        if (!rq)
                return SCSI_DH_RES_TEMP_UNAVAIL;
 
        /* Prepare the command. */
-       rq->cmd[0] = MAINTENANCE_OUT;
-       rq->cmd[1] = MO_SET_TARGET_PGS;
-       rq->cmd[6] = (stpg_len >> 24) & 0xff;
-       rq->cmd[7] = (stpg_len >> 16) & 0xff;
-       rq->cmd[8] = (stpg_len >>  8) & 0xff;
-       rq->cmd[9] = stpg_len & 0xff;
-       rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
-
-       rq->sense = h->sense;
-       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       rq->sense_len = h->senselen = 0;
+       rq->block_pc->cmd[0] = MAINTENANCE_OUT;
+       rq->block_pc->cmd[1] = MO_SET_TARGET_PGS;
+       rq->block_pc->cmd[6] = (stpg_len >> 24) & 0xff;
+       rq->block_pc->cmd[7] = (stpg_len >> 16) & 0xff;
+       rq->block_pc->cmd[8] = (stpg_len >>  8) & 0xff;
+       rq->block_pc->cmd[9] = stpg_len & 0xff;
+       rq->block_pc->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
+
        rq->end_io_data = h;
 
        blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c 
b/drivers/scsi/device_handler/scsi_dh_emc.c
index 6ed1caa..a009bf2 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -267,8 +267,8 @@ out:
  * Uses data and sense buffers in hardware handler context structure and
  * assumes serial servicing of commands, both issuance and completion.
  */
-static struct request *get_req(struct scsi_device *sdev, int cmd,
-                               unsigned char *buffer)
+static struct request *get_req(struct scsi_device *sdev,
+               struct clariion_dh_data *csdev, int cmd)
 {
        struct request *rq;
        int len = 0;
@@ -280,25 +280,31 @@ static struct request *get_req(struct scsi_device *sdev, 
int cmd,
                return NULL;
        }
 
-       blk_rq_set_block_pc(rq);
-       rq->cmd_len = COMMAND_SIZE(cmd);
-       rq->cmd[0] = cmd;
+       memset(csdev->sense, 0, SCSI_SENSE_BUFFERSIZE);
+       csdev->senselen = 0;
+
+       if (blk_rq_set_block_pc(rq, COMMAND_SIZE(cmd),
+                       csdev->sense, GFP_NOIO)) {
+               blk_put_request(rq);
+               return NULL;
+       }
+       rq->block_pc->cmd[0] = cmd;
 
        switch (cmd) {
        case MODE_SELECT:
                len = sizeof(short_trespass);
-               rq->cmd[1] = 0x10;
-               rq->cmd[4] = len;
+               rq->block_pc->cmd[1] = 0x10;
+               rq->block_pc->cmd[4] = len;
                break;
        case MODE_SELECT_10:
                len = sizeof(long_trespass);
-               rq->cmd[1] = 0x10;
-               rq->cmd[8] = len;
+               rq->block_pc->cmd[1] = 0x10;
+               rq->block_pc->cmd[8] = len;
                break;
        case INQUIRY:
                len = CLARIION_BUFFER_SIZE;
-               rq->cmd[4] = len;
-               memset(buffer, 0, len);
+               rq->block_pc->cmd[4] = len;
+               memset(csdev->buffer, 0, len);
                break;
        default:
                BUG_ON(1);
@@ -310,7 +316,7 @@ static struct request *get_req(struct scsi_device *sdev, 
int cmd,
        rq->timeout = CLARIION_TIMEOUT;
        rq->retries = CLARIION_RETRIES;
 
-       if (blk_rq_map_kern(rq->q, rq, buffer, len, GFP_NOIO)) {
+       if (blk_rq_map_kern(rq->q, rq, csdev->buffer, len, GFP_NOIO)) {
                blk_put_request(rq);
                return NULL;
        }
@@ -321,20 +327,16 @@ static struct request *get_req(struct scsi_device *sdev, 
int cmd,
 static int send_inquiry_cmd(struct scsi_device *sdev, int page,
                            struct clariion_dh_data *csdev)
 {
-       struct request *rq = get_req(sdev, INQUIRY, csdev->buffer);
+       struct request *rq = get_req(sdev, csdev, INQUIRY);
        int err;
 
        if (!rq)
                return SCSI_DH_RES_TEMP_UNAVAIL;
 
-       rq->sense = csdev->sense;
-       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       rq->sense_len = csdev->senselen = 0;
-
-       rq->cmd[0] = INQUIRY;
+       rq->block_pc->cmd[0] = INQUIRY;
        if (page != 0) {
-               rq->cmd[1] = 1;
-               rq->cmd[2] = page;
+               rq->block_pc->cmd[1] = 1;
+               rq->block_pc->cmd[2] = page;
        }
        err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
        if (err == -EIO) {
@@ -342,7 +344,7 @@ static int send_inquiry_cmd(struct scsi_device *sdev, int 
page,
                            "%s: failed to send %s INQUIRY: %x\n",
                            CLARIION_NAME, page?"EVPD":"standard",
                            rq->errors);
-               csdev->senselen = rq->sense_len;
+               csdev->senselen = rq->block_pc->sense_len;
                err = SCSI_DH_IO;
        }
 
@@ -376,17 +378,13 @@ static int send_trespass_cmd(struct scsi_device *sdev,
        BUG_ON((len > CLARIION_BUFFER_SIZE));
        memcpy(csdev->buffer, page22, len);
 
-       rq = get_req(sdev, cmd, csdev->buffer);
+       rq = get_req(sdev, csdev, cmd);
        if (!rq)
                return SCSI_DH_RES_TEMP_UNAVAIL;
 
-       rq->sense = csdev->sense;
-       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       rq->sense_len = csdev->senselen = 0;
-
        err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
        if (err == -EIO) {
-               if (rq->sense_len) {
+               if (rq->block_pc->sense_len) {
                        err = trespass_endio(sdev, csdev->sense);
                } else {
                        sdev_printk(KERN_INFO, sdev,
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c 
b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 485d995..06f2c36 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -119,19 +119,21 @@ retry:
        if (IS_ERR(req))
                return SCSI_DH_RES_TEMP_UNAVAIL;
 
-       blk_rq_set_block_pc(req);
+       memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+
+       ret = blk_rq_set_block_pc(req, 16, h->sense, GFP_NOIO);
+       if (ret)
+               goto out;
+
        req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
                          REQ_FAILFAST_DRIVER;
-       req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
-       req->cmd[0] = TEST_UNIT_READY;
+       req->block_pc->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
+       req->block_pc->cmd[0] = TEST_UNIT_READY;
        req->timeout = HP_SW_TIMEOUT;
-       req->sense = h->sense;
-       memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       req->sense_len = 0;
 
        ret = blk_execute_rq(req->q, NULL, req, 1);
        if (ret == -EIO) {
-               if (req->sense_len > 0) {
+               if (req->block_pc->sense_len > 0) {
                        ret = tur_done(sdev, h->sense);
                } else {
                        sdev_printk(KERN_WARNING, sdev,
@@ -152,8 +154,8 @@ retry:
                ret = SCSI_DH_OK;
        }
 
+out:
        blk_put_request(req);
-
        return ret;
 }
 
@@ -212,7 +214,7 @@ static void start_stop_endio(struct request *req, int error)
                goto done;
        }
 
-       if (req->sense_len > 0) {
+       if (req->block_pc->sense_len > 0) {
                err = start_done(h->sdev, h->sense);
                if (err == SCSI_DH_RETRY) {
                        err = SCSI_DH_IO;
@@ -249,16 +251,20 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
        if (IS_ERR(req))
                return SCSI_DH_RES_TEMP_UNAVAIL;
 
-       blk_rq_set_block_pc(req);
+       memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+
+       if (blk_rq_set_block_pc(req, 16, h->sense, GFP_ATOMIC) < 0) {
+               blk_put_request(req);
+               return SCSI_DH_RES_TEMP_UNAVAIL;
+       }
+               
        req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
                          REQ_FAILFAST_DRIVER;
-       req->cmd_len = COMMAND_SIZE(START_STOP);
-       req->cmd[0] = START_STOP;
-       req->cmd[4] = 1;        /* Start spin cycle */
+       req->block_pc->cmd_len = COMMAND_SIZE(START_STOP);
+       req->block_pc->cmd[0] = START_STOP;
+       req->block_pc->cmd[4] = 1;      /* Start spin cycle */
        req->timeout = HP_SW_TIMEOUT;
-       req->sense = h->sense;
-       memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       req->sense_len = 0;
+
        req->end_io_data = h;
 
        blk_execute_rq_nowait(req->q, NULL, req, 1, start_stop_endio);
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c 
b/drivers/scsi/device_handler/scsi_dh_rdac.c
index b46ace3..78552ae 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -266,7 +266,7 @@ static inline struct rdac_dh_data *get_rdac_data(struct 
scsi_device *sdev)
 }
 
 static struct request *get_rdac_req(struct scsi_device *sdev,
-                       void *buffer, unsigned buflen, int rw)
+               struct rdac_dh_data *h, void *buffer, unsigned buflen, int rw)
 {
        struct request *rq;
        struct request_queue *q = sdev->request_queue;
@@ -278,7 +278,12 @@ static struct request *get_rdac_req(struct scsi_device 
*sdev,
                                "get_rdac_req: blk_get_request failed.\n");
                return NULL;
        }
-       blk_rq_set_block_pc(rq);
+
+       memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+       if (blk_rq_set_block_pc(rq, 16, h->sense, GFP_NOIO)) {
+               blk_put_request(rq);
+               return NULL;
+       }
 
        if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
                blk_put_request(rq);
@@ -336,24 +341,20 @@ static struct request *rdac_failover_get(struct 
scsi_device *sdev,
        }
 
        /* get request for block layer packet command */
-       rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE);
+       rq = get_rdac_req(sdev, h, &h->ctlr->mode_select, data_size, WRITE);
        if (!rq)
                return NULL;
 
        /* Prepare the command. */
        if (h->ctlr->use_ms10) {
-               rq->cmd[0] = MODE_SELECT_10;
-               rq->cmd[7] = data_size >> 8;
-               rq->cmd[8] = data_size & 0xff;
+               rq->block_pc->cmd[0] = MODE_SELECT_10;
+               rq->block_pc->cmd[7] = data_size >> 8;
+               rq->block_pc->cmd[8] = data_size & 0xff;
        } else {
-               rq->cmd[0] = MODE_SELECT;
-               rq->cmd[4] = data_size;
+               rq->block_pc->cmd[0] = MODE_SELECT;
+               rq->block_pc->cmd[4] = data_size;
        }
-       rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
-
-       rq->sense = h->sense;
-       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       rq->sense_len = 0;
+       rq->block_pc->cmd_len = COMMAND_SIZE(rq->block_pc->cmd[0]);
 
        return rq;
 }
@@ -409,20 +410,16 @@ static int submit_inquiry(struct scsi_device *sdev, int 
page_code,
        struct request_queue *q = sdev->request_queue;
        int err = SCSI_DH_RES_TEMP_UNAVAIL;
 
-       rq = get_rdac_req(sdev, &h->inq, len, READ);
+       rq = get_rdac_req(sdev, h, &h->inq, len, READ);
        if (!rq)
                goto done;
 
        /* Prepare the command. */
-       rq->cmd[0] = INQUIRY;
-       rq->cmd[1] = 1;
-       rq->cmd[2] = page_code;
-       rq->cmd[4] = len;
-       rq->cmd_len = COMMAND_SIZE(INQUIRY);
-
-       rq->sense = h->sense;
-       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-       rq->sense_len = 0;
+       rq->block_pc->cmd[0] = INQUIRY;
+       rq->block_pc->cmd[1] = 1;
+       rq->block_pc->cmd[2] = page_code;
+       rq->block_pc->cmd[4] = len;
+       rq->block_pc->cmd_len = COMMAND_SIZE(INQUIRY);
 
        err = blk_execute_rq(q, NULL, rq, 1);
        if (err == -EIO)
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c 
b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index ff2500a..672597c 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -2094,8 +2094,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct 
sas_rphy *rphy,
                    ioc->name, __func__,
                    le16_to_cpu(mpi_reply->ResponseDataLength)));
 
-               memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
-               req->sense_len = sizeof(*mpi_reply);
+               memcpy(req->block_pc->sense, mpi_reply, sizeof(*mpi_reply));
+               req->block_pc->sense_len = sizeof(*mpi_reply);
                req->resid_len = 0;
                rsp->resid_len -=
                    le16_to_cpu(mpi_reply->ResponseDataLength);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c 
b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index efb98af..b558442 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -2054,8 +2054,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct 
sas_rphy *rphy,
                    ioc->name, __func__,
                    le16_to_cpu(mpi_reply->ResponseDataLength)));
 
-               memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
-               req->sense_len = sizeof(*mpi_reply);
+               memcpy(req->block_pc->sense, mpi_reply, sizeof(*mpi_reply));
+               req->block_pc->sense_len = sizeof(*mpi_reply);
                req->resid_len = 0;
                rsp->resid_len -=
                    le16_to_cpu(mpi_reply->ResponseDataLength);
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 0cccd60..055714d 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -480,7 +480,7 @@ static void _set_error_resid(struct osd_request *or, struct 
request *req,
 {
        or->async_error = error;
        or->req_errors = req->errors ? : error;
-       or->sense_len = req->sense_len;
+       or->sense_len = req->block_pc->sense_len;
        if (or->out.req)
                or->out.residual = or->out.req->resid_len;
        if (or->in.req)
@@ -1563,16 +1563,8 @@ static struct request *_make_request(struct 
request_queue *q, bool has_write,
 {
        if (oii->bio)
                return blk_make_request(q, oii->bio, flags);
-       else {
-               struct request *req;
-
-               req = blk_get_request(q, has_write ? WRITE : READ, flags);
-               if (IS_ERR(req))
-                       return req;
-
-               blk_rq_set_block_pc(req);
-               return req;
-       }
+       else 
+               return blk_get_request(q, has_write ? WRITE : READ, flags);
 }
 
 static int _init_blk_request(struct osd_request *or,
@@ -1590,13 +1582,22 @@ static int _init_blk_request(struct osd_request *or,
                goto out;
        }
 
+       /* 
+        * XXX: allocating max size here to avoid having to reorder all
+        * the code below.
+        */
+       ret = blk_rq_set_block_pc(req, 255, req->block_pc->sense, flags);
+       if (ret) {
+               blk_put_request(req);
+               goto out;
+       }
+
        or->request = req;
        req->cmd_flags |= REQ_QUIET;
 
        req->timeout = or->timeout;
        req->retries = or->retries;
-       req->sense = or->sense;
-       req->sense_len = 0;
+       req->block_pc->sense_len = 0;
 
        if (has_out) {
                or->out.req = req;
@@ -1608,7 +1609,6 @@ static int _init_blk_request(struct osd_request *or,
                                ret = PTR_ERR(req);
                                goto out;
                        }
-                       blk_rq_set_block_pc(req);
                        or->in.req = or->request->next_rq = req;
                }
        } else if (has_in)
@@ -1695,8 +1695,8 @@ int osd_finalize_request(struct osd_request *or,
 
        osd_sec_sign_cdb(&or->cdb, cap_key);
 
-       or->request->cmd = or->cdb.buff;
-       or->request->cmd_len = _osd_req_cdb_len(or);
+       memcpy(or->request->block_pc->cmd, or->cdb.buff, _osd_req_cdb_len(or));
+       or->request->block_pc->cmd_len = _osd_req_cdb_len(or);
 
        return 0;
 }
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 5033223..79b57fe 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -367,7 +367,9 @@ static int osst_execute(struct osst_request *SRpnt, const 
unsigned char *cmd,
        if (IS_ERR(req))
                return DRIVER_ERROR << 24;
 
-       blk_rq_set_block_pc(req);
+       err = blk_rq_set_block_pc(req, cmd_len, SRpnt->sense, GFP_KERNEL);
+       if (err)
+               goto free_req;
        req->cmd_flags |= REQ_QUIET;
 
        SRpnt->bio = NULL;
@@ -404,11 +406,7 @@ static int osst_execute(struct osst_request *SRpnt, const 
unsigned char *cmd,
                        goto free_req;
        }
 
-       req->cmd_len = cmd_len;
-       memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
-       memcpy(req->cmd, cmd, req->cmd_len);
-       req->sense = SRpnt->sense;
-       req->sense_len = 0;
+       memcpy(req->block_pc->cmd, cmd, cmd_len);
        req->timeout = timeout;
        req->retries = retries;
        req->end_io_data = SRpnt;
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 2e2bb6f..f6bf256 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -909,7 +909,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 
        bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
            sizeof(response) + sizeof(uint8_t);
-       fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
+       fw_sts_ptr = ((uint8_t *)bsg_job->req->block_pc->sense) +
            sizeof(struct fc_bsg_reply);
        memcpy(fw_sts_ptr, response, sizeof(response));
        fw_sts_ptr += sizeof(response);
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 6dc14cd..724eaa4 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1418,7 +1418,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que 
*req,
                            type, sp->handle, comp_status, fw_status[1], 
fw_status[2],
                            le16_to_cpu(((struct els_sts_entry_24xx *)
                                pkt)->total_byte_count));
-                       fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + 
sizeof(struct fc_bsg_reply);
+                       fw_sts_ptr = ((uint8_t*)bsg_job->req->block_pc->sense) +
+                                       sizeof(struct fc_bsg_reply);
                        memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
                }
                else {
@@ -1432,7 +1433,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que 
*req,
                                    pkt)->error_subcode_2));
                        res = DID_ERROR << 16;
                        bsg_job->reply->reply_payload_rcv_len = 0;
-                       fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + 
sizeof(struct fc_bsg_reply);
+                       fw_sts_ptr = ((uint8_t*)bsg_job->req->block_pc->sense) +
+                                       sizeof(struct fc_bsg_reply);
                        memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
                }
                ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056,
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 6d190b4..2ac1886 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -2242,7 +2242,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct 
req_que *req,
                memcpy(fstatus.reserved_3,
                    pkt->reserved_2, 20 * sizeof(uint8_t));
 
-               fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
+               fw_sts_ptr = ((uint8_t *)bsg_job->req->block_pc->sense) +
                    sizeof(struct fc_bsg_reply);
 
                memcpy(fw_sts_ptr, (uint8_t *)&fstatus,
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index c95a4e9..85d659e 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1968,16 +1968,18 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
        if (IS_ERR(req))
                return;
 
-       blk_rq_set_block_pc(req);
-
-       req->cmd[0] = ALLOW_MEDIUM_REMOVAL;
-       req->cmd[1] = 0;
-       req->cmd[2] = 0;
-       req->cmd[3] = 0;
-       req->cmd[4] = SCSI_REMOVAL_PREVENT;
-       req->cmd[5] = 0;
+       if (blk_rq_set_block_pc(req, COMMAND_SIZE(ALLOW_MEDIUM_REMOVAL),
+                               NULL, GFP_KERNEL) < 0) {
+               blk_put_request(req);
+               return;
+       }
 
-       req->cmd_len = COMMAND_SIZE(req->cmd[0]);
+       req->block_pc->cmd[0] = ALLOW_MEDIUM_REMOVAL;
+       req->block_pc->cmd[1] = 0;
+       req->block_pc->cmd[2] = 0;
+       req->block_pc->cmd[3] = 0;
+       req->block_pc->cmd[4] = SCSI_REMOVAL_PREVENT;
+       req->block_pc->cmd[5] = 0;
 
        req->cmd_flags |= REQ_QUIET;
        req->timeout = 10 * HZ;
@@ -2332,8 +2334,6 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
        blk_rq_init(NULL, &req);
        scmd->request = &req;
 
-       scmd->cmnd = req.cmd;
-
        scmd->scsi_done         = scsi_reset_provider_done_command;
        memset(&scmd->sdb, 0, sizeof(scmd->sdb));
 
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index b1a2631..29e0cd6 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -224,16 +224,15 @@ int scsi_execute(struct scsi_device *sdev, const unsigned 
char *cmd,
        req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
        if (IS_ERR(req))
                return ret;
-       blk_rq_set_block_pc(req);
+
+       if (blk_rq_set_block_pc(req, COMMAND_SIZE(cmd[0]), sense, GFP_KERNEL))
+               goto out;
 
        if (bufflen &&  blk_rq_map_kern(sdev->request_queue, req,
                                        buffer, bufflen, __GFP_WAIT))
                goto out;
 
-       req->cmd_len = COMMAND_SIZE(cmd[0]);
-       memcpy(req->cmd, cmd, req->cmd_len);
-       req->sense = sense;
-       req->sense_len = 0;
+       memcpy(req->block_pc->cmd, cmd, req->block_pc->cmd_len);
        req->retries = retries;
        req->timeout = timeout;
        req->cmd_flags |= flags | REQ_QUIET | REQ_PREEMPT;
@@ -835,7 +834,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int 
good_bytes)
 
        if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block 
level */
                if (result) {
-                       if (sense_valid && req->sense) {
+                       if (sense_valid && req->block_pc->sense) {
                                /*
                                 * SG_IO wants current and deferred errors
                                 */
@@ -843,8 +842,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int 
good_bytes)
 
                                if (len > SCSI_SENSE_BUFFERSIZE)
                                        len = SCSI_SENSE_BUFFERSIZE;
-                               memcpy(req->sense, cmd->sense_buffer,  len);
-                               req->sense_len = len;
+                               memcpy(req->block_pc->sense, cmd->sense_buffer, 
 len);
+                               req->block_pc->sense_len = len;
                        }
                        if (!sense_deferred)
                                error = __scsi_error_from_host_byte(cmd, 
result);
@@ -1208,7 +1207,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct 
scsi_device *sdev,
        cmd->tag = req->tag;
        cmd->request = req;
 
-       cmd->cmnd = req->cmd;
        cmd->prot_op = SCSI_PROT_NORMAL;
 
        return cmd;
@@ -1234,7 +1232,8 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device 
*sdev, struct request *req)
                memset(&cmd->sdb, 0, sizeof(cmd->sdb));
        }
 
-       cmd->cmd_len = req->cmd_len;
+       cmd->cmd_len = req->block_pc->cmd_len;
+       cmd->cmnd = req->block_pc->cmd;
        cmd->transfersize = blk_rq_bytes(req);
        cmd->allowed = req->retries;
        return BLKPREP_OK;
@@ -1255,7 +1254,7 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, 
struct request *req)
                        return ret;
        }
 
-       memset(cmd->cmnd, 0, BLK_MAX_CDB);
+       cmd->cmnd = cmd->__cmnd;
        return scsi_cmd_to_driver(cmd)->init_command(cmd);
 }
 
@@ -1911,7 +1910,6 @@ static int scsi_mq_prep_fn(struct request *req)
 
        cmd->tag = req->tag;
 
-       cmd->cmnd = req->cmd;
        cmd->prot_op = SCSI_PROT_NORMAL;
 
        INIT_LIST_HEAD(&cmd->list);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 24eaaf6..6024e6c 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3593,9 +3593,9 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
 
        if (err < 0)
                /* we're only returning the result field in the reply */
-               job->req->sense_len = sizeof(uint32_t);
+               job->req->block_pc->sense_len = sizeof(uint32_t);
        else
-               job->req->sense_len = job->reply_len;
+               job->req->block_pc->sense_len = job->reply_len;
 
        /* we assume all request payload was transferred, residual == 0 */
        req->resid_len = 0;
@@ -3725,9 +3725,9 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport 
*rport,
        if (i->f->dd_bsg_size)
                job->dd_data = (void *)&job[1];
        spin_lock_init(&job->job_lock);
-       job->request = (struct fc_bsg_request *)req->cmd;
-       job->request_len = req->cmd_len;
-       job->reply = req->sense;
+       job->request = (struct fc_bsg_request *)req->block_pc->cmd;
+       job->request_len = req->block_pc->cmd_len;
+       job->reply = req->block_pc->sense;
        job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
                                                 * allocated */
        if (req->bio) {
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index dcc4244..7883fd9 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -126,9 +126,6 @@ static DEFINE_IDA(sd_index_ida);
  * object after last put) */
 static DEFINE_MUTEX(sd_ref_mutex);
 
-static struct kmem_cache *sd_cdb_cache;
-static mempool_t *sd_cdb_pool;
-
 static const char *sd_cache_types[] = {
        "write through", "none", "write back",
        "write back, no read (daft)"
@@ -1016,13 +1013,6 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd 
*SCpnt)
                protect = 0;
 
        if (protect && sdkp->protection_type == SD_DIF_TYPE2_PROTECTION) {
-               SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC);
-
-               if (unlikely(SCpnt->cmnd == NULL)) {
-                       ret = BLKPREP_DEFER;
-                       goto out;
-               }
-
                SCpnt->cmd_len = SD_EXT_CDB_SIZE;
                memset(SCpnt->cmnd, 0, SCpnt->cmd_len);
                SCpnt->cmnd[0] = VARIABLE_LENGTH_CMD;
@@ -1138,12 +1128,6 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
 
        if (rq->cmd_flags & REQ_DISCARD)
                __free_page(rq->completion_data);
-
-       if (SCpnt->cmnd != rq->cmd) {
-               mempool_free(SCpnt->cmnd, sd_cdb_pool);
-               SCpnt->cmnd = NULL;
-               SCpnt->cmd_len = 0;
-       }
 }
 
 /**
@@ -3221,38 +3205,17 @@ static int __init init_sd(void)
 
        err = class_register(&sd_disk_class);
        if (err)
-               goto err_out;
-
-       sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE,
-                                        0, 0, NULL);
-       if (!sd_cdb_cache) {
-               printk(KERN_ERR "sd: can't init extended cdb cache\n");
-               err = -ENOMEM;
-               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;
-       }
+               goto out_unregister_blkdev;
 
        err = scsi_register_driver(&sd_template.gendrv);
        if (err)
-               goto err_out_driver;
+               goto out_unregister_class;
 
        return 0;
 
-err_out_driver:
-       mempool_destroy(sd_cdb_pool);
-
-err_out_cache:
-       kmem_cache_destroy(sd_cdb_cache);
-
-err_out_class:
+out_unregister_class:
        class_unregister(&sd_disk_class);
-err_out:
+out_unregister_blkdev:
        for (i = 0; i < SD_MAJORS; i++)
                unregister_blkdev(sd_major(i), "sd");
        return err;
@@ -3270,8 +3233,6 @@ static void __exit exit_sd(void)
        SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
 
        scsi_unregister_driver(&sd_template.gendrv);
-       mempool_destroy(sd_cdb_pool);
-       kmem_cache_destroy(sd_cdb_cache);
 
        class_unregister(&sd_disk_class);
 
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9d7b7db..a266319 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1297,7 +1297,7 @@ sg_rq_end_io(struct request *rq, int uptodate)
        if (unlikely(atomic_read(&sdp->detaching)))
                pr_info("%s: device detaching\n", __func__);
 
-       sense = rq->sense;
+       sense = rq->block_pc->sense;
        result = rq->errors;
        resid = rq->resid_len;
 
@@ -1342,8 +1342,6 @@ sg_rq_end_io(struct request *rq, int uptodate)
         * blk_rq_unmap_user() can be called from user context.
         */
        srp->rq = NULL;
-       if (rq->cmd != rq->__cmd)
-               kfree(rq->cmd);
        __blk_put_request(rq->q, rq);
 
        write_lock_irqsave(&sfp->rq_list_lock, iflags);
@@ -1701,16 +1699,16 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
                return PTR_ERR(rq);
        }
 
-       blk_rq_set_block_pc(rq);
+       res = blk_rq_set_block_pc(rq, hp->cmd_len, srp->sense_b, GFP_KERNEL);
+       if (res) {
+               blk_put_request(rq);
+               return res;
+       }
 
-       if (hp->cmd_len > BLK_MAX_CDB)
-               rq->cmd = long_cmdp;
-       memcpy(rq->cmd, cmd, hp->cmd_len);
-       rq->cmd_len = hp->cmd_len;
+       memcpy(rq->block_pc->cmd, cmd, hp->cmd_len);
 
        srp->rq = rq;
        rq->end_io_data = srp;
-       rq->sense = srp->sense_b;
        rq->retries = SG_DEFAULT_RETRIES;
 
        if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))
@@ -1785,11 +1783,8 @@ sg_finish_rem_req(Sg_request *srp)
        if (srp->bio)
                ret = blk_rq_unmap_user(srp->bio);
 
-       if (srp->rq) {
-               if (srp->rq->cmd != srp->rq->__cmd)
-                       kfree(srp->rq->cmd);
+       if (srp->rq)
                blk_put_request(srp->rq);
-       }
 
        if (srp->res_used)
                sg_unlink_reserve(sfp, srp);
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 9a1c342..7b4445f 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -502,7 +502,10 @@ static int st_scsi_execute(struct st_request *SRpnt, const 
unsigned char *cmd,
        if (IS_ERR(req))
                return DRIVER_ERROR << 24;
 
-       blk_rq_set_block_pc(req);
+       err = blk_rq_set_block_pc(req, COMMAND_SIZE(cmd[0]), SRpnt->sense,
+                       GFP_KERNEL);
+       if (err)
+               goto out_put_request;
        req->cmd_flags |= REQ_QUIET;
 
        mdata->null_mapped = 1;
@@ -510,24 +513,22 @@ static int st_scsi_execute(struct st_request *SRpnt, 
const unsigned char *cmd,
        if (bufflen) {
                err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
                                      GFP_KERNEL);
-               if (err) {
-                       blk_put_request(req);
-                       return DRIVER_ERROR << 24;
-               }
+               if (err)
+                       goto out_put_request;
        }
 
        SRpnt->bio = req->bio;
-       req->cmd_len = COMMAND_SIZE(cmd[0]);
-       memset(req->cmd, 0, BLK_MAX_CDB);
-       memcpy(req->cmd, cmd, req->cmd_len);
-       req->sense = SRpnt->sense;
-       req->sense_len = 0;
+       memcpy(req->block_pc->cmd, cmd, req->block_pc->cmd_len);
        req->timeout = timeout;
        req->retries = retries;
        req->end_io_data = SRpnt;
 
        blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
        return 0;
+
+out_put_request:
+       blk_put_request(req);
+       return DRIVER_ERROR << 24;
 }
 
 /* Do the scsi command. Waits until command performed if do_wait is true.
diff --git a/drivers/target/target_core_pscsi.c 
b/drivers/target/target_core_pscsi.c
index f6c954c..023accd 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -1064,8 +1064,6 @@ pscsi_execute_cmd(struct se_cmd *cmd)
                        ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                        goto fail;
                }
-
-               blk_rq_set_block_pc(req);
        } else {
                BUG_ON(!cmd->data_length);
 
@@ -1082,12 +1080,16 @@ pscsi_execute_cmd(struct se_cmd *cmd)
                }
        }
 
+       if (blk_rq_set_block_pc(req, scsi_command_size(pt->pscsi_cdb),
+                       &pt->pscsi_sense[0], GFP_KERNEL)) {
+               blk_put_request(req);
+               ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               goto fail;
+       }
+
        req->end_io = pscsi_req_done;
        req->end_io_data = cmd;
-       req->cmd_len = scsi_command_size(pt->pscsi_cdb);
-       req->cmd = &pt->pscsi_cdb[0];
-       req->sense = &pt->pscsi_sense[0];
-       req->sense_len = 0;
+       memcpy(req->block_pc->cmd, &pt->pscsi_cdb[0], req->block_pc->cmd_len);
        if (pdv->pdv_sd->type == TYPE_DISK)
                req->timeout = PS_TIMEOUT_DISK;
        else
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2da818a..e64a01b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -80,6 +80,16 @@ enum rq_cmd_type_bits {
 #define BLK_MAX_CDB    16
 
 /*
+ * when request is used as a packet command carrier
+ */
+struct block_pc_request {
+       unsigned short cmd_len;
+       unsigned int sense_len;
+       void *sense;
+       unsigned char cmd[];
+};
+
+/*
  * Try to put the fields that are referenced together in the same cacheline.
  *
  * If you modify this structure, make sure to update blk_rq_init() and
@@ -172,23 +182,19 @@ struct request {
        int tag;
        int errors;
 
-       /*
-        * when request is used as a packet command carrier
-        */
-       unsigned char __cmd[BLK_MAX_CDB];
-       unsigned char *cmd;
-       unsigned short cmd_len;
-
        unsigned int extra_len; /* length of alignment and padding */
-       unsigned int sense_len;
        unsigned int resid_len; /* residual count */
-       void *sense;
 
        unsigned long deadline;
        struct list_head timeout_list;
        unsigned int timeout;
        int retries;
 
+       union {
+               struct block_pc_request *block_pc;
+               void *drv_private;
+       };
+
        /*
         * completion callback.
         */
@@ -769,7 +775,8 @@ extern void __blk_put_request(struct request_queue *, 
struct request *);
 extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
 extern struct request *blk_make_request(struct request_queue *, struct bio *,
                                        gfp_t);
-extern void blk_rq_set_block_pc(struct request *);
+int blk_rq_set_block_pc(struct request *rq, unsigned short cmd_len,
+               u8 *sense, gfp_t gfp);
 extern void blk_requeue_request(struct request_queue *, struct request *);
 extern void blk_add_request_payload(struct request *rq, struct page *page,
                unsigned int len);
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index afc1343..8c63eca 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -105,7 +105,9 @@ struct compat_blk_user_trace_setup {
 
 static inline int blk_cmd_buf_len(struct request *rq)
 {
-       return (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? rq->cmd_len * 3 : 1;
+       if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
+               return rq->block_pc->cmd_len * 3;
+       return 1;
 }
 
 extern void blk_dump_cmd(char *buf, struct request *rq);
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 9fc1aec..de6d7d0 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -92,7 +92,7 @@ struct scsi_cmnd {
 
        /* These elements define the operation we are about to perform */
        unsigned char *cmnd;
-
+       unsigned char __cmnd[32];
 
        /* These elements define the operation we ultimately want to perform */
        struct scsi_data_buffer sdb;
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 483cecf..e87c0ac 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -720,7 +720,9 @@ static void blk_add_trace_rq(struct request_queue *q, 
struct request *rq,
        if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
                what |= BLK_TC_ACT(BLK_TC_PC);
                __blk_add_trace(bt, 0, nr_bytes, rq->cmd_flags,
-                               what, rq->errors, rq->cmd_len, rq->cmd);
+                               what, rq->errors,
+                               rq->block_pc->cmd_len,
+                               rq->block_pc->cmd);
        } else  {
                what |= BLK_TC_ACT(BLK_TC_FS);
                __blk_add_trace(bt, blk_rq_pos(rq), nr_bytes,
@@ -1762,14 +1764,17 @@ void blk_trace_remove_sysfs(struct device *dev)
 void blk_dump_cmd(char *buf, struct request *rq)
 {
        int i, end;
-       int len = rq->cmd_len;
-       unsigned char *cmd = rq->cmd;
+       int len;
+       unsigned char *cmd;
 
        if (rq->cmd_type != REQ_TYPE_BLOCK_PC) {
                buf[0] = '\0';
                return;
        }
 
+       len = rq->block_pc->cmd_len;
+       cmd = rq->block_pc->cmd;
+
        for (end = len - 1; end >= 0; end--)
                if (cmd[end])
                        break;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to