diff options
author | Christoph Hellwig <hch@lst.de> | 2014-05-01 10:51:02 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-05-19 06:33:41 -0400 |
commit | c682adf3e1176095a665716a0b62fead8f4b8f5c (patch) | |
tree | 673170d74351781c848f0436fc545e7e12a535f8 | |
parent | d6d211db37e75de2ddc3a4f979038c40df7cc79c (diff) |
scsi: explicitly release bidi buffers
Instead of trying to guess when we have a BIDI buffer in scsi_release_buffers
add a function to explicitly free the BIDI ressoures in the one place that
handles them. This avoids needing a special __scsi_release_buffers for the
case where we already have freed the request as well.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9db097a28a74..f416b5932a45 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -512,8 +512,6 @@ void scsi_run_host_queues(struct Scsi_Host *shost) | |||
512 | scsi_run_queue(sdev->request_queue); | 512 | scsi_run_queue(sdev->request_queue); |
513 | } | 513 | } |
514 | 514 | ||
515 | static void __scsi_release_buffers(struct scsi_cmnd *, int); | ||
516 | |||
517 | /* | 515 | /* |
518 | * Function: scsi_end_request() | 516 | * Function: scsi_end_request() |
519 | * | 517 | * |
@@ -569,7 +567,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error, | |||
569 | * This will goose the queue request function at the end, so we don't | 567 | * This will goose the queue request function at the end, so we don't |
570 | * need to worry about launching another command. | 568 | * need to worry about launching another command. |
571 | */ | 569 | */ |
572 | __scsi_release_buffers(cmd, 0); | 570 | scsi_release_buffers(cmd); |
573 | scsi_next_command(cmd); | 571 | scsi_next_command(cmd); |
574 | return NULL; | 572 | return NULL; |
575 | } | 573 | } |
@@ -625,30 +623,10 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb) | |||
625 | __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free); | 623 | __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free); |
626 | } | 624 | } |
627 | 625 | ||
628 | static void __scsi_release_buffers(struct scsi_cmnd *cmd, int do_bidi_check) | ||
629 | { | ||
630 | |||
631 | if (cmd->sdb.table.nents) | ||
632 | scsi_free_sgtable(&cmd->sdb); | ||
633 | |||
634 | memset(&cmd->sdb, 0, sizeof(cmd->sdb)); | ||
635 | |||
636 | if (do_bidi_check && scsi_bidi_cmnd(cmd)) { | ||
637 | struct scsi_data_buffer *bidi_sdb = | ||
638 | cmd->request->next_rq->special; | ||
639 | scsi_free_sgtable(bidi_sdb); | ||
640 | kmem_cache_free(scsi_sdb_cache, bidi_sdb); | ||
641 | cmd->request->next_rq->special = NULL; | ||
642 | } | ||
643 | |||
644 | if (scsi_prot_sg_count(cmd)) | ||
645 | scsi_free_sgtable(cmd->prot_sdb); | ||
646 | } | ||
647 | |||
648 | /* | 626 | /* |
649 | * Function: scsi_release_buffers() | 627 | * Function: scsi_release_buffers() |
650 | * | 628 | * |
651 | * Purpose: Completion processing for block device I/O requests. | 629 | * Purpose: Free resources allocate for a scsi_command. |
652 | * | 630 | * |
653 | * Arguments: cmd - command that we are bailing. | 631 | * Arguments: cmd - command that we are bailing. |
654 | * | 632 | * |
@@ -659,15 +637,29 @@ static void __scsi_release_buffers(struct scsi_cmnd *cmd, int do_bidi_check) | |||
659 | * Notes: In the event that an upper level driver rejects a | 637 | * Notes: In the event that an upper level driver rejects a |
660 | * command, we must release resources allocated during | 638 | * command, we must release resources allocated during |
661 | * the __init_io() function. Primarily this would involve | 639 | * the __init_io() function. Primarily this would involve |
662 | * the scatter-gather table, and potentially any bounce | 640 | * the scatter-gather table. |
663 | * buffers. | ||
664 | */ | 641 | */ |
665 | void scsi_release_buffers(struct scsi_cmnd *cmd) | 642 | void scsi_release_buffers(struct scsi_cmnd *cmd) |
666 | { | 643 | { |
667 | __scsi_release_buffers(cmd, 1); | 644 | if (cmd->sdb.table.nents) |
645 | scsi_free_sgtable(&cmd->sdb); | ||
646 | |||
647 | memset(&cmd->sdb, 0, sizeof(cmd->sdb)); | ||
648 | |||
649 | if (scsi_prot_sg_count(cmd)) | ||
650 | scsi_free_sgtable(cmd->prot_sdb); | ||
668 | } | 651 | } |
669 | EXPORT_SYMBOL(scsi_release_buffers); | 652 | EXPORT_SYMBOL(scsi_release_buffers); |
670 | 653 | ||
654 | static void scsi_release_bidi_buffers(struct scsi_cmnd *cmd) | ||
655 | { | ||
656 | struct scsi_data_buffer *bidi_sdb = cmd->request->next_rq->special; | ||
657 | |||
658 | scsi_free_sgtable(bidi_sdb); | ||
659 | kmem_cache_free(scsi_sdb_cache, bidi_sdb); | ||
660 | cmd->request->next_rq->special = NULL; | ||
661 | } | ||
662 | |||
671 | /** | 663 | /** |
672 | * __scsi_error_from_host_byte - translate SCSI error code into errno | 664 | * __scsi_error_from_host_byte - translate SCSI error code into errno |
673 | * @cmd: SCSI command (unused) | 665 | * @cmd: SCSI command (unused) |
@@ -801,6 +793,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
801 | req->next_rq->resid_len = scsi_in(cmd)->resid; | 793 | req->next_rq->resid_len = scsi_in(cmd)->resid; |
802 | 794 | ||
803 | scsi_release_buffers(cmd); | 795 | scsi_release_buffers(cmd); |
796 | scsi_release_bidi_buffers(cmd); | ||
804 | blk_end_request_all(req, 0); | 797 | blk_end_request_all(req, 0); |
805 | 798 | ||
806 | scsi_next_command(cmd); | 799 | scsi_next_command(cmd); |