[PATCH] block: support larger block pc requests
This patch modifies blk_rq_map/unmap_user() and the cdrom and scsi_ioctl.c
users so that it supports requests larger than bio by chaining them together.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index e55a756..5493c2f 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -226,7 +226,6 @@
unsigned long start_time;
int writing = 0, ret = 0;
struct request *rq;
- struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char cmd[BLK_MAX_CDB];
@@ -258,6 +257,32 @@
if (!rq)
return -ENOMEM;
+ /*
+ * fill in request structure
+ */
+ rq->cmd_len = hdr->cmd_len;
+ memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
+ memcpy(rq->cmd, cmd, hdr->cmd_len);
+
+ memset(sense, 0, sizeof(sense));
+ rq->sense = sense;
+ rq->sense_len = 0;
+
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
+
+ /*
+ * bounce this after holding a reference to the original bio, it's
+ * needed for proper unmapping
+ */
+ if (rq->bio)
+ blk_queue_bounce(q, &rq->bio);
+
+ rq->timeout = (hdr->timeout * HZ) / 1000;
+ if (!rq->timeout)
+ rq->timeout = q->sg_timeout;
+ if (!rq->timeout)
+ rq->timeout = BLK_DEFAULT_TIMEOUT;
+
if (hdr->iovec_count) {
const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
struct sg_iovec *iov;
@@ -274,7 +299,8 @@
goto out;
}
- ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count);
+ ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
+ hdr->dxfer_len);
kfree(iov);
} else if (hdr->dxfer_len)
ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
@@ -282,33 +308,6 @@
if (ret)
goto out;
- /*
- * fill in request structure
- */
- rq->cmd_len = hdr->cmd_len;
- memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
- memcpy(rq->cmd, cmd, hdr->cmd_len);
-
- memset(sense, 0, sizeof(sense));
- rq->sense = sense;
- rq->sense_len = 0;
-
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
- bio = rq->bio;
-
- /*
- * bounce this after holding a reference to the original bio, it's
- * needed for proper unmapping
- */
- if (rq->bio)
- blk_queue_bounce(q, &rq->bio);
-
- rq->timeout = (hdr->timeout * HZ) / 1000;
- if (!rq->timeout)
- rq->timeout = q->sg_timeout;
- if (!rq->timeout)
- rq->timeout = BLK_DEFAULT_TIMEOUT;
-
rq->retries = 0;
start_time = jiffies;
@@ -339,7 +338,7 @@
hdr->sb_len_wr = len;
}
- if (blk_rq_unmap_user(bio, hdr->dxfer_len))
+ if (blk_rq_unmap_user(rq))
ret = -EFAULT;
/* may not have succeeded, but output values written to control