diff options
| author | Christoph Hellwig <hch@lst.de> | 2014-08-21 21:39:53 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@fb.com> | 2014-08-21 21:42:01 -0400 |
| commit | a57821cac6bb6e46abea118e34d0e86444ec1410 (patch) | |
| tree | 87bacd0df173a80439af323372035f69932cc8d8 | |
| parent | 2cada584b20007470931080c49310d85908449b0 (diff) | |
block: support > 16 byte CDBs for SG_IO
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Boaz Harrosh <boaz@plexistor.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
| -rw-r--r-- | block/scsi_ioctl.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index ba8706f6cded..1d78e6cf9d61 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
| @@ -296,8 +296,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
| 296 | 296 | ||
| 297 | if (hdr->interface_id != 'S') | 297 | if (hdr->interface_id != 'S') |
| 298 | return -EINVAL; | 298 | return -EINVAL; |
| 299 | if (hdr->cmd_len > BLK_MAX_CDB) | ||
| 300 | return -EINVAL; | ||
| 301 | 299 | ||
| 302 | if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9)) | 300 | if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9)) |
| 303 | return -EIO; | 301 | return -EIO; |
| @@ -316,14 +314,21 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
| 316 | if (hdr->flags & SG_FLAG_Q_AT_HEAD) | 314 | if (hdr->flags & SG_FLAG_Q_AT_HEAD) |
| 317 | at_head = 1; | 315 | at_head = 1; |
| 318 | 316 | ||
| 317 | ret = -ENOMEM; | ||
| 319 | rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); | 318 | rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); |
| 320 | if (!rq) | 319 | if (!rq) |
| 321 | return -ENOMEM; | 320 | goto out; |
| 322 | blk_rq_set_block_pc(rq); | 321 | blk_rq_set_block_pc(rq); |
| 323 | 322 | ||
| 323 | if (hdr->cmd_len > BLK_MAX_CDB) { | ||
| 324 | rq->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); | ||
| 325 | if (!rq->cmd) | ||
| 326 | goto out_put_request; | ||
| 327 | } | ||
| 328 | |||
| 324 | ret = -EFAULT; | 329 | ret = -EFAULT; |
| 325 | if (blk_fill_sghdr_rq(q, rq, hdr, mode)) | 330 | if (blk_fill_sghdr_rq(q, rq, hdr, mode)) |
| 326 | goto out; | 331 | goto out_free_cdb; |
| 327 | 332 | ||
| 328 | if (hdr->iovec_count) { | 333 | if (hdr->iovec_count) { |
| 329 | size_t iov_data_len; | 334 | size_t iov_data_len; |
| @@ -333,7 +338,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
| 333 | 0, NULL, &iov); | 338 | 0, NULL, &iov); |
| 334 | if (ret < 0) { | 339 | if (ret < 0) { |
| 335 | kfree(iov); | 340 | kfree(iov); |
| 336 | goto out; | 341 | goto out_free_cdb; |
| 337 | } | 342 | } |
| 338 | 343 | ||
| 339 | iov_data_len = ret; | 344 | iov_data_len = ret; |
| @@ -356,7 +361,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
| 356 | GFP_KERNEL); | 361 | GFP_KERNEL); |
| 357 | 362 | ||
| 358 | if (ret) | 363 | if (ret) |
| 359 | goto out; | 364 | goto out_free_cdb; |
| 360 | 365 | ||
| 361 | bio = rq->bio; | 366 | bio = rq->bio; |
| 362 | memset(sense, 0, sizeof(sense)); | 367 | memset(sense, 0, sizeof(sense)); |
| @@ -375,8 +380,13 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
| 375 | hdr->duration = jiffies_to_msecs(jiffies - start_time); | 380 | hdr->duration = jiffies_to_msecs(jiffies - start_time); |
| 376 | 381 | ||
| 377 | ret = blk_complete_sghdr_rq(rq, hdr, bio); | 382 | ret = blk_complete_sghdr_rq(rq, hdr, bio); |
| 378 | out: | 383 | |
| 384 | out_free_cdb: | ||
| 385 | if (rq->cmd != rq->__cmd) | ||
| 386 | kfree(rq->cmd); | ||
| 387 | out_put_request: | ||
| 379 | blk_put_request(rq); | 388 | blk_put_request(rq); |
| 389 | out: | ||
| 380 | return ret; | 390 | return ret; |
| 381 | } | 391 | } |
| 382 | 392 | ||
