Skip to contentSkip to conversation

RFC: struct request cleanups

PATCH New Christoph Hellwig 4 participants 12 messages Apr 17, 2015 – May 11, 2015

Subsystems (16)
SCSI Block layer Tracing libata +12 more subsystems
lore
Share & tools
lore

Christoph Hellwig

author maintainer
#0 lore raw

The first 5 patches move the magic IDE request types into the old IDE driver to keep the core block code clean of them. Those are basically ready to merge, just like the 6th one which is a cleanup on it's own.

The real RFC is the last one which allocates the block_pc specific data separately in the callers instead of bloating every struct request with it. I always hated what we did, but with the upcoming split of nvme into transports and command sets we'll need a NVME equivalent of BLOCK_PC, and as NVMe was designed by crackmonkeys dreaming of an ATA controller the "command block" for NVME is even bigger than what we have to deal with in SCSI.

Note that the old IDE driver doesn't compile with the last patch yet as there are major nightmares to sort out, and BLOCK_PC passthrough with dm-multipath doesn't work yet either. If I get some general concensus on the approach I'll fix those of course.

author maintainer
#1 lore raw

PATCH 1/7 block: rename REQ_TYPE_SPECIAL to REQ_TYPE_DRV_PRIV

Signed-off-by Christoph Hellwig <hch at lst.de>
---
 drivers/block/nbd.c        | 2 +-
 drivers/block/paride/pd.c  | 4 ++--
 drivers/block/sx8.c        | 4 ++--
 drivers/block/virtio_blk.c | 6 +++---
 drivers/ide/ide-atapi.c    | 4 ++--
 drivers/ide/ide-cd.c       | 2 +-
 drivers/ide/ide-cd_ioctl.c | 2 +-
 drivers/ide/ide-devsets.c  | 2 +-
 drivers/ide/ide-eh.c       | 2 +-
 drivers/ide/ide-floppy.c   | 6 +++---
 drivers/ide/ide-io.c       | 4 ++--
 drivers/ide/ide-ioctls.c   | 2 +-
 drivers/ide/ide-park.c     | 4 ++--
 drivers/ide/ide-tape.c     | 4 ++--
 include/linux/blkdev.h     | 4 ++--
 15 files changed, 26 insertions(+), 26 deletions(-)
drivers/block/nbd.c +1 -1
index 39e5f7f..9cf52ac 100644
@@ -592,7 +592,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
 		fsync_bdev(bdev);
 		mutex_lock(&nbd->tx_lock);
 		blk_rq_init(NULL, &sreq);
-		sreq.cmd_type = REQ_TYPE_SPECIAL;
+		sreq.cmd_type = REQ_TYPE_DRV_PRIV;
 		nbd_cmd(&sreq) = NBD_CMD_DISC;
 
 		/* Check again after getting mutex back.  */
drivers/block/paride/pd.c +2 -2
index d48715b..dbb4da1 100644
@@ -442,7 +442,7 @@ static char *pd_buf;		/* buffer for request in progress */
 
 static enum action do_pd_io_start(void)
 {
-	if (pd_req->cmd_type == REQ_TYPE_SPECIAL) {
+	if (pd_req->cmd_type == REQ_TYPE_DRV_PRIV) {
 		phase = pd_special;
 		return pd_special();
 	}
@@ -725,7 +725,7 @@ static int pd_special_command(struct pd_unit *disk,
 	if (IS_ERR(rq))
 		return PTR_ERR(rq);
 
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	rq->special = func;
 
 	err = blk_execute_rq(disk->gd->queue, disk->gd, rq, 0);
drivers/block/sx8.c +2 -2
index 5d55285..59c91d4 100644
@@ -620,7 +620,7 @@ static int carm_array_info (struct carm_host *host, unsigned int array_idx)
 	spin_unlock_irq(&host->lock);
 
 	DPRINTK("blk_execute_rq_nowait, tag == %u\n", idx);
-	crq->rq->cmd_type = REQ_TYPE_SPECIAL;
+	crq->rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	crq->rq->special = crq;
 	blk_execute_rq_nowait(host->oob_q, NULL, crq->rq, true, NULL);
 
@@ -661,7 +661,7 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func)
 	crq->msg_bucket = (u32) rc;
 
 	DPRINTK("blk_execute_rq_nowait, tag == %u\n", idx);
-	crq->rq->cmd_type = REQ_TYPE_SPECIAL;
+	crq->rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	crq->rq->special = crq;
 	blk_execute_rq_nowait(host->oob_q, NULL, crq->rq, true, NULL);
 
drivers/block/virtio_blk.c +3 -3
index 5ea2f0b..d4d05f0 100644
@@ -124,7 +124,7 @@ static inline void virtblk_request_done(struct request *req)
 		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->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
-	} else if (req->cmd_type == REQ_TYPE_SPECIAL) {
+	} else if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
 		req->errors = (error != 0);
 	}
 
@@ -188,7 +188,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
 			vbr->out_hdr.sector = 0;
 			vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
 			break;
-		case REQ_TYPE_SPECIAL:
+		case REQ_TYPE_DRV_PRIV:
 			vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_GET_ID);
 			vbr->out_hdr.sector = 0;
 			vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
@@ -251,7 +251,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str)
 		return PTR_ERR(req);
 	}
 
-	req->cmd_type = REQ_TYPE_SPECIAL;
+	req->cmd_type = REQ_TYPE_DRV_PRIV;
 	err = blk_execute_rq(vblk->disk->queue, vblk->disk, req, false);
 	blk_put_request(req);
 
