diff options
author | Christoph Hellwig <hch@lst.de> | 2017-01-27 03:46:29 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-01-27 17:08:35 -0500 |
commit | 82ed4db499b8598f16f8871261bff088d6b0597f (patch) | |
tree | e1cc0a433bf5ae2b9723837291617bdfeeb61816 /block/scsi_ioctl.c | |
parent | 8ae94eb65be9425af4d57a4f4cfebfdf03081e93 (diff) |
block: split scsi_request out of struct request
And require all drivers that want to support BLOCK_PC to allocate it
as the first thing of their private data. To support this the legacy
IDE and BSG code is switched to set cmd_size on their queues to let
the block layer allocate the additional space.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/scsi_ioctl.c')
-rw-r--r-- | block/scsi_ioctl.c | 76 |
1 files changed, 43 insertions, 33 deletions
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index c2b64923ab66..7edf44f25e08 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -230,15 +230,17 @@ EXPORT_SYMBOL(blk_verify_command); | |||
230 | static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, | 230 | static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, |
231 | struct sg_io_hdr *hdr, fmode_t mode) | 231 | struct sg_io_hdr *hdr, fmode_t mode) |
232 | { | 232 | { |
233 | if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) | 233 | struct scsi_request *req = scsi_req(rq); |
234 | |||
235 | if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len)) | ||
234 | return -EFAULT; | 236 | return -EFAULT; |
235 | if (blk_verify_command(rq->cmd, mode & FMODE_WRITE)) | 237 | if (blk_verify_command(req->cmd, mode & FMODE_WRITE)) |
236 | return -EPERM; | 238 | return -EPERM; |
237 | 239 | ||
238 | /* | 240 | /* |
239 | * fill in request structure | 241 | * fill in request structure |
240 | */ | 242 | */ |
241 | rq->cmd_len = hdr->cmd_len; | 243 | req->cmd_len = hdr->cmd_len; |
242 | 244 | ||
243 | rq->timeout = msecs_to_jiffies(hdr->timeout); | 245 | rq->timeout = msecs_to_jiffies(hdr->timeout); |
244 | if (!rq->timeout) | 246 | if (!rq->timeout) |
@@ -254,6 +256,7 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, | |||
254 | static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, | 256 | static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, |
255 | struct bio *bio) | 257 | struct bio *bio) |
256 | { | 258 | { |
259 | struct scsi_request *req = scsi_req(rq); | ||
257 | int r, ret = 0; | 260 | int r, ret = 0; |
258 | 261 | ||
259 | /* | 262 | /* |
@@ -267,13 +270,13 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, | |||
267 | hdr->info = 0; | 270 | hdr->info = 0; |
268 | if (hdr->masked_status || hdr->host_status || hdr->driver_status) | 271 | if (hdr->masked_status || hdr->host_status || hdr->driver_status) |
269 | hdr->info |= SG_INFO_CHECK; | 272 | hdr->info |= SG_INFO_CHECK; |
270 | hdr->resid = rq->resid_len; | 273 | hdr->resid = req->resid_len; |
271 | hdr->sb_len_wr = 0; | 274 | hdr->sb_len_wr = 0; |
272 | 275 | ||
273 | if (rq->sense_len && hdr->sbp) { | 276 | if (req->sense_len && hdr->sbp) { |
274 | int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len); | 277 | int len = min((unsigned int) hdr->mx_sb_len, req->sense_len); |
275 | 278 | ||
276 | if (!copy_to_user(hdr->sbp, rq->sense, len)) | 279 | if (!copy_to_user(hdr->sbp, req->sense, len)) |
277 | hdr->sb_len_wr = len; | 280 | hdr->sb_len_wr = len; |
278 | else | 281 | else |
279 | ret = -EFAULT; | 282 | ret = -EFAULT; |
@@ -294,7 +297,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
294 | int writing = 0; | 297 | int writing = 0; |
295 | int at_head = 0; | 298 | int at_head = 0; |
296 | struct request *rq; | 299 | struct request *rq; |
297 | char sense[SCSI_SENSE_BUFFERSIZE]; | 300 | struct scsi_request *req; |
298 | struct bio *bio; | 301 | struct bio *bio; |
299 | 302 | ||
300 | if (hdr->interface_id != 'S') | 303 | if (hdr->interface_id != 'S') |
@@ -321,11 +324,12 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
321 | rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); | 324 | rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); |
322 | if (IS_ERR(rq)) | 325 | if (IS_ERR(rq)) |
323 | return PTR_ERR(rq); | 326 | return PTR_ERR(rq); |
324 | blk_rq_set_block_pc(rq); | 327 | req = scsi_req(rq); |
328 | scsi_req_init(rq); | ||
325 | 329 | ||
326 | if (hdr->cmd_len > BLK_MAX_CDB) { | 330 | if (hdr->cmd_len > BLK_MAX_CDB) { |
327 | rq->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); | 331 | req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); |
328 | if (!rq->cmd) | 332 | if (!req->cmd) |
329 | goto out_put_request; | 333 | goto out_put_request; |
330 | } | 334 | } |
331 | 335 | ||
@@ -357,9 +361,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
357 | goto out_free_cdb; | 361 | goto out_free_cdb; |
358 | 362 | ||
359 | bio = rq->bio; | 363 | bio = rq->bio; |
360 | memset(sense, 0, sizeof(sense)); | ||
361 | rq->sense = sense; | ||
362 | rq->sense_len = 0; | ||
363 | rq->retries = 0; | 364 | rq->retries = 0; |
364 | 365 | ||
365 | start_time = jiffies; | 366 | start_time = jiffies; |
@@ -375,8 +376,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
375 | ret = blk_complete_sghdr_rq(rq, hdr, bio); | 376 | ret = blk_complete_sghdr_rq(rq, hdr, bio); |
376 | 377 | ||
377 | out_free_cdb: | 378 | out_free_cdb: |
378 | if (rq->cmd != rq->__cmd) | 379 | scsi_req_free_cmd(req); |
379 | kfree(rq->cmd); | ||
380 | out_put_request: | 380 | out_put_request: |
381 | blk_put_request(rq); | 381 | blk_put_request(rq); |
382 | return ret; | 382 | return ret; |
@@ -420,9 +420,10 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, | |||
420 | struct scsi_ioctl_command __user *sic) | 420 | struct scsi_ioctl_command __user *sic) |
421 | { | 421 | { |
422 | struct request *rq; | 422 | struct request *rq; |
423 | struct scsi_request *req; | ||
423 | int err; | 424 | int err; |
424 | unsigned int in_len, out_len, bytes, opcode, cmdlen; | 425 | unsigned int in_len, out_len, bytes, opcode, cmdlen; |
425 | char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; | 426 | char *buffer = NULL; |
426 | 427 | ||
427 | if (!sic) | 428 | if (!sic) |
428 | return -EINVAL; | 429 | return -EINVAL; |
@@ -452,7 +453,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, | |||
452 | err = PTR_ERR(rq); | 453 | err = PTR_ERR(rq); |
453 | goto error_free_buffer; | 454 | goto error_free_buffer; |
454 | } | 455 | } |
455 | blk_rq_set_block_pc(rq); | 456 | req = scsi_req(rq); |
457 | scsi_req_init(rq); | ||
456 | 458 | ||
457 | cmdlen = COMMAND_SIZE(opcode); | 459 | cmdlen = COMMAND_SIZE(opcode); |
458 | 460 | ||
@@ -460,14 +462,14 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, | |||
460 | * get command and data to send to device, if any | 462 | * get command and data to send to device, if any |
461 | */ | 463 | */ |
462 | err = -EFAULT; | 464 | err = -EFAULT; |
463 | rq->cmd_len = cmdlen; | 465 | req->cmd_len = cmdlen; |
464 | if (copy_from_user(rq->cmd, sic->data, cmdlen)) | 466 | if (copy_from_user(req->cmd, sic->data, cmdlen)) |
465 | goto error; | 467 | goto error; |
466 | 468 | ||
467 | if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) | 469 | if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) |
468 | goto error; | 470 | goto error; |
469 | 471 | ||
470 | err = blk_verify_command(rq->cmd, mode & FMODE_WRITE); | 472 | err = blk_verify_command(req->cmd, mode & FMODE_WRITE); |
471 | if (err) | 473 | if (err) |
472 | goto error; | 474 | goto error; |
473 | 475 | ||
@@ -503,18 +505,14 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, | |||
503 | goto error; | 505 | goto error; |
504 | } | 506 | } |
505 | 507 | ||
506 | memset(sense, 0, sizeof(sense)); | ||
507 | rq->sense = sense; | ||
508 | rq->sense_len = 0; | ||
509 | |||
510 | blk_execute_rq(q, disk, rq, 0); | 508 | blk_execute_rq(q, disk, rq, 0); |
511 | 509 | ||
512 | err = rq->errors & 0xff; /* only 8 bit SCSI status */ | 510 | err = rq->errors & 0xff; /* only 8 bit SCSI status */ |
513 | if (err) { | 511 | if (err) { |
514 | if (rq->sense_len && rq->sense) { | 512 | if (req->sense_len && req->sense) { |
515 | bytes = (OMAX_SB_LEN > rq->sense_len) ? | 513 | bytes = (OMAX_SB_LEN > req->sense_len) ? |
516 | rq->sense_len : OMAX_SB_LEN; | 514 | req->sense_len : OMAX_SB_LEN; |
517 | if (copy_to_user(sic->data, rq->sense, bytes)) | 515 | if (copy_to_user(sic->data, req->sense, bytes)) |
518 | err = -EFAULT; | 516 | err = -EFAULT; |
519 | } | 517 | } |
520 | } else { | 518 | } else { |
@@ -542,11 +540,11 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, | |||
542 | rq = blk_get_request(q, WRITE, __GFP_RECLAIM); | 540 | rq = blk_get_request(q, WRITE, __GFP_RECLAIM); |
543 | if (IS_ERR(rq)) | 541 | if (IS_ERR(rq)) |
544 | return PTR_ERR(rq); | 542 | return PTR_ERR(rq); |
545 | blk_rq_set_block_pc(rq); | 543 | scsi_req_init(rq); |
546 | rq->timeout = BLK_DEFAULT_SG_TIMEOUT; | 544 | rq->timeout = BLK_DEFAULT_SG_TIMEOUT; |
547 | rq->cmd[0] = cmd; | 545 | scsi_req(rq)->cmd[0] = cmd; |
548 | rq->cmd[4] = data; | 546 | scsi_req(rq)->cmd[4] = data; |
549 | rq->cmd_len = 6; | 547 | scsi_req(rq)->cmd_len = 6; |
550 | err = blk_execute_rq(q, bd_disk, rq, 0); | 548 | err = blk_execute_rq(q, bd_disk, rq, 0); |
551 | blk_put_request(rq); | 549 | blk_put_request(rq); |
552 | 550 | ||
@@ -743,6 +741,18 @@ int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode, | |||
743 | } | 741 | } |
744 | EXPORT_SYMBOL(scsi_cmd_blk_ioctl); | 742 | EXPORT_SYMBOL(scsi_cmd_blk_ioctl); |
745 | 743 | ||
744 | void scsi_req_init(struct request *rq) | ||
745 | { | ||
746 | struct scsi_request *req = scsi_req(rq); | ||
747 | |||
748 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | ||
749 | memset(req->__cmd, 0, sizeof(req->__cmd)); | ||
750 | req->cmd = req->__cmd; | ||
751 | req->cmd_len = BLK_MAX_CDB; | ||
752 | req->sense_len = 0; | ||
753 | } | ||
754 | EXPORT_SYMBOL(scsi_req_init); | ||
755 | |||
746 | static int __init blk_scsi_ioctl_init(void) | 756 | static int __init blk_scsi_ioctl_init(void) |
747 | { | 757 | { |
748 | blk_set_cmd_filter_defaults(&blk_default_cmd_filter); | 758 | blk_set_cmd_filter_defaults(&blk_default_cmd_filter); |