drivers/ide/ide-atapi.c +2 -2
index fac3d9d..b367300 100644
@@ -93,7 +93,7 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
 	int error;
 
 	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	rq->special = (char *)pc;
 
 	if (buf && bufflen) {
@@ -477,7 +477,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
 		if (uptodate == 0)
 			drive->failed_pc = NULL;
 
-		if (rq->cmd_type == REQ_TYPE_SPECIAL) {
+		if (rq->cmd_type == REQ_TYPE_DRV_PRIV) {
 			rq->errors = 0;
 			error = 0;
 		} else {
drivers/ide/ide-cd.c +1 -1
index 0b510ba..9a32603 100644
@@ -799,7 +799,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
 
 		cdrom_do_block_pc(drive, rq);
 		break;
-	case REQ_TYPE_SPECIAL:
+	case REQ_TYPE_DRV_PRIV:
 		/* right now this can only be a reset... */
 		uptodate = 1;
 		goto out_end;
drivers/ide/ide-cd_ioctl.c +1 -1
index 02caa7d..066e390 100644
@@ -304,7 +304,7 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi)
 	int ret;
 
 	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	rq->cmd_flags = REQ_QUIET;
 	ret = blk_execute_rq(drive->queue, cd->disk, rq, 0);
 	blk_put_request(rq);
drivers/ide/ide-devsets.c +1 -1
index 9e98122..b05a74d 100644
@@ -166,7 +166,7 @@ int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
 		return setting->set(drive, arg);
 
 	rq = blk_get_request(q, READ, __GFP_WAIT);
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	rq->cmd_len = 5;
 	rq->cmd[0] = REQ_DEVSET_EXEC;
 	*(int *)&rq->cmd[1] = arg;
drivers/ide/ide-eh.c +1 -1
index 3297066..19d809c 100644
@@ -147,7 +147,7 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
 {
 	struct request *rq = drive->hwif->rq;
 
-	if (rq && rq->cmd_type == REQ_TYPE_SPECIAL &&
+	if (rq && rq->cmd_type == REQ_TYPE_DRV_PRIV &&
 	    rq->cmd[0] == REQ_DRIVE_RESET) {
 		if (err <= 0 && rq->errors == 0)
 			rq->errors = -EIO;
drivers/ide/ide-floppy.c +3 -3
index 8c6363c..3dbfa5b 100644
@@ -97,7 +97,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
 			       "Aborting request!\n");
 	}
 
-	if (rq->cmd_type == REQ_TYPE_SPECIAL)
+	if (rq->cmd_type == REQ_TYPE_DRV_PRIV)
 		rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
 
 	return uptodate;
@@ -246,7 +246,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
 		} else
 			printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
 
-		if (rq->cmd_type == REQ_TYPE_SPECIAL) {
+		if (rq->cmd_type == REQ_TYPE_DRV_PRIV) {
 			rq->errors = 0;
 			ide_complete_rq(drive, 0, blk_rq_bytes(rq));
 			return ide_stopped;
@@ -265,7 +265,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
 		pc = &floppy->queued_pc;
 		idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
 		break;
-	case REQ_TYPE_SPECIAL:
+	case REQ_TYPE_DRV_PRIV:
 	case REQ_TYPE_SENSE:
 		pc = (struct ide_atapi_pc *)rq->special;
 		break;
drivers/ide/ide-io.c +2 -2
index 177db6d..8e55abd 100644
@@ -135,7 +135,7 @@ EXPORT_SYMBOL(ide_complete_rq);
 
 void ide_kill_rq(ide_drive_t *drive, struct request *rq)
 {
-	u8 drv_req = (rq->cmd_type == REQ_TYPE_SPECIAL) && rq->rq_disk;
+	u8 drv_req = (rq->cmd_type == REQ_TYPE_DRV_PRIV) && rq->rq_disk;
 	u8 media = drive->media;
 
 	drive->failed_pc = NULL;
@@ -353,7 +353,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
 			    pm->pm_step == IDE_PM_COMPLETED)
 				ide_complete_pm_rq(drive, rq);
 			return startstop;
-		} else if (!rq->rq_disk && rq->cmd_type == REQ_TYPE_SPECIAL)
+		} else if (!rq->rq_disk && rq->cmd_type == REQ_TYPE_DRV_PRIV)
 			/*
 			 * TODO: Once all ULDs have been modified to
 			 * check for specific op codes rather than
drivers/ide/ide-ioctls.c +1 -1
index 6233fa2c..aa2e9b7 100644
@@ -222,7 +222,7 @@ static int generic_drive_reset(ide_drive_t *drive)
 	int ret = 0;
 
 	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	rq->cmd_len = 1;
 	rq->cmd[0] = REQ_DRIVE_RESET;
 	if (blk_execute_rq(drive->queue, NULL, rq, 1))
drivers/ide/ide-park.c +2 -2
index ca95860..c808685 100644
@@ -34,7 +34,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
 	rq = blk_get_request(q, READ, __GFP_WAIT);
 	rq->cmd[0] = REQ_PARK_HEADS;
 	rq->cmd_len = 1;
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	rq->special = &timeout;
 	rc = blk_execute_rq(q, NULL, rq, 1);
 	blk_put_request(rq);
@@ -51,7 +51,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
 
 	rq->cmd[0] = REQ_UNPARK_HEADS;
 	rq->cmd_len = 1;
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	elv_add_request(q, rq, ELEVATOR_INSERT_FRONT);
 
 out:
drivers/ide/ide-tape.c +2 -2
index 6eb738c..2a5d543 100644
@@ -576,7 +576,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
 		      rq->cmd[0], (unsigned long long)blk_rq_pos(rq),
 		      blk_rq_sectors(rq));
 
-	BUG_ON(!(rq->cmd_type == REQ_TYPE_SPECIAL ||
+	BUG_ON(!(rq->cmd_type == REQ_TYPE_DRV_PRIV ||
 		 rq->cmd_type == REQ_TYPE_SENSE));
 
 	/* Retry a failed packet command */
@@ -853,7 +853,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
 	BUG_ON(size < 0 || size % tape->blk_size);
 
 	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_type = REQ_TYPE_DRV_PRIV;
 	rq->cmd[13] = cmd;
 	rq->rq_disk = tape->disk;
 	rq->__sector = tape->first_frame;
include/linux/blkdev.h +2 -2
index 7f9a516..98c9027 100644
@@ -79,10 +79,10 @@ enum rq_cmd_type_bits {
 	REQ_TYPE_PM_SUSPEND,		/* suspend request */
 	REQ_TYPE_PM_RESUME,		/* resume request */
 	REQ_TYPE_PM_SHUTDOWN,		/* shutdown request */
-	REQ_TYPE_SPECIAL,		/* driver defined type */
+	REQ_TYPE_DRV_PRIV,		/* driver defined type */
 	/*
 	 * for ATA/ATAPI devices. this really doesn't belong here, ide should
-	 * use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver
+	 * use REQ_TYPE_DRV_PRIV and use rq->cmd[0] with the range of driver
 	 * private REQ_LB opcodes to differentiate what type of request this is
 	 */
 	REQ_TYPE_ATA_TASKFILE,
Signature · 1 line
1.9.1
author maintainer
#2 lore raw

PATCH 2/7 block: move REQ_TYPE_ATA_TASKFILE and REQ_TYPE_ATA_PC to ide.h

In reply to Christoph Hellwig

These values are only used by the IDE driver, so move them into it by allowing drivers to take cmd_type values after the first private one. Note that we have to turn cmd_type into a plain unsigned integer so that gcc doesn't complain about mismatching enum types.

Signed-off-by Christoph Hellwig <hch at lst.de>
---
 include/linux/blkdev.h | 11 ++---------
 include/linux/ide.h    |  7 +++++++
 2 files changed, 9 insertions(+), 9 deletions(-)
include/linux/blkdev.h +2 -9
index 98c9027..9cb4d80 100644
@@ -79,14 +79,7 @@ enum rq_cmd_type_bits {
 	REQ_TYPE_PM_SUSPEND,		/* suspend request */
 	REQ_TYPE_PM_RESUME,		/* resume request */
 	REQ_TYPE_PM_SHUTDOWN,		/* shutdown request */
-	REQ_TYPE_DRV_PRIV,		/* driver defined type */
-	/*
-	 * for ATA/ATAPI devices. this really doesn't belong here, ide should
-	 * use REQ_TYPE_DRV_PRIV and use rq->cmd[0] with the range of driver
-	 * private REQ_LB opcodes to differentiate what type of request this is
-	 */
-	REQ_TYPE_ATA_TASKFILE,
-	REQ_TYPE_ATA_PC,
+	REQ_TYPE_DRV_PRIV,		/* driver defined types from here */
 };
 
 #define BLK_MAX_CDB	16
@@ -108,7 +101,7 @@ struct request {
 	struct blk_mq_ctx *mq_ctx;
 
 	u64 cmd_flags;
-	enum rq_cmd_type_bits cmd_type;
+	unsigned cmd_type;
 	unsigned long atomic_flags;
 
 	int cpu;
include/linux/ide.h +7 -0
index 93b5ca7..62ac399 100644
@@ -39,6 +39,12 @@
 
 struct device;
 
+/* IDE-specific values for req->cmd_type */
+enum ata_cmd_type_bits {
+	REQ_TYPE_ATA_TASKFILE = REQ_TYPE_DRV_PRIV + 1,
+	REQ_TYPE_ATA_PC,
+};
+
 /* Error codes returned in rq->errors to the higher part of the driver. */
 enum {
 	IDE_DRV_ERROR_GENERAL	= 101,
@@ -1551,4 +1557,5 @@ static inline void ide_set_drivedata(ide_drive_t *drive, void *data)
 #define ide_host_for_each_port(i, port, host) \
 	for ((i) = 0; ((port) = (host)->ports[i]) || (i) < MAX_HOST_PORTS; (i)++)
 
+
 #endif /* _IDE_H */
Signature · 1 line
1.9.1
author maintainer
#3 lore raw

PATCH 3/7 block: move REQ_TYPE_SENSE to the ide driver

In reply to Christoph Hellwig
Signed-off-by Christoph Hellwig <hch at lst.de>
---
 drivers/ide/ide-atapi.c  | 6 +++---
 drivers/ide/ide-cd.c     | 8 ++++----
 drivers/ide/ide-floppy.c | 2 +-
 drivers/ide/ide-tape.c   | 2 +-
 include/linux/blkdev.h   | 1 -
 include/linux/ide.h      | 1 +
 6 files changed, 10 insertions(+), 10 deletions(-)
drivers/ide/ide-atapi.c +3 -3
index b367300..1362ad8 100644
@@ -191,7 +191,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
 
 	BUG_ON(sense_len > sizeof(*sense));
 
-	if (rq->cmd_type == REQ_TYPE_SENSE || drive->sense_rq_armed)
+	if (rq->cmd_type == REQ_TYPE_ATA_SENSE || drive->sense_rq_armed)
 		return;
 
 	memset(sense, 0, sizeof(*sense));
@@ -210,7 +210,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
 	sense_rq->rq_disk = rq->rq_disk;
 	sense_rq->cmd[0] = GPCMD_REQUEST_SENSE;
 	sense_rq->cmd[4] = cmd_len;
-	sense_rq->cmd_type = REQ_TYPE_SENSE;
+	sense_rq->cmd_type = REQ_TYPE_ATA_SENSE;
 	sense_rq->cmd_flags |= REQ_PREEMPT;
 
 	if (drive->media == ide_tape)
@@ -310,7 +310,7 @@ int ide_cd_get_xferlen(struct request *rq)
 	switch (rq->cmd_type) {
 	case REQ_TYPE_FS:
 		return 32768;
-	case REQ_TYPE_SENSE:
+	case REQ_TYPE_ATA_SENSE:
 	case REQ_TYPE_BLOCK_PC:
 	case REQ_TYPE_ATA_PC:
 		return blk_rq_bytes(rq);
drivers/ide/ide-cd.c +4 -4
index 9a32603..64a6b82 100644
@@ -210,7 +210,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
 static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
 {
 	/*
-	 * For REQ_TYPE_SENSE, "rq->special" points to the original
+	 * For REQ_TYPE_ATA_SENSE, "rq->special" points to the original
 	 * failed request.  Also, the sense data should be read
 	 * directly from rq which might be different from the original
 	 * sense buffer if it got copied during mapping.
@@ -285,7 +285,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
 				  "stat 0x%x",
 				  rq->cmd[0], rq->cmd_type, err, stat);
 
-	if (rq->cmd_type == REQ_TYPE_SENSE) {
+	if (rq->cmd_type == REQ_TYPE_ATA_SENSE) {
 		/*
 		 * We got an error trying to get sense info from the drive
 		 * (probably while trying to recover from a former error).
@@ -526,7 +526,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 	ide_expiry_t *expiry = NULL;
 	int dma_error = 0, dma, thislen, uptodate = 0;
 	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0;
-	int sense = (rq->cmd_type == REQ_TYPE_SENSE);
+	int sense = (rq->cmd_type == REQ_TYPE_ATA_SENSE);
 	unsigned int timeout;
 	u16 len;
 	u8 ireason, stat;
@@ -791,7 +791,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
 		if (cdrom_start_rw(drive, rq) == ide_stopped)
 			goto out_end;
 		break;
-	case REQ_TYPE_SENSE:
+	case REQ_TYPE_ATA_SENSE:
 	case REQ_TYPE_BLOCK_PC:
 	case REQ_TYPE_ATA_PC:
 		if (!rq->timeout)
drivers/ide/ide-floppy.c +1 -1
index 3dbfa5b..2fb5350 100644
@@ -266,7 +266,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
 		idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
 		break;
 	case REQ_TYPE_DRV_PRIV:
-	case REQ_TYPE_SENSE:
+	case REQ_TYPE_ATA_SENSE:
 		pc = (struct ide_atapi_pc *)rq->special;
 		break;
 	case REQ_TYPE_BLOCK_PC:
drivers/ide/ide-tape.c +1 -1
index 2a5d543..f5d51d1 100644
@@ -577,7 +577,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
 		      blk_rq_sectors(rq));
 
 	BUG_ON(!(rq->cmd_type == REQ_TYPE_DRV_PRIV ||
-		 rq->cmd_type == REQ_TYPE_SENSE));
+		 rq->cmd_type == REQ_TYPE_ATA_SENSE));
 
 	/* Retry a failed packet command */
 	if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
include/linux/blkdev.h +0 -1
index 9cb4d80..6076b9e 100644
@@ -75,7 +75,6 @@ struct request_list {
 enum rq_cmd_type_bits {
 	REQ_TYPE_FS		= 1,	/* fs request */
 	REQ_TYPE_BLOCK_PC,		/* scsi command */
-	REQ_TYPE_SENSE,			/* sense request */
 	REQ_TYPE_PM_SUSPEND,		/* suspend request */
 	REQ_TYPE_PM_RESUME,		/* resume request */
 	REQ_TYPE_PM_SHUTDOWN,		/* shutdown request */
include/linux/ide.h +1 -0
index 62ac399..9856b7d 100644
@@ -43,6 +43,7 @@ struct device;
 enum ata_cmd_type_bits {
 	REQ_TYPE_ATA_TASKFILE = REQ_TYPE_DRV_PRIV + 1,
 	REQ_TYPE_ATA_PC,
+	REQ_TYPE_ATA_SENSE,	/* sense request */
 };
 
 /* Error codes returned in rq->errors to the higher part of the driver. */
Signature · 1 line
1.9.1
author maintainer
#4 lore raw

PATCH 4/7 block: remove REQ_TYPE_PM_SHUTDOWN

In reply to Christoph Hellwig
Signed-off-by Christoph Hellwig <hch at lst.de>
---
 include/linux/blkdev.h | 1 -
 1 file changed, 1 deletion(-)
include/linux/blkdev.h +0 -1
index 6076b9e..c2829ba 100644
@@ -77,7 +77,6 @@ enum rq_cmd_type_bits {
 	REQ_TYPE_BLOCK_PC,		/* scsi command */
 	REQ_TYPE_PM_SUSPEND,		/* suspend request */
 	REQ_TYPE_PM_RESUME,		/* resume request */
-	REQ_TYPE_PM_SHUTDOWN,		/* shutdown request */
 	REQ_TYPE_DRV_PRIV,		/* driver defined types from here */
 };
 
Signature · 1 line
1.9.1
author maintainer
#5 lore raw

PATCH 5/7 block: move PM request support to IDE

In reply to Christoph Hellwig

This removes the request types and hacks from the block code and into the old IDE driver. There is a small amunt of code duplication due to this, but it's not too bad.

Signed-off-by Christoph Hellwig <hch at lst.de>
---
 block/blk-core.c           |  1 +
 block/blk-exec.c           | 10 ---------
 block/blk.h                |  2 --
 drivers/ide/ide-eh.c       |  2 +-
 drivers/ide/ide-io.c       |  8 +++----
 drivers/ide/ide-pm.c       | 56 +++++++++++++++++++++++++++++++++++-----------
 drivers/ide/ide-taskfile.c |  2 +-
 include/linux/blkdev.h     | 21 +----------------
 include/linux/ide.h        | 19 ++++++++++++++++
 9 files changed, 70 insertions(+), 51 deletions(-)
block/blk-core.c +1 -0
index fd154b9..2e5020f 100644
@@ -285,6 +285,7 @@ inline void __blk_run_queue_uncond(struct request_queue *q)
 	q->request_fn(q);
 	q->request_fn_active--;
 }
+EXPORT_SYMBOL_GPL(__blk_run_queue_uncond);
 
 /**
  * __blk_run_queue - run a single device queue
block/blk-exec.c +0 -10
index 9924725..3fec8a2 100644
@@ -53,7 +53,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 			   rq_end_io_fn *done)
 {
 	int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
-	bool is_pm_resume;
 
 	WARN_ON(irqs_disabled());
 	WARN_ON(rq->cmd_type == REQ_TYPE_FS);
@@ -70,12 +69,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 		return;
 	}
 
-	/*
-	 * need to check this before __blk_run_queue(), because rq can
-	 * be freed before that returns.
-	 */
-	is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
-
 	spin_lock_irq(q->queue_lock);
 
 	if (unlikely(blk_queue_dying(q))) {
@@ -88,9 +81,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 
 	__elv_add_request(q, rq, where);
 	__blk_run_queue(q);
-	/* the queue is stopped so it won't be run */
-	if (is_pm_resume)
-		__blk_run_queue_uncond(q);
 	spin_unlock_irq(q->queue_lock);
 }
 EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
block/blk.h +0 -2
index 43b0361..4b48d55 100644
@@ -193,8 +193,6 @@ int blk_try_merge(struct request *rq, struct bio *bio);
 
 void blk_queue_congestion_threshold(struct request_queue *q);
 
-void __blk_run_queue_uncond(struct request_queue *q);
-
 int blk_dev_init(void);
 
 
drivers/ide/ide-eh.c +1 -1
index 19d809c..d6da011 100644
@@ -129,7 +129,7 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
 
 			if (cmd)
 				ide_complete_cmd(drive, cmd, stat, err);
-		} else if (blk_pm_request(rq)) {
+		} else if (ata_pm_request(rq)) {
 			rq->errors = 1;
 			ide_complete_pm_rq(drive, rq);
 			return ide_stopped;
drivers/ide/ide-io.c +4 -4
index 8e55abd..669ea1e 100644
@@ -320,7 +320,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
 		goto kill_rq;
 	}
 
-	if (blk_pm_request(rq))
+	if (ata_pm_request(rq))
 		ide_check_pm_state(drive, rq);
 
 	drive->hwif->tp_ops->dev_select(drive);
@@ -342,8 +342,8 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
 
 		if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
 			return execute_drive_cmd(drive, rq);
-		else if (blk_pm_request(rq)) {
-			struct request_pm_state *pm = rq->special;
+		else if (ata_pm_request(rq)) {
+			struct ide_pm_state *pm = rq->special;
 #ifdef DEBUG_PM
 			printk("%s: start_power_step(step: %d)\n",
 				drive->name, pm->pm_step);
@@ -538,7 +538,7 @@ repeat:
 		 * state machine.
 		 */
 		if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
-		    blk_pm_request(rq) == 0 &&
+		    ata_pm_request(rq) == 0 &&
 		    (rq->cmd_flags & REQ_PREEMPT) == 0) {
 			/* there should be no pending command at this point */
 			ide_unlock_port(hwif);
drivers/ide/ide-pm.c +43 -13

127 lines not on this page · raw message

drivers/ide/ide-taskfile.c +1 -1
index dabb88b..0979e12 100644
@@ -186,7 +186,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 	    tf->command == ATA_CMD_CHK_POWER) {
 		struct request *rq = hwif->rq;
 
-		if (blk_pm_request(rq))
+		if (ata_pm_request(rq))
 			ide_complete_pm_rq(drive, rq);
 		else
 			ide_finish_cmd(drive, cmd, stat);
include/linux/blkdev.h +1 -20
index c2829ba..2da818a 100644
@@ -30,7 +30,6 @@ struct scsi_ioctl_command;
 
 struct request_queue;
 struct elevator_queue;
-struct request_pm_state;
 struct blk_trace;
 struct request;
 struct sg_io_hdr;
@@ -75,8 +74,6 @@ struct request_list {
 enum rq_cmd_type_bits {
 	REQ_TYPE_FS		= 1,	/* fs request */
 	REQ_TYPE_BLOCK_PC,		/* scsi command */
-	REQ_TYPE_PM_SUSPEND,		/* suspend request */
-	REQ_TYPE_PM_RESUME,		/* resume request */
 	REQ_TYPE_DRV_PRIV,		/* driver defined types from here */
 };
 
@@ -207,19 +204,6 @@ static inline unsigned short req_get_ioprio(struct request *req)
 	return req->ioprio;
 }
 
-/*
- * State information carried for REQ_TYPE_PM_SUSPEND and REQ_TYPE_PM_RESUME
- * requests. Some step values could eventually be made generic.
- */
-struct request_pm_state
-{
-	/* PM state machine step value, currently driver specific */
-	int	pm_step;
-	/* requested PM state value (S1, S2, S3, S4, ...) */
-	u32	pm_state;
-	void*	data;		/* for driver use */
-};
-
 #include <linux/elevator.h>
 
 struct blk_queue_ctx;
@@ -601,10 +585,6 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 	(((rq)->cmd_flags & REQ_STARTED) && \
 	 ((rq)->cmd_type == REQ_TYPE_FS))
 
-#define blk_pm_request(rq)	\
-	((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \
-	 (rq)->cmd_type == REQ_TYPE_PM_RESUME)
-
 #define blk_rq_cpu_valid(rq)	((rq)->cpu != -1)
 #define blk_bidi_rq(rq)		((rq)->next_rq != NULL)
 /* rq->queuelist of dequeued request must be list_empty() */
@@ -838,6 +818,7 @@ extern void blk_stop_queue(struct request_queue *q);
 extern void blk_sync_queue(struct request_queue *q);
 extern void __blk_stop_queue(struct request_queue *q);
 extern void __blk_run_queue(struct request_queue *q);
+extern void __blk_run_queue_uncond(struct request_queue *q);
 extern void blk_run_queue(struct request_queue *);
 extern void blk_run_queue_async(struct request_queue *q);
 extern int blk_rq_map_user(struct request_queue *, struct request *,
include/linux/ide.h +19 -0
index 9856b7d..a633898 100644
@@ -44,8 +44,14 @@ enum ata_cmd_type_bits {
 	REQ_TYPE_ATA_TASKFILE = REQ_TYPE_DRV_PRIV + 1,
 	REQ_TYPE_ATA_PC,
 	REQ_TYPE_ATA_SENSE,	/* sense request */
+	REQ_TYPE_ATA_PM_SUSPEND,/* suspend request */
+	REQ_TYPE_ATA_PM_RESUME,	/* resume request */
 };
 
+#define ata_pm_request(rq)	\
+	((rq)->cmd_type == REQ_TYPE_ATA_PM_SUSPEND || \
+	 (rq)->cmd_type == REQ_TYPE_ATA_PM_RESUME)
+
 /* Error codes returned in rq->errors to the higher part of the driver. */
 enum {
 	IDE_DRV_ERROR_GENERAL	= 101,
@@ -1321,6 +1327,19 @@ struct ide_port_info {
 	u8			udma_mask;
 };
 
+/*
+ * State information carried for REQ_TYPE_ATA_PM_SUSPEND and REQ_TYPE_ATA_PM_RESUME
+ * requests.
+ */
+struct ide_pm_state {
+	/* PM state machine step value, currently driver specific */
+	int	pm_step;
+	/* requested PM state value (S1, S2, S3, S4, ...) */
+	u32	pm_state;
+	void*	data;		/* for driver use */
+};
+
+
 int ide_pci_init_one(struct pci_dev *, const struct ide_port_info *, void *);
 int ide_pci_init_two(struct pci_dev *, struct pci_dev *,
 		     const struct ide_port_info *, void *);
Signature · 1 line
1.9.1
author maintainer
#6 lore raw

PATCH 6/7 nbd: stop using req->cmd

In reply to Christoph Hellwig
Signed-off-by Christoph Hellwig <hch at lst.de>
---
 drivers/block/nbd.c      | 48 +++++++++++++++++++++++-------------------------
 include/uapi/linux/nbd.h |  2 --
 2 files changed, 23 insertions(+), 27 deletions(-)
drivers/block/nbd.c +23 -25
index 9cf52ac..83a7ba4 100644
@@ -230,29 +230,40 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
 	int result, flags;
 	struct nbd_request request;
 	unsigned long size = blk_rq_bytes(req);
+	u32 type;
+
+	if (req->cmd_type == REQ_TYPE_DRV_PRIV)
+		type = NBD_CMD_DISC;
+	else if (req->cmd_flags & REQ_DISCARD)
+		type = NBD_CMD_TRIM;
+	else if (req->cmd_flags & REQ_FLUSH)
+		type = NBD_CMD_FLUSH;
+	else if (rq_data_dir(req) == WRITE)
+		type = NBD_CMD_WRITE;
+	else
+		type = NBD_CMD_READ;
 
 	memset(&request, 0, sizeof(request));
 	request.magic = htonl(NBD_REQUEST_MAGIC);
-	request.type = htonl(nbd_cmd(req));
-
-	if (nbd_cmd(req) != NBD_CMD_FLUSH && nbd_cmd(req) != NBD_CMD_DISC) {
+	request.type = htonl(type);
+	if (type != NBD_CMD_FLUSH && type != NBD_CMD_DISC) {
 		request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
 		request.len = htonl(size);
 	}
 	memcpy(request.handle, &req, sizeof(req));
 
 	dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
-		req, nbdcmd_to_ascii(nbd_cmd(req)),
+		req, nbdcmd_to_ascii(type),
 		(unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
 	result = sock_xmit(nbd, 1, &request, sizeof(request),
-			(nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0);
+			(type == NBD_CMD_WRITE) ? MSG_MORE : 0);
 	if (result <= 0) {
 		dev_err(disk_to_dev(nbd->disk),
 			"Send control failed (result %d)\n", result);
 		return -EIO;
 	}
 
-	if (nbd_cmd(req) == NBD_CMD_WRITE) {
+	if (type == NBD_CMD_WRITE) {
 		struct req_iterator iter;
 		struct bio_vec bvec;
 		/*
@@ -352,7 +363,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
 	}
 
 	dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", req);
-	if (nbd_cmd(req) == NBD_CMD_READ) {
+	if (rq_data_dir(req) != WRITE) {
 		struct req_iterator iter;
 		struct bio_vec bvec;
 
@@ -452,23 +463,11 @@ static void nbd_handle_req(struct nbd_device *nbd, struct request *req)
 	if (req->cmd_type != REQ_TYPE_FS)
 		goto error_out;
 
-	nbd_cmd(req) = NBD_CMD_READ;
-	if (rq_data_dir(req) == WRITE) {
-		if ((req->cmd_flags & REQ_DISCARD)) {
-			WARN_ON(!(nbd->flags & NBD_FLAG_SEND_TRIM));
-			nbd_cmd(req) = NBD_CMD_TRIM;
-		} else
-			nbd_cmd(req) = NBD_CMD_WRITE;
-		if (nbd->flags & NBD_FLAG_READ_ONLY) {
-			dev_err(disk_to_dev(nbd->disk),
-				"Write on read-only\n");
-			goto error_out;
-		}
-	}
-
-	if (req->cmd_flags & REQ_FLUSH) {
-		BUG_ON(unlikely(blk_rq_sectors(req)));
-		nbd_cmd(req) = NBD_CMD_FLUSH;
+	if (rq_data_dir(req) == WRITE &&
+	    (nbd->flags & NBD_FLAG_READ_ONLY)) {
+		dev_err(disk_to_dev(nbd->disk),
+			"Write on read-only\n");
+		goto error_out;
 	}
 
 	req->errors = 0;
@@ -593,7 +592,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
 		mutex_lock(&nbd->tx_lock);
 		blk_rq_init(NULL, &sreq);
 		sreq.cmd_type = REQ_TYPE_DRV_PRIV;
-		nbd_cmd(&sreq) = NBD_CMD_DISC;
 
 		/* Check again after getting mutex back.  */
 		if (!nbd->sock)
include/uapi/linux/nbd.h +0 -2
index 4f52549..e08e413 100644
@@ -44,8 +44,6 @@ enum {
 /* there is a gap here to match userspace */
 #define NBD_FLAG_SEND_TRIM    (1 << 5) /* send trim/discard */
 
-#define nbd_cmd(req) ((req)->cmd[0])
-
 /* userspace doesn't need the nbd_device structure */
 
 /* These are sent over the network in the request/reply magic fields */
Signature · 1 line
1.9.1
author maintainer
#7 lore raw

PATCH 7/7 block: allocate block_pc data separate from struct request

In reply to Christoph Hellwig

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(-)
block/blk-core.c +16 -7
index 2e5020f..5d78a85 100644
@@ -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;
block/blk-exec.c +0 -17
index 3fec8a2..94e909e 100644
@@ -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);
block/blk-mq.c +0 -4
index ade8a2d..715e3c0 100644
@@ -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;
block/bsg-lib.c +5 -5
index 650f427..6b73dca 100644
@@ -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) {
block/bsg.c +10 -21
index d214e92..ebf0dc1 100644
@@ -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;
block/scsi_ioctl.c +28 -40

160 lines not on this page · raw message

drivers/ata/libata-scsi.c +1 -1
index 3131adc..d8cb4ec 100644
@@ -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,
drivers/block/pktcdvd.c +6 -3
index 09e628da..51f919d 100644
@@ -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)
drivers/block/virtio_blk.c +6 -3
index d4d05f0..cd3bcc0 100644
@@ -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);
drivers/cdrom/cdrom.c +21 -15
index 5d28a45..7a5672a 100644
@@ -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))
drivers/md/dm.c +4 -0
index 8001fe9..17df896 100644
@@ -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;
 
drivers/message/fusion/mptsas.c +2 -2
index 5bdaae1..34127ac 100644
@@ -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 {
drivers/scsi/device_handler/scsi_dh_alua.c +37 -41

141 lines not on this page · raw message

drivers/scsi/device_handler/scsi_dh_emc.c +25 -27

109 lines not on this page · raw message

drivers/scsi/device_handler/scsi_dh_hp_sw.c +22 -16
index 485d995..06f2c36 100644
@@ -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);
drivers/scsi/device_handler/scsi_dh_rdac.c +20 -23

78 lines not on this page · raw message

drivers/scsi/mpt2sas/mpt2sas_transport.c +2 -2
index ff2500a..672597c 100644
@@ -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);
drivers/scsi/mpt3sas/mpt3sas_transport.c +2 -2
index efb98af..b558442 100644
@@ -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);
drivers/scsi/osd/osd_initiator.c +16 -16
index 0cccd60..055714d 100644
@@ -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;
 }
drivers/scsi/osst.c +4 -6
index 5033223..79b57fe 100644
@@ -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;
drivers/scsi/qla2xxx/qla_bsg.c +1 -1
index 2e2bb6f..f6bf256 100644
@@ -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);
drivers/scsi/qla2xxx/qla_isr.c +4 -2
index 6dc14cd..724eaa4 100644
@@ -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,
drivers/scsi/qla2xxx/qla_mr.c +1 -1
index 6d190b4..2ac1886 100644
@@ -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,
drivers/scsi/scsi_error.c +11 -11
index c95a4e9..85d659e 100644
@@ -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));
 
drivers/scsi/scsi_lib.c +10 -12
index b1a2631..29e0cd6 100644
@@ -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);
drivers/scsi/scsi_transport_fc.c +5 -5
index 24eaaf6..6024e6c 100644
@@ -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) {
drivers/scsi/sd.c +4 -43

84 lines not on this page · raw message

drivers/scsi/sg.c +8 -13
index 9d7b7db..a266319 100644
@@ -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);
drivers/scsi/st.c +11 -10
index 9a1c342..7b4445f 100644
@@ -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.
drivers/target/target_core_pscsi.c +8 -6
index f6c954c..023accd 100644
@@ -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
include/linux/blkdev.h +17 -10
index 2da818a..e64a01b 100644
@@ -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);
include/linux/blktrace_api.h +3 -1
index afc1343..8c63eca 100644
@@ -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);
include/scsi/scsi_cmnd.h +1 -1
index 9fc1aec..de6d7d0 100644
@@ -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;
kernel/trace/blktrace.c +8 -3
index 483cecf..e87c0ac 100644
@@ -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;
Signature · 1 line
1.9.1
#8 lore raw

PATCH 7/7 block: allocate block_pc data separate from struct request

Quoted 3 lines · Christoph Hellwig

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

Quoted 4 lines
block/blk-core.c +0 -0
index 2e5020f..5d78a85 100644

<>

Quoted 9 lines
block/blk-core.c +2 -1
@@ -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)

block/blk-core.c EXPORT_SYMBOL(blk_make_request); · line 1285

Quoted 10 lines
block/blk-core.c +4 -1
+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);

I wish you would not embed a dynamic allocation here for any driver regardless. This extra allocation does hurt a lot. See how in SCSI fs commands you embedded it in scsi_cmnd so it catches as well for multi-Q pre-allocation.

I think you need to just make it the same as *sense pass it from outside and the allocation is the caller responsibility. The caller must have an end-request call back set. (Or is a sync call)

Usually all users already have a structure to put this in. The only bit more work is to take care of the free. If they are already passing sense then they already need to free at end of request. Those that are synchronous can have it on the stack. Only very few places need a bit of extra work.

Quoted 54 lines
block/blk-core.c +9 -0
+	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;
block/blk-exec.c +0 -12
index 3fec8a2..94e909e 100644
@@ -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)

block/blk-exec.c int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk, · line 116

Quoted 10 lines
block/blk-exec.c +0 -5
 		err = -EIO;
 
-	if (rq->sense == sense)	{
-		rq->sense = NULL;
-		rq->sense_len = 0;
-	}
-
 	return err;
 }
 EXPORT_SYMBOL(blk_execute_rq);

<>

Quoted 5 lines
include/linux/blkdev.h +0 -0
index 2da818a..e64a01b 100644

include/linux/blkdev.h enum rq_cmd_type_bits { · line 88

Quoted 9 lines
include/linux/blkdev.h +6 -0
@@ -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;

Better move cmd_len here the short will combine well with the char array.

Quoted 23 lines
include/linux/blkdev.h +4 -9
+	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;
 

include/linux/blkdev.h struct request { · line 197

Quoted 10 lines
include/linux/blkdev.h +5 -0
 	unsigned long deadline;
 	struct list_head timeout_list;
 	unsigned int timeout;
 	int retries;
 
+	union {
+		struct block_pc_request *block_pc;
+		void *drv_private;
+	};
+

Exactly. drv_private is allocated by caller we can do the same for block_pc. Also If (theoretically) a driver needs both it is just the same pointer right? (container_of)

include/linux/blkdev.h extern void __blk_put_request(struct request_queue *, struct request *); · line 782

Quoted 13 lines
include/linux/blkdev.h +2 -1
 	/*
 	 * 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);

<>

include/scsi/scsi_cmnd.h struct scsi_cmnd { · line 98

Quoted 13 lines
include/scsi/scsi_cmnd.h +1 -1
index 9fc1aec..de6d7d0 100644
@@ -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;

<>

Thanks
Boaz

author maintainer
#9 lore raw

PATCH 7/7 block: allocate block_pc data separate from struct request

Quoted 9 lines · Boaz Harrosh

block/blk-core.c EXPORT_SYMBOL(blk_make_request); · line 1285

Quoted 3 lines
block/blk-core.c +2 -1
-	memset(rq->__cmd, 0, sizeof(rq->__cmd));
+
+	rq->block_pc = kzalloc(sizeof(*rq->block_pc) + cmd_len, gfp);

I wish you would not embed a dynamic allocation here for any driver regardless. This extra allocation does hurt a lot. See how in SCSI fs commands you embedded it in scsi_cmnd so it catches as well for multi-Q pre-allocation.

Quoted 8 lines

I think you need to just make it the same as *sense pass it from outside and the allocation is the caller responsibility. The caller must have an end-request call back set. (Or is a sync call)

Usually all users already have a structure to put this in. The only bit more work is to take care of the free. If they are already passing sense then they already need to free at end of request. Those that are synchronous can have it on the stack. Only very few places need a bit of extra work.

Actually most don't have a structure ready, that's why I ressorted to this version. But once this is in you can easily add low-level version that allows passing a preallocate cdb buffer for the OSD case.

Quoted 7 lines

include/linux/blkdev.h enum rq_cmd_type_bits { · line 88

Quoted 4 lines
include/linux/blkdev.h +4 -0
+struct block_pc_request {
+	unsigned short cmd_len;
+	unsigned int sense_len;
+	void *sense;

Better move cmd_len here the short will combine well with the char array.

Thanks.

Quoted 9 lines

include/linux/blkdev.h struct request { · line 197

Quoted 5 lines
include/linux/blkdev.h +5 -0
+	union {
+		struct block_pc_request *block_pc;
+		void *drv_private;
+	};
+

Exactly. drv_private is allocated by caller we can do the same for block_pc. Also If (theoretically) a driver needs both it is just the same pointer right? (container_of)

I probably need to rename the field. It's only driver private when the low-level driver itself submits the request, e.g. internal commands in the LLDD. But in that particular case what you suggest is fine.

#10 lore raw
In reply to Christoph Hellwig
Quoted 7 lines · Christoph Hellwig

The real RFC is the last one which allocates the block_pc specific data separately in the callers instead of bloating every struct request with it. I always hated what we did, but with the upcoming split of nvme into transports and command sets we'll need a NVME equivalent of BLOCK_PC, and as NVMe was designed by crackmonkeys dreaming of an ATA controller the "command block" for NVME is even bigger than what we have to deal with in SCSI.

Umm, the NVMe command was never supposed to be "transported". The crackmonkeys are the ones who are trying to ship it across the network instead of designing a proper network protocol.

maintainer
#11 lore raw
In reply to Christoph Hellwig
Quoted 12 lines · Christoph Hellwig

The first 5 patches move the magic IDE request types into the old IDE driver to keep the core block code clean of them. Those are basically ready to merge, just like the 6th one which is a cleanup on it's own.

The real RFC is the last one which allocates the block_pc specific data separately in the callers instead of bloating every struct request with it. I always hated what we did, but with the upcoming split of nvme into transports and command sets we'll need a NVME equivalent of BLOCK_PC, and as NVMe was designed by crackmonkeys dreaming of an ATA controller the "command block" for NVME is even bigger than what we have to deal with in SCSI.

Quoted 4 lines

Note that the old IDE driver doesn't compile with the last patch yet as there are major nightmares to sort out, and BLOCK_PC passthrough with dm-multipath doesn't work yet either. If I get some general concensus on the approach I'll fix those of course.

These are nice improvements, it'd be great to get rid of embeeding the command block. I have applied 1-6 for 4.2.

Signature · 1 line
Jens Axboe